Repository: golangci/golangci-lint
Branch: main
Commit: b7ca3baed01b
Files: 1800
Total size: 8.4 MB
Directory structure:
gitextract_2yvj2yhy/
├── .custom-gcl.reference.yml
├── .gitattributes
├── .github/
│ ├── CONTRIBUTING.md
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ └── feature_request.yml
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── boring-cyborg.yml
│ ├── dependabot.yml
│ ├── new-linter-checklist.md
│ ├── peril/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── rules/
│ │ │ └── invite-collaborator.ts
│ │ ├── settings.json
│ │ ├── tests/
│ │ │ └── invite-collaborator.test.ts
│ │ └── tsconfig.json
│ ├── stale.yml
│ └── workflows/
│ ├── codeql.yml
│ ├── deploy-documentation.yml
│ ├── new-linter-checklist.yml
│ ├── post-release.yml
│ ├── pr-checks.yml
│ ├── pr-documentation.yml
│ ├── pr-tests.yml
│ └── release.yml
├── .gitignore
├── .golangci.next.reference.yml
├── .golangci.reference.yml
├── .golangci.yml
├── .goreleaser.yml
├── .pre-commit-hooks.yaml
├── CHANGELOG-v1.md
├── CHANGELOG.md
├── LICENSE
├── Makefile
├── README.md
├── assets/
│ ├── github-action-config-v1.json
│ ├── github-action-config-v2.json
│ └── github-action-config.json
├── build/
│ ├── buildx-alpine.Dockerfile
│ └── buildx.Dockerfile
├── cmd/
│ └── golangci-lint/
│ ├── main.go
│ └── plugins.go
├── docs/
│ ├── .gitignore
│ ├── Makefile
│ ├── archetypes/
│ │ └── default.md
│ ├── assets/
│ │ └── css/
│ │ └── custom.css
│ ├── content/
│ │ ├── _index.md
│ │ └── docs/
│ │ ├── _index.md
│ │ ├── configuration/
│ │ │ ├── _index.md
│ │ │ ├── cli.md
│ │ │ └── file.md
│ │ ├── contributing/
│ │ │ ├── _index.md
│ │ │ ├── architecture.md
│ │ │ ├── debug.md
│ │ │ ├── faq.md
│ │ │ ├── new-linters.md
│ │ │ ├── website.md
│ │ │ └── workflow.md
│ │ ├── donate/
│ │ │ └── _index.md
│ │ ├── formatters/
│ │ │ ├── _index.md
│ │ │ └── configuration.md
│ │ ├── linters/
│ │ │ ├── _index.md
│ │ │ ├── configuration.md
│ │ │ └── false-positives.md
│ │ ├── plugins/
│ │ │ ├── _index.md
│ │ │ ├── go-plugins.md
│ │ │ └── module-plugins.md
│ │ ├── product/
│ │ │ ├── _index.md
│ │ │ ├── changelog-v1.md
│ │ │ ├── changelog.md
│ │ │ ├── migration-guide.md
│ │ │ ├── roadmap.md
│ │ │ └── thanks.md
│ │ └── welcome/
│ │ ├── _index.md
│ │ ├── faq.md
│ │ ├── install/
│ │ │ ├── _index.md
│ │ │ ├── ci.md
│ │ │ └── local.md
│ │ ├── integrations.md
│ │ └── quick-start.md
│ ├── data/
│ │ ├── cli_help.json
│ │ ├── configuration_file.json
│ │ ├── exclusion_presets.json
│ │ ├── formatters_info.json
│ │ ├── icons.yaml
│ │ ├── linters_info.json
│ │ └── thanks.json
│ ├── go.mod
│ ├── go.sum
│ ├── golangci-lint.tape
│ ├── hugo.yaml
│ ├── i18n/
│ │ └── en.yaml
│ ├── layouts/
│ │ ├── 404.html
│ │ ├── _partials/
│ │ │ ├── custom/
│ │ │ │ └── head-end.html
│ │ │ ├── footer.html
│ │ │ ├── golangci/
│ │ │ │ └── items/
│ │ │ │ ├── compare-versions.html
│ │ │ │ ├── format-description.html
│ │ │ │ └── tag.html
│ │ │ └── shortcodes/
│ │ │ ├── badge.html
│ │ │ └── cards.html
│ │ └── _shortcodes/
│ │ ├── cards.html
│ │ ├── details.html
│ │ └── golangci/
│ │ ├── authors.html
│ │ ├── button.html
│ │ ├── cli-output.html
│ │ ├── configuration-file-snippet.html
│ │ ├── embed.html
│ │ ├── exclusion-preset-tables.html
│ │ ├── exclusion-presets-snippet.html
│ │ ├── image-card.html
│ │ ├── items/
│ │ │ ├── cards.html
│ │ │ ├── filter-badge.html
│ │ │ ├── filter.html
│ │ │ └── settings.html
│ │ ├── latest-version.html
│ │ └── starcharts.html
│ └── static/
│ ├── CNAME
│ └── site.webmanifest
├── go.mod
├── go.sum
├── install.sh
├── internal/
│ ├── cache/
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ └── testdata/
│ │ └── hello.go
│ ├── errorutil/
│ │ └── errors.go
│ ├── go/
│ │ ├── LICENSE
│ │ ├── base/
│ │ │ ├── error_notunix.go
│ │ │ ├── error_unix.go
│ │ │ └── readme.md
│ │ ├── cache/
│ │ │ ├── cache.go
│ │ │ ├── cache_gcil.go
│ │ │ ├── cache_test.go
│ │ │ ├── default.go
│ │ │ ├── default_gcil.go
│ │ │ ├── hash.go
│ │ │ ├── hash_gcil.go
│ │ │ ├── hash_test.go
│ │ │ ├── prog.go
│ │ │ └── readme.md
│ │ ├── cacheprog/
│ │ │ ├── cacheprog.go
│ │ │ └── readme.md
│ │ ├── mmap/
│ │ │ ├── mmap.go
│ │ │ ├── mmap_other.go
│ │ │ ├── mmap_unix.go
│ │ │ ├── mmap_windows.go
│ │ │ └── readme.md
│ │ ├── quoted/
│ │ │ ├── quoted.go
│ │ │ ├── quoted_test.go
│ │ │ └── readme.md
│ │ └── testenv/
│ │ ├── readme.md
│ │ ├── testenv.go
│ │ ├── testenv_notunix.go
│ │ ├── testenv_notwin.go
│ │ ├── testenv_unix.go
│ │ └── testenv_windows.go
│ └── x/
│ ├── LICENSE
│ └── tools/
│ ├── diff/
│ │ ├── diff.go
│ │ ├── lcs/
│ │ │ ├── common.go
│ │ │ ├── common_test.go
│ │ │ ├── doc.go
│ │ │ ├── git.sh
│ │ │ ├── labels.go
│ │ │ ├── old.go
│ │ │ ├── old_test.go
│ │ │ └── sequence.go
│ │ ├── myers/
│ │ │ └── diff.go
│ │ ├── ndiff.go
│ │ ├── readme.md
│ │ └── unified.go
│ └── driverutil/
│ ├── readfile.go
│ ├── readme.md
│ └── url.go
├── jsonschema/
│ ├── custom-gcl.jsonschema.json
│ ├── golangci.jsonschema.json
│ ├── golangci.next.jsonschema.json
│ ├── golangci.v1.57.jsonschema.json
│ ├── golangci.v1.58.jsonschema.json
│ ├── golangci.v1.59.jsonschema.json
│ ├── golangci.v1.60.jsonschema.json
│ ├── golangci.v1.61.jsonschema.json
│ ├── golangci.v1.62.jsonschema.json
│ ├── golangci.v1.63.jsonschema.json
│ ├── golangci.v1.64.jsonschema.json
│ ├── golangci.v1.jsonschema.json
│ ├── golangci.v2.0.jsonschema.json
│ ├── golangci.v2.1.jsonschema.json
│ ├── golangci.v2.10.jsonschema.json
│ ├── golangci.v2.2.jsonschema.json
│ ├── golangci.v2.3.jsonschema.json
│ ├── golangci.v2.4.jsonschema.json
│ ├── golangci.v2.5.jsonschema.json
│ ├── golangci.v2.6.jsonschema.json
│ ├── golangci.v2.7.jsonschema.json
│ ├── golangci.v2.8.jsonschema.json
│ └── golangci.v2.9.jsonschema.json
├── pkg/
│ ├── commands/
│ │ ├── cache.go
│ │ ├── config.go
│ │ ├── config_verify.go
│ │ ├── config_verify_test.go
│ │ ├── custom.go
│ │ ├── flagsets.go
│ │ ├── fmt.go
│ │ ├── formatters.go
│ │ ├── help.go
│ │ ├── help_formatters.go
│ │ ├── help_linters.go
│ │ ├── help_test.go
│ │ ├── internal/
│ │ │ ├── builder.go
│ │ │ ├── builder_test.go
│ │ │ ├── configuration.go
│ │ │ ├── configuration_test.go
│ │ │ ├── dirhash.go
│ │ │ ├── imports.go
│ │ │ ├── imports_test.go
│ │ │ ├── migrate/
│ │ │ │ ├── cloner/
│ │ │ │ │ └── cloner.go
│ │ │ │ ├── fakeloader/
│ │ │ │ │ ├── config.go
│ │ │ │ │ └── fakeloader.go
│ │ │ │ ├── migrate.go
│ │ │ │ ├── migrate_formatters.go
│ │ │ │ ├── migrate_issues.go
│ │ │ │ ├── migrate_linter_names.go
│ │ │ │ ├── migrate_linter_names_test.go
│ │ │ │ ├── migrate_linters.go
│ │ │ │ ├── migrate_linters_exclusions.go
│ │ │ │ ├── migrate_linters_settings.go
│ │ │ │ ├── migrate_output.go
│ │ │ │ ├── migrate_run.go
│ │ │ │ ├── migrate_severity.go
│ │ │ │ ├── migrate_test.go
│ │ │ │ ├── parser/
│ │ │ │ │ └── parser.go
│ │ │ │ ├── ptr/
│ │ │ │ │ └── ptr.go
│ │ │ │ ├── testdata/
│ │ │ │ │ ├── json/
│ │ │ │ │ │ ├── empty.golden.json
│ │ │ │ │ │ └── empty.json
│ │ │ │ │ ├── toml/
│ │ │ │ │ │ ├── empty.golden.toml
│ │ │ │ │ │ ├── empty.toml
│ │ │ │ │ │ ├── linters-settings_goheader.golden.toml
│ │ │ │ │ │ └── linters-settings_goheader.toml
│ │ │ │ │ └── yaml/
│ │ │ │ │ ├── empty.golden.yml
│ │ │ │ │ ├── empty.yml
│ │ │ │ │ ├── issues_01_a.golden.yml
│ │ │ │ │ ├── issues_01_a.yml
│ │ │ │ │ ├── issues_01_b.golden.yml
│ │ │ │ │ ├── issues_01_b.yml
│ │ │ │ │ ├── issues_02_a.golden.yml
│ │ │ │ │ ├── issues_02_a.yml
│ │ │ │ │ ├── issues_02_b.golden.yml
│ │ │ │ │ ├── issues_02_b.yml
│ │ │ │ │ ├── issues_04_a.golden.yml
│ │ │ │ │ ├── issues_04_a.yml
│ │ │ │ │ ├── issues_04_b.golden.yml
│ │ │ │ │ ├── issues_04_b.yml
│ │ │ │ │ ├── issues_04_c.golden.yml
│ │ │ │ │ ├── issues_04_c.yml
│ │ │ │ │ ├── issues_05_a.golden.yml
│ │ │ │ │ ├── issues_05_a.yml
│ │ │ │ │ ├── issues_05_b.golden.yml
│ │ │ │ │ ├── issues_05_b.yml
│ │ │ │ │ ├── issues_05_c.golden.yml
│ │ │ │ │ ├── issues_05_c.yml
│ │ │ │ │ ├── issues_06_a.golden.yml
│ │ │ │ │ ├── issues_06_a.yml
│ │ │ │ │ ├── issues_06_b.golden.yml
│ │ │ │ │ ├── issues_06_b.yml
│ │ │ │ │ ├── issues_06_c.golden.yml
│ │ │ │ │ ├── issues_06_c.yml
│ │ │ │ │ ├── issues_06_d.golden.yml
│ │ │ │ │ ├── issues_06_d.yml
│ │ │ │ │ ├── issues_06_e.golden.yml
│ │ │ │ │ ├── issues_06_e.yml
│ │ │ │ │ ├── issues_06_f.golden.yml
│ │ │ │ │ ├── issues_06_f.yml
│ │ │ │ │ ├── issues_06_g.golden.yml
│ │ │ │ │ ├── issues_06_g.yml
│ │ │ │ │ ├── issues_06_h.golden.yml
│ │ │ │ │ ├── issues_06_h.yml
│ │ │ │ │ ├── issues_07_a.golden.yml
│ │ │ │ │ ├── issues_07_a.yml
│ │ │ │ │ ├── issues_07_b.golden.yml
│ │ │ │ │ ├── issues_07_b.yml
│ │ │ │ │ ├── issues_08_a.golden.yml
│ │ │ │ │ ├── issues_08_a.yml
│ │ │ │ │ ├── issues_08_b.golden.yml
│ │ │ │ │ ├── issues_08_b.yml
│ │ │ │ │ ├── issues_09_a.golden.yml
│ │ │ │ │ ├── issues_09_a.yml
│ │ │ │ │ ├── issues_09_b.golden.yml
│ │ │ │ │ ├── issues_09_b.yml
│ │ │ │ │ ├── issues_10.golden.yml
│ │ │ │ │ ├── issues_10.yml
│ │ │ │ │ ├── linters-settings_asasalint.golden.yml
│ │ │ │ │ ├── linters-settings_asasalint.yml
│ │ │ │ │ ├── linters-settings_bidichk.golden.yml
│ │ │ │ │ ├── linters-settings_bidichk.yml
│ │ │ │ │ ├── linters-settings_copyloopvar.golden.yml
│ │ │ │ │ ├── linters-settings_copyloopvar.yml
│ │ │ │ │ ├── linters-settings_custom.golden.yml
│ │ │ │ │ ├── linters-settings_custom.yml
│ │ │ │ │ ├── linters-settings_cyclop.golden.yml
│ │ │ │ │ ├── linters-settings_cyclop.yml
│ │ │ │ │ ├── linters-settings_decorder.golden.yml
│ │ │ │ │ ├── linters-settings_decorder.yml
│ │ │ │ │ ├── linters-settings_depguard.golden.yml
│ │ │ │ │ ├── linters-settings_depguard.yml
│ │ │ │ │ ├── linters-settings_dogsled.golden.yml
│ │ │ │ │ ├── linters-settings_dogsled.yml
│ │ │ │ │ ├── linters-settings_dupl.golden.yml
│ │ │ │ │ ├── linters-settings_dupl.yml
│ │ │ │ │ ├── linters-settings_dupword.golden.yml
│ │ │ │ │ ├── linters-settings_dupword.yml
│ │ │ │ │ ├── linters-settings_errcheck.golden.yml
│ │ │ │ │ ├── linters-settings_errcheck.yml
│ │ │ │ │ ├── linters-settings_errchkjson.golden.yml
│ │ │ │ │ ├── linters-settings_errchkjson.yml
│ │ │ │ │ ├── linters-settings_errorlint.golden.yml
│ │ │ │ │ ├── linters-settings_errorlint.yml
│ │ │ │ │ ├── linters-settings_exhaustive.golden.yml
│ │ │ │ │ ├── linters-settings_exhaustive.yml
│ │ │ │ │ ├── linters-settings_exhaustruct.golden.yml
│ │ │ │ │ ├── linters-settings_exhaustruct.yml
│ │ │ │ │ ├── linters-settings_fatcontext.golden.yml
│ │ │ │ │ ├── linters-settings_fatcontext.yml
│ │ │ │ │ ├── linters-settings_forbidigo.golden.yml
│ │ │ │ │ ├── linters-settings_forbidigo.yml
│ │ │ │ │ ├── linters-settings_funlen.golden.yml
│ │ │ │ │ ├── linters-settings_funlen.yml
│ │ │ │ │ ├── linters-settings_gci.golden.yml
│ │ │ │ │ ├── linters-settings_gci.yml
│ │ │ │ │ ├── linters-settings_ginkgolinter.golden.yml
│ │ │ │ │ ├── linters-settings_ginkgolinter.yml
│ │ │ │ │ ├── linters-settings_gochecksumtype.golden.yml
│ │ │ │ │ ├── linters-settings_gochecksumtype.yml
│ │ │ │ │ ├── linters-settings_gocognit.golden.yml
│ │ │ │ │ ├── linters-settings_gocognit.yml
│ │ │ │ │ ├── linters-settings_goconst.golden.yml
│ │ │ │ │ ├── linters-settings_goconst.yml
│ │ │ │ │ ├── linters-settings_gocritic.golden.yml
│ │ │ │ │ ├── linters-settings_gocritic.yml
│ │ │ │ │ ├── linters-settings_gocyclo.golden.yml
│ │ │ │ │ ├── linters-settings_gocyclo.yml
│ │ │ │ │ ├── linters-settings_godot.golden.yml
│ │ │ │ │ ├── linters-settings_godot.yml
│ │ │ │ │ ├── linters-settings_godox.golden.yml
│ │ │ │ │ ├── linters-settings_godox.yml
│ │ │ │ │ ├── linters-settings_gofmt.golden.yml
│ │ │ │ │ ├── linters-settings_gofmt.yml
│ │ │ │ │ ├── linters-settings_gofumpt.golden.yml
│ │ │ │ │ ├── linters-settings_gofumpt.yml
│ │ │ │ │ ├── linters-settings_goheader.golden.yml
│ │ │ │ │ ├── linters-settings_goheader.yml
│ │ │ │ │ ├── linters-settings_goimports.golden.yml
│ │ │ │ │ ├── linters-settings_goimports.yml
│ │ │ │ │ ├── linters-settings_gomoddirectives.golden.yml
│ │ │ │ │ ├── linters-settings_gomoddirectives.yml
│ │ │ │ │ ├── linters-settings_gomodguard.golden.yml
│ │ │ │ │ ├── linters-settings_gomodguard.yml
│ │ │ │ │ ├── linters-settings_gosec.golden.yml
│ │ │ │ │ ├── linters-settings_gosec.yml
│ │ │ │ │ ├── linters-settings_gosimple.golden.yml
│ │ │ │ │ ├── linters-settings_gosimple.yml
│ │ │ │ │ ├── linters-settings_gosmopolitan.golden.yml
│ │ │ │ │ ├── linters-settings_gosmopolitan.yml
│ │ │ │ │ ├── linters-settings_govet.golden.yml
│ │ │ │ │ ├── linters-settings_govet.yml
│ │ │ │ │ ├── linters-settings_grouper.golden.yml
│ │ │ │ │ ├── linters-settings_grouper.yml
│ │ │ │ │ ├── linters-settings_iface.golden.yml
│ │ │ │ │ ├── linters-settings_iface.yml
│ │ │ │ │ ├── linters-settings_importas.golden.yml
│ │ │ │ │ ├── linters-settings_importas.yml
│ │ │ │ │ ├── linters-settings_inamedparam.golden.yml
│ │ │ │ │ ├── linters-settings_inamedparam.yml
│ │ │ │ │ ├── linters-settings_interfacebloat.golden.yml
│ │ │ │ │ ├── linters-settings_interfacebloat.yml
│ │ │ │ │ ├── linters-settings_ireturn.golden.yml
│ │ │ │ │ ├── linters-settings_ireturn.yml
│ │ │ │ │ ├── linters-settings_lll.golden.yml
│ │ │ │ │ ├── linters-settings_lll.yml
│ │ │ │ │ ├── linters-settings_loggercheck.golden.yml
│ │ │ │ │ ├── linters-settings_loggercheck.yml
│ │ │ │ │ ├── linters-settings_maintidx.golden.yml
│ │ │ │ │ ├── linters-settings_maintidx.yml
│ │ │ │ │ ├── linters-settings_makezero.golden.yml
│ │ │ │ │ ├── linters-settings_makezero.yml
│ │ │ │ │ ├── linters-settings_misspell.golden.yml
│ │ │ │ │ ├── linters-settings_misspell.yml
│ │ │ │ │ ├── linters-settings_mnd.golden.yml
│ │ │ │ │ ├── linters-settings_mnd.yml
│ │ │ │ │ ├── linters-settings_musttag.golden.yml
│ │ │ │ │ ├── linters-settings_musttag.yml
│ │ │ │ │ ├── linters-settings_nakedret.golden.yml
│ │ │ │ │ ├── linters-settings_nakedret.yml
│ │ │ │ │ ├── linters-settings_nakedret_zero.golden.yml
│ │ │ │ │ ├── linters-settings_nakedret_zero.yml
│ │ │ │ │ ├── linters-settings_nestif.golden.yml
│ │ │ │ │ ├── linters-settings_nestif.yml
│ │ │ │ │ ├── linters-settings_nilnil.golden.yml
│ │ │ │ │ ├── linters-settings_nilnil.yml
│ │ │ │ │ ├── linters-settings_nlreturn.golden.yml
│ │ │ │ │ ├── linters-settings_nlreturn.yml
│ │ │ │ │ ├── linters-settings_nolintlint.golden.yml
│ │ │ │ │ ├── linters-settings_nolintlint.yml
│ │ │ │ │ ├── linters-settings_nonamedreturns.golden.yml
│ │ │ │ │ ├── linters-settings_nonamedreturns.yml
│ │ │ │ │ ├── linters-settings_paralleltest.golden.yml
│ │ │ │ │ ├── linters-settings_paralleltest.yml
│ │ │ │ │ ├── linters-settings_perfsprint.golden.yml
│ │ │ │ │ ├── linters-settings_perfsprint.yml
│ │ │ │ │ ├── linters-settings_prealloc.golden.yml
│ │ │ │ │ ├── linters-settings_prealloc.yml
│ │ │ │ │ ├── linters-settings_predeclared.golden.yml
│ │ │ │ │ ├── linters-settings_predeclared.yml
│ │ │ │ │ ├── linters-settings_promlinter.golden.yml
│ │ │ │ │ ├── linters-settings_promlinter.yml
│ │ │ │ │ ├── linters-settings_protogetter.golden.yml
│ │ │ │ │ ├── linters-settings_protogetter.yml
│ │ │ │ │ ├── linters-settings_reassign.golden.yml
│ │ │ │ │ ├── linters-settings_reassign.yml
│ │ │ │ │ ├── linters-settings_recvcheck.golden.yml
│ │ │ │ │ ├── linters-settings_recvcheck.yml
│ │ │ │ │ ├── linters-settings_revive.golden.yml
│ │ │ │ │ ├── linters-settings_revive.yml
│ │ │ │ │ ├── linters-settings_rowserrcheck.golden.yml
│ │ │ │ │ ├── linters-settings_rowserrcheck.yml
│ │ │ │ │ ├── linters-settings_sloglint.golden.yml
│ │ │ │ │ ├── linters-settings_sloglint.yml
│ │ │ │ │ ├── linters-settings_spancheck.golden.yml
│ │ │ │ │ ├── linters-settings_spancheck.yml
│ │ │ │ │ ├── linters-settings_staticcheck.golden.yml
│ │ │ │ │ ├── linters-settings_staticcheck.yml
│ │ │ │ │ ├── linters-settings_staticcheck_merge.golden.yml
│ │ │ │ │ ├── linters-settings_staticcheck_merge.yml
│ │ │ │ │ ├── linters-settings_stylecheck.golden.yml
│ │ │ │ │ ├── linters-settings_stylecheck.yml
│ │ │ │ │ ├── linters-settings_tagalign.golden.yml
│ │ │ │ │ ├── linters-settings_tagalign.yml
│ │ │ │ │ ├── linters-settings_tagliatelle.golden.yml
│ │ │ │ │ ├── linters-settings_tagliatelle.yml
│ │ │ │ │ ├── linters-settings_testifylint.golden.yml
│ │ │ │ │ ├── linters-settings_testifylint.yml
│ │ │ │ │ ├── linters-settings_testpackage.golden.yml
│ │ │ │ │ ├── linters-settings_testpackage.yml
│ │ │ │ │ ├── linters-settings_thelper.golden.yml
│ │ │ │ │ ├── linters-settings_thelper.yml
│ │ │ │ │ ├── linters-settings_unconvert.golden.yml
│ │ │ │ │ ├── linters-settings_unconvert.yml
│ │ │ │ │ ├── linters-settings_unparam.golden.yml
│ │ │ │ │ ├── linters-settings_unparam.yml
│ │ │ │ │ ├── linters-settings_unused.golden.yml
│ │ │ │ │ ├── linters-settings_unused.yml
│ │ │ │ │ ├── linters-settings_usestdlibvars.golden.yml
│ │ │ │ │ ├── linters-settings_usestdlibvars.yml
│ │ │ │ │ ├── linters-settings_usetesting.golden.yml
│ │ │ │ │ ├── linters-settings_usetesting.yml
│ │ │ │ │ ├── linters-settings_varnamelen.golden.yml
│ │ │ │ │ ├── linters-settings_varnamelen.yml
│ │ │ │ │ ├── linters-settings_whitespace.golden.yml
│ │ │ │ │ ├── linters-settings_whitespace.yml
│ │ │ │ │ ├── linters-settings_wrapcheck.golden.yml
│ │ │ │ │ ├── linters-settings_wrapcheck.yml
│ │ │ │ │ ├── linters-settings_wsl.golden.yml
│ │ │ │ │ ├── linters-settings_wsl.yml
│ │ │ │ │ ├── linters_01.golden.yml
│ │ │ │ │ ├── linters_01.yml
│ │ │ │ │ ├── linters_02.golden.yml
│ │ │ │ │ ├── linters_02.yml
│ │ │ │ │ ├── linters_03.golden.yml
│ │ │ │ │ ├── linters_03.yml
│ │ │ │ │ ├── linters_04.golden.yml
│ │ │ │ │ ├── linters_04.yml
│ │ │ │ │ ├── linters_05.golden.yml
│ │ │ │ │ ├── linters_05.yml
│ │ │ │ │ ├── linters_06.golden.yml
│ │ │ │ │ ├── linters_06.yml
│ │ │ │ │ ├── linters_07.golden.yml
│ │ │ │ │ ├── linters_07.yml
│ │ │ │ │ ├── linters_08.golden.yml
│ │ │ │ │ ├── linters_08.yml
│ │ │ │ │ ├── linters_09.golden.yml
│ │ │ │ │ ├── linters_09.yml
│ │ │ │ │ ├── linters_10.golden.yml
│ │ │ │ │ ├── linters_10.yml
│ │ │ │ │ ├── linters_11.golden.yml
│ │ │ │ │ ├── linters_11.yml
│ │ │ │ │ ├── linters_12.golden.yml
│ │ │ │ │ ├── linters_12.yml
│ │ │ │ │ ├── linters_13_a.golden.yml
│ │ │ │ │ ├── linters_13_a.yml
│ │ │ │ │ ├── linters_13_b.golden.yml
│ │ │ │ │ ├── linters_13_b.yml
│ │ │ │ │ ├── linters_13_c.golden.yml
│ │ │ │ │ ├── linters_13_c.yml
│ │ │ │ │ ├── linters_13_d.golden.yml
│ │ │ │ │ ├── linters_13_d.yml
│ │ │ │ │ ├── output_01_a.golden.yml
│ │ │ │ │ ├── output_01_a.yml
│ │ │ │ │ ├── output_01_b.golden.yml
│ │ │ │ │ ├── output_01_b.yml
│ │ │ │ │ ├── output_01_c.golden.yml
│ │ │ │ │ ├── output_01_c.yml
│ │ │ │ │ ├── output_01_d.golden.yml
│ │ │ │ │ ├── output_01_d.yml
│ │ │ │ │ ├── output_01_f.golden.yml
│ │ │ │ │ ├── output_01_f.yml
│ │ │ │ │ ├── output_01_g.golden.yml
│ │ │ │ │ ├── output_01_g.yml
│ │ │ │ │ ├── output_01_h.golden.yml
│ │ │ │ │ ├── output_01_h.yml
│ │ │ │ │ ├── output_01_i.golden.yml
│ │ │ │ │ ├── output_01_i.yml
│ │ │ │ │ ├── output_01_j.golden.yml
│ │ │ │ │ ├── output_01_j.yml
│ │ │ │ │ ├── output_01_k.golden.yml
│ │ │ │ │ ├── output_01_k.yml
│ │ │ │ │ ├── output_01_l.golden.yml
│ │ │ │ │ ├── output_01_l.yml
│ │ │ │ │ ├── output_01_m.golden.yml
│ │ │ │ │ ├── output_01_m.yml
│ │ │ │ │ ├── output_01_o.golden.yml
│ │ │ │ │ ├── output_01_o.yml
│ │ │ │ │ ├── output_01_p.golden.yml
│ │ │ │ │ ├── output_01_p.yml
│ │ │ │ │ ├── output_02.golden.yml
│ │ │ │ │ ├── output_02.yml
│ │ │ │ │ ├── output_03.golden.yml
│ │ │ │ │ ├── output_03.yml
│ │ │ │ │ ├── output_04.golden.yml
│ │ │ │ │ ├── output_04.yml
│ │ │ │ │ ├── run_01.golden.yml
│ │ │ │ │ ├── run_01.yml
│ │ │ │ │ ├── run_02_a.golden.yml
│ │ │ │ │ ├── run_02_a.yml
│ │ │ │ │ ├── run_02_b.golden.yml
│ │ │ │ │ ├── run_02_b.yml
│ │ │ │ │ ├── run_03_a.golden.yml
│ │ │ │ │ ├── run_03_a.yml
│ │ │ │ │ ├── run_03_b.golden.yml
│ │ │ │ │ ├── run_03_b.yml
│ │ │ │ │ ├── run_04_a.golden.yml
│ │ │ │ │ ├── run_04_a.yml
│ │ │ │ │ ├── run_04_b.golden.yml
│ │ │ │ │ ├── run_04_b.yml
│ │ │ │ │ ├── run_05.golden.yml
│ │ │ │ │ ├── run_05.yml
│ │ │ │ │ ├── run_06.golden.yml
│ │ │ │ │ ├── run_06.yml
│ │ │ │ │ ├── run_07.golden.yml
│ │ │ │ │ ├── run_07.yml
│ │ │ │ │ ├── run_08.golden.yml
│ │ │ │ │ ├── run_08.yml
│ │ │ │ │ ├── run_09_a.golden.yml
│ │ │ │ │ ├── run_09_a.yml
│ │ │ │ │ ├── run_09_b.golden.yml
│ │ │ │ │ ├── run_09_b.yml
│ │ │ │ │ ├── run_10.golden.yml
│ │ │ │ │ ├── run_10.yml
│ │ │ │ │ ├── severity_01.golden.yml
│ │ │ │ │ ├── severity_01.yml
│ │ │ │ │ ├── severity_02.golden.yml
│ │ │ │ │ ├── severity_02.yml
│ │ │ │ │ ├── severity_03.golden.yml
│ │ │ │ │ ├── severity_03.yml
│ │ │ │ │ ├── unknown-fields.golden.yml
│ │ │ │ │ └── unknown-fields.yml
│ │ │ │ ├── versionone/
│ │ │ │ │ ├── base_rule.go
│ │ │ │ │ ├── config.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── issues.go
│ │ │ │ │ ├── linters.go
│ │ │ │ │ ├── linters_settings.go
│ │ │ │ │ ├── output.go
│ │ │ │ │ ├── run.go
│ │ │ │ │ └── severity.go
│ │ │ │ └── versiontwo/
│ │ │ │ ├── base_rule.go
│ │ │ │ ├── config.go
│ │ │ │ ├── formatters.go
│ │ │ │ ├── formatters_settings.go
│ │ │ │ ├── issues.go
│ │ │ │ ├── linters.go
│ │ │ │ ├── linters_exclusions.go
│ │ │ │ ├── linters_settings.go
│ │ │ │ ├── output.go
│ │ │ │ ├── output_formats.go
│ │ │ │ ├── run.go
│ │ │ │ └── severity.go
│ │ │ ├── testdata/
│ │ │ │ └── imports.go
│ │ │ └── vibra.go
│ │ ├── linters.go
│ │ ├── migrate.go
│ │ ├── root.go
│ │ ├── run.go
│ │ └── version.go
│ ├── config/
│ │ ├── base_loader.go
│ │ ├── base_rule.go
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── formatters.go
│ │ ├── formatters_settings.go
│ │ ├── issues.go
│ │ ├── linters.go
│ │ ├── linters_exclusions.go
│ │ ├── linters_exclusions_test.go
│ │ ├── linters_settings.go
│ │ ├── linters_settings_test.go
│ │ ├── loader.go
│ │ ├── output.go
│ │ ├── output_formats.go
│ │ ├── output_test.go
│ │ ├── placeholders.go
│ │ ├── run.go
│ │ ├── run_test.go
│ │ ├── severity.go
│ │ └── severity_test.go
│ ├── exitcodes/
│ │ └── exitcodes.go
│ ├── fsutils/
│ │ ├── basepath.go
│ │ ├── filecache.go
│ │ ├── fsutils.go
│ │ ├── fsutils_test.go
│ │ ├── fsutils_unix.go
│ │ ├── fsutils_windows.go
│ │ ├── linecache.go
│ │ ├── path_unix.go
│ │ └── path_windows.go
│ ├── goanalysis/
│ │ ├── issue.go
│ │ ├── linter.go
│ │ ├── load/
│ │ │ └── guard.go
│ │ ├── metalinter.go
│ │ ├── pkgerrors/
│ │ │ ├── errors.go
│ │ │ ├── extract.go
│ │ │ ├── extract_test.go
│ │ │ ├── parse.go
│ │ │ └── parse_test.go
│ │ ├── position.go
│ │ ├── runner.go
│ │ ├── runner_action.go
│ │ ├── runner_action_cache.go
│ │ ├── runner_action_test.go
│ │ ├── runner_checker.go
│ │ ├── runner_loadingpackage.go
│ │ ├── runners.go
│ │ └── runners_cache.go
│ ├── goformat/
│ │ ├── runner.go
│ │ └── runner_test.go
│ ├── goformatters/
│ │ ├── analyzer.go
│ │ ├── formatters.go
│ │ ├── gci/
│ │ │ ├── gci.go
│ │ │ └── internal/
│ │ │ ├── LICENSE
│ │ │ ├── config/
│ │ │ │ └── config.go
│ │ │ ├── readme.md
│ │ │ └── section/
│ │ │ ├── parser.go
│ │ │ ├── section.go
│ │ │ ├── standard.go
│ │ │ └── standard_list.go
│ │ ├── gofmt/
│ │ │ └── gofmt.go
│ │ ├── gofumpt/
│ │ │ └── gofumpt.go
│ │ ├── goimports/
│ │ │ └── goimports.go
│ │ ├── golines/
│ │ │ └── golines.go
│ │ ├── internal/
│ │ │ ├── commons.go
│ │ │ ├── diff.go
│ │ │ ├── diff_test.go
│ │ │ └── testdata/
│ │ │ ├── add_only.diff
│ │ │ ├── add_only_different_lines.diff
│ │ │ ├── add_only_in_all_diff.diff
│ │ │ ├── add_only_multiple_lines.diff
│ │ │ ├── add_only_on_first_line.diff
│ │ │ ├── add_only_on_first_line_with_shared_original_line.diff
│ │ │ ├── delete_last_line.diff
│ │ │ ├── delete_only_first_lines.diff
│ │ │ ├── gofmt_diff.diff
│ │ │ ├── replace_line.diff
│ │ │ └── replace_line_after_first_line_adding.diff
│ │ ├── meta_formatter.go
│ │ └── swaggo/
│ │ └── swaggo.go
│ ├── golinters/
│ │ ├── arangolint/
│ │ │ ├── arangolint.go
│ │ │ ├── arangolint_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── arangolint.go
│ │ │ ├── arangolint_cgo.go
│ │ │ ├── go.mod
│ │ │ └── go.sum
│ │ ├── asasalint/
│ │ │ ├── asasalint.go
│ │ │ ├── asasalint_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── asasalint.go
│ │ │ └── asasalint_cgo.go
│ │ ├── asciicheck/
│ │ │ ├── asciicheck.go
│ │ │ ├── asciicheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── asciicheck.go
│ │ │ └── asciicheck_cgo.go
│ │ ├── bidichk/
│ │ │ ├── bidichk.go
│ │ │ ├── bidichk_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── bidichk.go
│ │ │ └── bidichk_cgo.go
│ │ ├── bodyclose/
│ │ │ ├── bodyclose.go
│ │ │ ├── bodyclose_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── bodyclose.go
│ │ │ └── bodyclose_cgo.go
│ │ ├── canonicalheader/
│ │ │ ├── canonicalheader.go
│ │ │ ├── canonicalheader_test.go
│ │ │ └── testdata/
│ │ │ ├── canonicalheader.go
│ │ │ ├── canonicalheader_cgo.go
│ │ │ └── fix/
│ │ │ ├── in/
│ │ │ │ └── canonicalheader.go
│ │ │ └── out/
│ │ │ └── canonicalheader.go
│ │ ├── containedctx/
│ │ │ ├── containedctx.go
│ │ │ ├── containedctx_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── containedctx.go
│ │ │ └── containedctx_cgo.go
│ │ ├── contextcheck/
│ │ │ ├── contextcheck.go
│ │ │ ├── contextcheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── contextcheck.go
│ │ │ └── contextcheck_cgo.go
│ │ ├── copyloopvar/
│ │ │ ├── copyloopvar.go
│ │ │ ├── copyloopvar_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── copyloopvar.go
│ │ │ ├── copyloopvar.yml
│ │ │ ├── copyloopvar_cgo.go
│ │ │ ├── copyloopvar_custom.go
│ │ │ └── fix/
│ │ │ ├── in/
│ │ │ │ └── copyloopvar.go
│ │ │ └── out/
│ │ │ └── copyloopvar.go
│ │ ├── cyclop/
│ │ │ ├── cyclop.go
│ │ │ ├── cyclop_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── cyclop.go
│ │ │ ├── cyclop.yml
│ │ │ └── cyclop_cgo.go
│ │ ├── decorder/
│ │ │ ├── decorder.go
│ │ │ ├── decorder_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── decorder.go
│ │ │ ├── decorder_cgo.go
│ │ │ ├── decorder_custom.go
│ │ │ └── decorder_custom.yml
│ │ ├── depguard/
│ │ │ ├── depguard.go
│ │ │ ├── depguard_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── depguard.go
│ │ │ ├── depguard.yml
│ │ │ ├── depguard_additional_guards.go
│ │ │ ├── depguard_additional_guards.yml
│ │ │ ├── depguard_cgo.go
│ │ │ ├── depguard_ignore_file_rules.go
│ │ │ └── depguard_ignore_file_rules.yml
│ │ ├── dogsled/
│ │ │ ├── dogsled.go
│ │ │ ├── dogsled_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── dogsled.go
│ │ │ └── dogsled_cgo.go
│ │ ├── dupl/
│ │ │ ├── dupl.go
│ │ │ ├── dupl_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── dupl.go
│ │ │ ├── dupl.yml
│ │ │ └── dupl_cgo.go
│ │ ├── dupword/
│ │ │ ├── dupword.go
│ │ │ ├── dupword_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── dupword.go
│ │ │ ├── dupword_cgo.go
│ │ │ ├── dupword_comments_only.go
│ │ │ ├── dupword_comments_only.yml
│ │ │ ├── dupword_ignore.go
│ │ │ ├── dupword_ignore.yml
│ │ │ └── fix/
│ │ │ ├── in/
│ │ │ │ └── dupword.go
│ │ │ └── out/
│ │ │ └── dupword.go
│ │ ├── durationcheck/
│ │ │ ├── durationcheck.go
│ │ │ ├── durationcheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── durationcheck.go
│ │ │ └── durationcheck_cgo.go
│ │ ├── embeddedstructfieldcheck/
│ │ │ ├── embeddedstructfieldcheck.go
│ │ │ ├── embeddedstructfieldcheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── embeddedstructfieldcheck_comments.go
│ │ │ ├── embeddedstructfieldcheck_mutex.go
│ │ │ ├── embeddedstructfieldcheck_mutex.yml
│ │ │ ├── embeddedstructfieldcheck_simple.go
│ │ │ ├── embeddedstructfieldcheck_special_cases.go
│ │ │ └── fix/
│ │ │ ├── in/
│ │ │ │ ├── comments.go
│ │ │ │ └── simple.go
│ │ │ └── out/
│ │ │ ├── comments.go
│ │ │ └── simple.go
│ │ ├── err113/
│ │ │ ├── err113.go
│ │ │ ├── err113_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── err113.go
│ │ │ ├── err113_cgo.go
│ │ │ └── fix/
│ │ │ ├── in/
│ │ │ │ └── err113.go
│ │ │ └── out/
│ │ │ └── err113.go
│ │ ├── errcheck/
│ │ │ ├── errcheck.go
│ │ │ ├── errcheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── errcheck.go
│ │ │ ├── errcheck_cgo.go
│ │ │ ├── errcheck_exclude_functions.go
│ │ │ ├── errcheck_exclude_functions.yml
│ │ │ ├── errcheck_ignore_default.go
│ │ │ ├── errcheck_ignore_default.yml
│ │ │ ├── errcheck_type_assertions.go
│ │ │ └── errcheck_type_assertions.yml
│ │ ├── errchkjson/
│ │ │ ├── errchkjson.go
│ │ │ ├── errchkjson_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── errchkjson.go
│ │ │ ├── errchkjson.yml
│ │ │ ├── errchkjson_cgo.go
│ │ │ ├── errchkjson_check_error_free_encoding.go
│ │ │ ├── errchkjson_check_error_free_encoding.yml
│ │ │ ├── errchkjson_no_exported.go
│ │ │ └── errchkjson_no_exported.yml
│ │ ├── errname/
│ │ │ ├── errname.go
│ │ │ ├── errname_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── errname.go
│ │ │ └── errname_cgo.go
│ │ ├── errorlint/
│ │ │ ├── errorlint.go
│ │ │ ├── errorlint_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── errorlint.go
│ │ │ ├── errorlint_asserts.go
│ │ │ ├── errorlint_asserts.yml
│ │ │ ├── errorlint_cgo.go
│ │ │ ├── errorlint_comparison.go
│ │ │ ├── errorlint_comparison.yml
│ │ │ ├── errorlint_errorf.go
│ │ │ ├── errorlint_errorf.yml
│ │ │ └── fix/
│ │ │ ├── in/
│ │ │ │ └── errorlint.go
│ │ │ └── out/
│ │ │ └── errorlint.go
│ │ ├── exhaustive/
│ │ │ ├── exhaustive.go
│ │ │ ├── exhaustive_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── exhaustive.go
│ │ │ ├── exhaustive_cgo.go
│ │ │ ├── exhaustive_default.go
│ │ │ ├── exhaustive_default.yml
│ │ │ ├── exhaustive_generated.go
│ │ │ ├── exhaustive_ignore_enum_members.go
│ │ │ └── exhaustive_ignore_enum_members.yml
│ │ ├── exhaustruct/
│ │ │ ├── exhaustruct.go
│ │ │ ├── exhaustruct_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── exhaustruct.go
│ │ │ ├── exhaustruct_cgo.go
│ │ │ ├── exhaustruct_custom.go
│ │ │ └── exhaustruct_custom.yml
│ │ ├── exptostd/
│ │ │ ├── exptostd.go
│ │ │ ├── exptostd_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── exptostd.go
│ │ │ ├── exptostd_cgo.go
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── exptostd.go
│ │ │ │ └── out/
│ │ │ │ └── exptostd.go
│ │ │ ├── go.mod
│ │ │ └── go.sum
│ │ ├── fatcontext/
│ │ │ ├── fatcontext.go
│ │ │ ├── fatcontext_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fatcontext.go
│ │ │ ├── fatcontext_cgo.go
│ │ │ ├── fatcontext_structpointer.go
│ │ │ ├── fatcontext_structpointer.yml
│ │ │ └── fix/
│ │ │ ├── in/
│ │ │ │ └── fatcontext.go
│ │ │ └── out/
│ │ │ └── fatcontext.go
│ │ ├── forbidigo/
│ │ │ ├── forbidigo.go
│ │ │ ├── forbidigo_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── forbidigo.yml
│ │ │ ├── forbidigo_cgo.go
│ │ │ ├── forbidigo_example.go
│ │ │ ├── forbidigo_example_test.go
│ │ │ ├── forbidigo_include_godoc_examples.yml
│ │ │ ├── forbidigo_include_godoc_examples_test.go
│ │ │ ├── forbidigo_struct.yml
│ │ │ └── forbidigo_struct_config.go
│ │ ├── forcetypeassert/
│ │ │ ├── forcetypeassert.go
│ │ │ ├── forcetypeassert_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── forcetypeassert.go
│ │ │ └── forcetypeassert_cgo.go
│ │ ├── funcorder/
│ │ │ ├── funcorder.go
│ │ │ ├── funcorder_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── funcorder.go
│ │ │ ├── funcorder_disable_constructor.go
│ │ │ ├── funcorder_disable_constructor.yml
│ │ │ ├── funcorder_struct_method.go
│ │ │ └── funcorder_struct_method.yml
│ │ ├── funlen/
│ │ │ ├── funlen.go
│ │ │ ├── funlen_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── funlen.go
│ │ │ ├── funlen_cgo.go
│ │ │ ├── funlen_custom.go
│ │ │ ├── funlen_custom.yml
│ │ │ ├── funlen_ignore_comments.go
│ │ │ └── funlen_ignore_comments.yml
│ │ ├── gci/
│ │ │ ├── gci.go
│ │ │ ├── gci_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── gci.go
│ │ │ │ └── out/
│ │ │ │ └── gci.go
│ │ │ ├── gci.go
│ │ │ ├── gci.yml
│ │ │ ├── gci_cgo.go
│ │ │ ├── gci_go124.go
│ │ │ └── gci_go124.yml
│ │ ├── ginkgolinter/
│ │ │ ├── ginkgolinter.go
│ │ │ ├── ginkgolinter_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── ginkgolinter.go
│ │ │ ├── ginkgolinter_allow_havelen0.yml
│ │ │ ├── ginkgolinter_cgo.go
│ │ │ ├── ginkgolinter_default.yml
│ │ │ ├── ginkgolinter_havelen0.go
│ │ │ ├── ginkgolinter_suppress_async.go
│ │ │ ├── ginkgolinter_suppress_async.yml
│ │ │ ├── ginkgolinter_suppress_compare.go
│ │ │ ├── ginkgolinter_suppress_compare.yml
│ │ │ ├── ginkgolinter_suppress_err.go
│ │ │ ├── ginkgolinter_suppress_err.yml
│ │ │ ├── ginkgolinter_suppress_focused_containers.go
│ │ │ ├── ginkgolinter_suppress_focused_containers.yml
│ │ │ ├── ginkgolinter_suppress_len.go
│ │ │ ├── ginkgolinter_suppress_len.yml
│ │ │ ├── ginkgolinter_suppress_nil.go
│ │ │ ├── ginkgolinter_suppress_nil.yml
│ │ │ ├── go.mod
│ │ │ └── go.sum
│ │ ├── gocheckcompilerdirectives/
│ │ │ ├── gocheckcompilerdirectives.go
│ │ │ ├── gocheckcompilerdirectives_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── gocheckcompilerdirectives.go
│ │ │ └── gocheckcompilerdirectives_cgo.go
│ │ ├── gochecknoglobals/
│ │ │ ├── gochecknoglobals.go
│ │ │ ├── gochecknoglobals_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── gochecknoglobals.go
│ │ │ └── gochecknoglobals_cgo.go
│ │ ├── gochecknoinits/
│ │ │ ├── gochecknoinits.go
│ │ │ ├── gochecknoinits_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── gochecknoinits.go
│ │ │ └── gochecknoinits_cgo.go
│ │ ├── gochecksumtype/
│ │ │ ├── gochecksumtype.go
│ │ │ ├── gochecksumtype_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── gochecksumtype.go
│ │ │ ├── gochecksumtype_cgo.go
│ │ │ ├── gochecksumtype_custom.go
│ │ │ └── gochecksumtype_custom.yml
│ │ ├── gocognit/
│ │ │ ├── gocognit.go
│ │ │ ├── gocognit_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── gocognit.go
│ │ │ ├── gocognit.yml
│ │ │ └── gocognit_cgo.go
│ │ ├── goconst/
│ │ │ ├── goconst.go
│ │ │ ├── goconst_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── goconst.go
│ │ │ ├── goconst_calls_enabled.go
│ │ │ ├── goconst_calls_enabled.yml
│ │ │ ├── goconst_cgo.go
│ │ │ ├── goconst_dont_ignore_test.go
│ │ │ ├── goconst_eval_and_find_duplicates.go
│ │ │ ├── goconst_eval_and_find_duplicates.yml
│ │ │ ├── goconst_eval_const_expressions.go
│ │ │ ├── goconst_eval_const_expressions.yml
│ │ │ ├── goconst_find_duplicates.go
│ │ │ └── goconst_find_duplicates.yml
│ │ ├── gocritic/
│ │ │ ├── gocritic.go
│ │ │ ├── gocritic_integration_test.go
│ │ │ ├── gocritic_settings.go
│ │ │ ├── gocritic_settings_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── gocritic.go
│ │ │ │ └── out/
│ │ │ │ └── gocritic.go
│ │ │ ├── gocritic-fix.yml
│ │ │ ├── gocritic.go
│ │ │ ├── gocritic.yml
│ │ │ ├── gocritic_cgo.go
│ │ │ ├── gocritic_importShadow.go
│ │ │ ├── gocritic_inportShadow.yml
│ │ │ └── ruleguard/
│ │ │ ├── README.md
│ │ │ ├── preferWriteString.go
│ │ │ ├── rangeExprCopy.go
│ │ │ └── stringsSimplify.go
│ │ ├── gocyclo/
│ │ │ ├── gocyclo.go
│ │ │ ├── gocyclo_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── gocyclo.go
│ │ │ ├── gocyclo.yml
│ │ │ └── gocyclo_cgo.go
│ │ ├── godoclint/
│ │ │ ├── godoclint.go
│ │ │ ├── godoclint_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── godoclint.yml
│ │ │ ├── godoclint_default_fail.go
│ │ │ ├── godoclint_default_pass.go
│ │ │ ├── godoclint_full_fail.go
│ │ │ ├── godoclint_full_pass.go
│ │ │ └── godoclint_full_pass_test.go
│ │ ├── godot/
│ │ │ ├── godot.go
│ │ │ ├── godot_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── godot.go
│ │ │ │ └── out/
│ │ │ │ └── godot.go
│ │ │ ├── godot.go
│ │ │ └── godot_cgo.go
│ │ ├── godox/
│ │ │ ├── godox.go
│ │ │ ├── godox_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── godox.go
│ │ │ ├── godox.yml
│ │ │ └── godox_cgo.go
│ │ ├── gofmt/
│ │ │ ├── gofmt.go
│ │ │ ├── gofmt_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ ├── gofmt.go
│ │ │ │ │ └── gofmt_rewrite_rules.go
│ │ │ │ └── out/
│ │ │ │ ├── gofmt.go
│ │ │ │ └── gofmt_rewrite_rules.go
│ │ │ ├── gofmt.go
│ │ │ ├── gofmt.yml
│ │ │ ├── gofmt_cgo.go
│ │ │ ├── gofmt_no_simplify.go
│ │ │ ├── gofmt_no_simplify.yml
│ │ │ ├── gofmt_rewrite_rules.go
│ │ │ ├── gofmt_rewrite_rules.yml
│ │ │ └── gofmt_too_many_empty_lines.go
│ │ ├── gofumpt/
│ │ │ ├── gofumpt.go
│ │ │ ├── gofumpt_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ ├── gofumpt.go
│ │ │ │ │ └── gofumpt_cgo.go
│ │ │ │ └── out/
│ │ │ │ ├── gofumpt.go
│ │ │ │ └── gofumpt_cgo.go
│ │ │ ├── gofumpt-fix.yml
│ │ │ ├── gofumpt.go
│ │ │ ├── gofumpt.yml
│ │ │ ├── gofumpt_cgo.go
│ │ │ ├── gofumpt_too_many_empty_lines.go
│ │ │ ├── gofumpt_with_extra.go
│ │ │ └── gofumpt_with_extra.yml
│ │ ├── goheader/
│ │ │ ├── goheader.go
│ │ │ ├── goheader_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ ├── goheader_1.go
│ │ │ │ │ ├── goheader_2.go
│ │ │ │ │ ├── goheader_3.go
│ │ │ │ │ └── goheader_4.go
│ │ │ │ └── out/
│ │ │ │ ├── goheader_1.go
│ │ │ │ ├── goheader_2.go
│ │ │ │ ├── goheader_3.go
│ │ │ │ └── goheader_4.go
│ │ │ ├── goheader-fix.yml
│ │ │ ├── goheader.yml
│ │ │ ├── goheader_bad.go
│ │ │ ├── goheader_cgo.go
│ │ │ └── goheader_good.go
│ │ ├── goimports/
│ │ │ ├── goimports.go
│ │ │ ├── goimports_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ ├── goimports.go
│ │ │ │ │ └── goimports_cgo.go
│ │ │ │ └── out/
│ │ │ │ ├── goimports.go
│ │ │ │ └── goimports_cgo.go
│ │ │ ├── goimports.go
│ │ │ ├── goimports.yml
│ │ │ ├── goimports_cgo.go
│ │ │ ├── goimports_local.go
│ │ │ └── goimports_local.yml
│ │ ├── golines/
│ │ │ ├── golines.go
│ │ │ ├── golines_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ ├── golines-custom.go
│ │ │ │ │ └── golines.go
│ │ │ │ └── out/
│ │ │ │ ├── golines-custom.go
│ │ │ │ └── golines.go
│ │ │ ├── golines-custom.yml
│ │ │ ├── golines.go
│ │ │ └── golines.yml
│ │ ├── gomoddirectives/
│ │ │ └── gomoddirectives.go
│ │ ├── gomodguard/
│ │ │ ├── gomodguard.go
│ │ │ ├── gomodguard_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── go.mod
│ │ │ ├── go.sum
│ │ │ ├── gomodguard.go
│ │ │ ├── gomodguard.yml
│ │ │ └── gomodguard_cgo.go
│ │ ├── goprintffuncname/
│ │ │ ├── goprintffuncname.go
│ │ │ ├── goprintffuncname_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── goprintffuncname.go
│ │ │ └── goprintffuncname_cgo.go
│ │ ├── gosec/
│ │ │ ├── gosec.go
│ │ │ ├── gosec_integration_test.go
│ │ │ ├── gosec_test.go
│ │ │ └── testdata/
│ │ │ ├── gosec.go
│ │ │ ├── gosec.yml
│ │ │ ├── gosec_cgo.go
│ │ │ ├── gosec_global_option.go
│ │ │ ├── gosec_global_option.yml
│ │ │ ├── gosec_nosec.go
│ │ │ ├── gosec_nosec.yml
│ │ │ ├── gosec_rules_config.go
│ │ │ ├── gosec_severity_confidence.go
│ │ │ └── gosec_severity_confidence.yml
│ │ ├── gosmopolitan/
│ │ │ ├── gosmopolitan.go
│ │ │ ├── gosmopolitan_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── gosmopolitan.go
│ │ │ ├── gosmopolitan_allow_time_local.go
│ │ │ ├── gosmopolitan_allow_time_local.yml
│ │ │ ├── gosmopolitan_cgo.go
│ │ │ ├── gosmopolitan_dont_ignore_test.go
│ │ │ ├── gosmopolitan_escape_hatches.go
│ │ │ ├── gosmopolitan_escape_hatches.yml
│ │ │ ├── gosmopolitan_scripts.go
│ │ │ └── gosmopolitan_scripts.yml
│ │ ├── govet/
│ │ │ ├── govet.go
│ │ │ ├── govet_integration_test.go
│ │ │ ├── govet_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── govet.go
│ │ │ │ └── out/
│ │ │ │ └── govet.go
│ │ │ ├── govet.go
│ │ │ ├── govet.yml
│ │ │ ├── govet_cgo.go
│ │ │ ├── govet_custom_formatter.go
│ │ │ ├── govet_fieldalignment.go
│ │ │ ├── govet_fieldalignment.yml
│ │ │ ├── govet_fix.yml
│ │ │ ├── govet_ifaceassert.go
│ │ │ └── govet_ifaceassert.yml
│ │ ├── grouper/
│ │ │ ├── grouper.go
│ │ │ ├── grouper_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── grouper.go
│ │ │ ├── grouper.yml
│ │ │ └── grouper_cgo.go
│ │ ├── iface/
│ │ │ ├── iface.go
│ │ │ ├── iface_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── iface.go
│ │ │ │ └── out/
│ │ │ │ └── iface.go
│ │ │ ├── iface_all.go
│ │ │ ├── iface_all.yml
│ │ │ ├── iface_cgo.go
│ │ │ ├── iface_default.go
│ │ │ ├── iface_fix.yml
│ │ │ ├── iface_identical.go
│ │ │ ├── iface_identical.yml
│ │ │ ├── iface_opaque.go
│ │ │ ├── iface_opaque.yml
│ │ │ ├── iface_unexported.go
│ │ │ ├── iface_unexported.yml
│ │ │ ├── iface_unused.go
│ │ │ └── iface_unused.yml
│ │ ├── importas/
│ │ │ ├── importas.go
│ │ │ ├── importas_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── importas.go
│ │ │ │ └── out/
│ │ │ │ └── importas.go
│ │ │ ├── importas.go
│ │ │ ├── importas.yml
│ │ │ ├── importas_cgo.go
│ │ │ ├── importas_several_empty_aliases.go
│ │ │ ├── importas_several_empty_aliases.yml
│ │ │ ├── importas_strict.go
│ │ │ └── importas_strict.yml
│ │ ├── inamedparam/
│ │ │ ├── inamedparam.go
│ │ │ ├── inamedparam_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── inamedparam.go
│ │ │ ├── inamedparam_cgo.go
│ │ │ ├── inamedparam_skip_single_param.go
│ │ │ └── inamedparam_skip_single_param.yml
│ │ ├── ineffassign/
│ │ │ ├── ineffassign.go
│ │ │ ├── ineffassign_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── ineffassign.go
│ │ │ └── ineffassign_cgo.go
│ │ ├── interfacebloat/
│ │ │ ├── interfacebloat.go
│ │ │ ├── interfacebloat_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── interfacebloat.go
│ │ │ └── interfacebloat_cgo.go
│ │ ├── internal/
│ │ │ ├── commons.go
│ │ │ └── util.go
│ │ ├── intrange/
│ │ │ ├── intrange.go
│ │ │ ├── intrange_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── intrange.go
│ │ │ │ └── out/
│ │ │ │ └── intrange.go
│ │ │ ├── intrange.go
│ │ │ └── intrange_cgo.go
│ │ ├── iotamixing/
│ │ │ ├── iotamixing.go
│ │ │ ├── iotamixing_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── iotamixing.go
│ │ │ ├── iotamixing_report-individual.go
│ │ │ └── iotamixing_report-individual.yml
│ │ ├── ireturn/
│ │ │ ├── ireturn.go
│ │ │ ├── ireturn_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── ireturn.go
│ │ │ ├── ireturn_allow.go
│ │ │ ├── ireturn_allow.yml
│ │ │ ├── ireturn_cgo.go
│ │ │ ├── ireturn_reject_generics.go
│ │ │ ├── ireturn_reject_generics.yml
│ │ │ ├── ireturn_reject_stdlib.go
│ │ │ └── ireturn_reject_stdlib.yml
│ │ ├── lll/
│ │ │ ├── lll.go
│ │ │ ├── lll_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── lll.go
│ │ │ ├── lll.yml
│ │ │ ├── lll_cgo.go
│ │ │ ├── lll_import.yml
│ │ │ ├── lll_import_multi.go
│ │ │ ├── lll_import_single.go
│ │ │ ├── lll_max_scan_token_size.go
│ │ │ └── lll_max_scan_token_size_cgo.go
│ │ ├── loggercheck/
│ │ │ ├── loggercheck.go
│ │ │ ├── loggercheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── go.mod
│ │ │ ├── go.sum
│ │ │ ├── loggercheck_cgo.go
│ │ │ ├── loggercheck_custom.go
│ │ │ ├── loggercheck_custom.yml
│ │ │ ├── loggercheck_default.go
│ │ │ ├── loggercheck_kitlogonly.go
│ │ │ ├── loggercheck_kitlogonly.yml
│ │ │ ├── loggercheck_logronly.go
│ │ │ ├── loggercheck_logronly.yml
│ │ │ ├── loggercheck_noprintflike.go
│ │ │ ├── loggercheck_noprintflike.yml
│ │ │ ├── loggercheck_requirestringkey.go
│ │ │ ├── loggercheck_requirestringkey.yml
│ │ │ ├── loggercheck_slogonly.go
│ │ │ ├── loggercheck_slogonly.yml
│ │ │ ├── loggercheck_zaponly.go
│ │ │ └── loggercheck_zaponly.yml
│ │ ├── maintidx/
│ │ │ ├── maintidx.go
│ │ │ ├── maintidx_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── maintidx.go
│ │ │ ├── maintidx_cgo.go
│ │ │ ├── maintidx_under_100.go
│ │ │ └── maintidx_under_100.yml
│ │ ├── makezero/
│ │ │ ├── makezero.go
│ │ │ ├── makezero_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── makezero.go
│ │ │ ├── makezero_always.go
│ │ │ ├── makezero_always.yml
│ │ │ └── makezero_cgo.go
│ │ ├── mirror/
│ │ │ ├── mirror.go
│ │ │ ├── mirror_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── mirror.go
│ │ │ │ └── out/
│ │ │ │ └── mirror.go
│ │ │ ├── mirror.go
│ │ │ └── mirror_cgo.go
│ │ ├── misspell/
│ │ │ ├── misspell.go
│ │ │ ├── misspell_integration_test.go
│ │ │ ├── misspell_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── misspell.go
│ │ │ │ └── out/
│ │ │ │ └── misspell.go
│ │ │ ├── misspell.go
│ │ │ ├── misspell.yml
│ │ │ ├── misspell_cgo.go
│ │ │ ├── misspell_custom.go
│ │ │ └── misspell_custom.yml
│ │ ├── mnd/
│ │ │ ├── mnd.go
│ │ │ ├── mnd_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── mnd.go
│ │ │ ├── mnd_cgo.go
│ │ │ ├── mnd_custom.go
│ │ │ └── mnd_custom.yml
│ │ ├── modernize/
│ │ │ ├── modernize.go
│ │ │ ├── modernize_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ ├── any.go
│ │ │ │ │ ├── fieldsseq.go
│ │ │ │ │ ├── fmtappendf.go
│ │ │ │ │ ├── forvar.go
│ │ │ │ │ ├── mapsloop.go
│ │ │ │ │ ├── mapsloop_dot.go
│ │ │ │ │ ├── minmax.go
│ │ │ │ │ ├── rangeint.go
│ │ │ │ │ ├── reflecttypefor.go
│ │ │ │ │ ├── slicescontains.go
│ │ │ │ │ ├── slicessort.go
│ │ │ │ │ ├── splitseq.go
│ │ │ │ │ ├── stditerators.go
│ │ │ │ │ ├── stringsbuilder.go
│ │ │ │ │ ├── stringscutprefix.go
│ │ │ │ │ ├── testingcontext_test.go
│ │ │ │ │ └── waitgroup.go
│ │ │ │ └── out/
│ │ │ │ ├── any.go
│ │ │ │ ├── fieldsseq.go
│ │ │ │ ├── fmtappendf.go
│ │ │ │ ├── forvar.go
│ │ │ │ ├── mapsloop.go
│ │ │ │ ├── mapsloop_dot.go
│ │ │ │ ├── minmax.go
│ │ │ │ ├── rangeint.go
│ │ │ │ ├── reflecttypefor.go
│ │ │ │ ├── slicescontains.go
│ │ │ │ ├── slicessort.go
│ │ │ │ ├── splitseq.go
│ │ │ │ ├── stditerators.go
│ │ │ │ ├── stringsbuilder.go
│ │ │ │ ├── stringscutprefix.go
│ │ │ │ ├── testingcontext_test.go
│ │ │ │ └── waitgroup.go
│ │ │ ├── modernize_any.go
│ │ │ ├── modernize_custom.go
│ │ │ └── modernize_custom.yml
│ │ ├── musttag/
│ │ │ ├── musttag.go
│ │ │ ├── musttag_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── musttag.go
│ │ │ ├── musttag.yml
│ │ │ ├── musttag_cgo.go
│ │ │ └── musttag_custom.go
│ │ ├── nakedret/
│ │ │ ├── nakedret.go
│ │ │ ├── nakedret_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── nakedret.go
│ │ │ │ └── out/
│ │ │ │ └── nakedret.go
│ │ │ ├── nakedret.go
│ │ │ └── nakedret_cgo.go
│ │ ├── nestif/
│ │ │ ├── nestif.go
│ │ │ ├── nestif_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── nestif.go
│ │ │ ├── nestif.yml
│ │ │ └── nestif_cgo.go
│ │ ├── nilerr/
│ │ │ ├── nilerr.go
│ │ │ ├── nilerr_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── nilerr.go
│ │ │ └── nilerr_cgo.go
│ │ ├── nilnesserr/
│ │ │ ├── nilnesserr.go
│ │ │ ├── nilnesserr_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── nilnesserr.go
│ │ │ └── nilnesserr_cgo.go
│ │ ├── nilnil/
│ │ │ ├── nilnil.go
│ │ │ ├── nilnil_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── nilnil.go
│ │ │ ├── nilnil_cgo.go
│ │ │ ├── nilnil_detect_opposite.go
│ │ │ ├── nilnil_detect_opposite.yml
│ │ │ ├── nilnil_multiple_nils.go
│ │ │ ├── nilnil_multiple_nils.yml
│ │ │ ├── nilnil_pointers_only.go
│ │ │ └── nilnil_pointers_only.yml
│ │ ├── nlreturn/
│ │ │ ├── nlreturn.go
│ │ │ ├── nlreturn_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── nlreturn.go
│ │ │ │ └── out/
│ │ │ │ └── nlreturn.go
│ │ │ ├── nlreturn-block-size.go
│ │ │ ├── nlreturn-block-size.yml
│ │ │ ├── nlreturn.go
│ │ │ └── nlreturn_cgo.go
│ │ ├── noctx/
│ │ │ ├── noctx.go
│ │ │ ├── noctx_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── noctx.go
│ │ │ └── noctx_cgo.go
│ │ ├── noinlineerr/
│ │ │ ├── noinlineerr.go
│ │ │ ├── noinlineerr_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── noinlineerr.go
│ │ │ │ └── out/
│ │ │ │ └── noinlineerr.go
│ │ │ └── noinlineerr.go
│ │ ├── nolintlint/
│ │ │ ├── internal/
│ │ │ │ ├── README.md
│ │ │ │ ├── issues.go
│ │ │ │ ├── nolintlint.go
│ │ │ │ └── nolintlint_test.go
│ │ │ ├── nolintlint.go
│ │ │ ├── nolintlint_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── nolintlint.go
│ │ │ │ └── out/
│ │ │ │ └── nolintlint.go
│ │ │ ├── nolintlint.go
│ │ │ ├── nolintlint.yml
│ │ │ ├── nolintlint_cgo.go
│ │ │ ├── nolintlint_unused.go
│ │ │ └── nolintlint_unused.yml
│ │ ├── nonamedreturns/
│ │ │ ├── nonamedreturns.go
│ │ │ ├── nonamedreturns_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── nonamedreturns.go
│ │ │ ├── nonamedreturns_cgo.go
│ │ │ ├── nonamedreturns_custom.go
│ │ │ └── nonamedreturns_custom.yml
│ │ ├── nosprintfhostport/
│ │ │ ├── nosprintfhostport.go
│ │ │ ├── nosprintfhostport_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── nosprintfhostport.go
│ │ │ └── nosprintfhostport_cgo.go
│ │ ├── paralleltest/
│ │ │ ├── paralleltest.go
│ │ │ ├── paralleltest_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── paralleltest_custom_test.go
│ │ │ ├── paralleltest_custom_test.yml
│ │ │ └── paralleltest_test.go
│ │ ├── perfsprint/
│ │ │ ├── perfsprint.go
│ │ │ ├── perfsprint_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── perfsprint.go
│ │ │ │ └── out/
│ │ │ │ └── perfsprint.go
│ │ │ ├── perfsprint.go
│ │ │ ├── perfsprint_cgo.go
│ │ │ ├── perfsprint_custom.go
│ │ │ └── perfsprint_custom.yml
│ │ ├── prealloc/
│ │ │ ├── prealloc.go
│ │ │ ├── prealloc_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── prealloc.go
│ │ │ └── prealloc_cgo.go
│ │ ├── predeclared/
│ │ │ ├── predeclared.go
│ │ │ ├── predeclared_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── predeclared.go
│ │ │ ├── predeclared_cgo.go
│ │ │ ├── predeclared_custom.go
│ │ │ └── predeclared_custom.yml
│ │ ├── promlinter/
│ │ │ ├── promlinter.go
│ │ │ ├── promlinter_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── promlinter.go
│ │ │ └── promlinter_cgo.go
│ │ ├── protogetter/
│ │ │ ├── protogetter.go
│ │ │ ├── protogetter_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── go.mod
│ │ │ ├── go.sum
│ │ │ ├── proto/
│ │ │ │ ├── test.go
│ │ │ │ ├── test.pb.go
│ │ │ │ ├── test.proto
│ │ │ │ └── test_grpc.pb.go
│ │ │ ├── protogetter.go
│ │ │ └── protogetter_cgo.go
│ │ ├── reassign/
│ │ │ ├── reassign.go
│ │ │ ├── reassign_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── reassign.go
│ │ │ ├── reassign_cgo.go
│ │ │ ├── reassign_patterns.go
│ │ │ └── reassign_patterns.yml
│ │ ├── recvcheck/
│ │ │ ├── recvcheck.go
│ │ │ ├── recvcheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── recvcheck.go
│ │ │ └── recvcheck_cgo.go
│ │ ├── revive/
│ │ │ ├── revive.go
│ │ │ ├── revive_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── revive.go
│ │ │ │ └── out/
│ │ │ │ └── revive.go
│ │ │ ├── revive-fix.yml
│ │ │ ├── revive.go
│ │ │ ├── revive.yml
│ │ │ ├── revive_cgo.go
│ │ │ └── revive_default.go
│ │ ├── rowserrcheck/
│ │ │ ├── rowserrcheck.go
│ │ │ ├── rowserrcheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── rowserrcheck.go
│ │ │ └── rowserrcheck_cgo.go
│ │ ├── sloglint/
│ │ │ ├── sloglint.go
│ │ │ ├── sloglint_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── sloglint.go
│ │ │ ├── sloglint_args_on_sep_lines.go
│ │ │ ├── sloglint_args_on_sep_lines.yml
│ │ │ ├── sloglint_attr_only.go
│ │ │ ├── sloglint_attr_only.yml
│ │ │ ├── sloglint_cgo.go
│ │ │ ├── sloglint_context_only.go
│ │ │ ├── sloglint_context_only.yml
│ │ │ ├── sloglint_forbidden_keys.go
│ │ │ ├── sloglint_forbidden_keys.yml
│ │ │ ├── sloglint_key_naming_case.go
│ │ │ ├── sloglint_key_naming_case.yml
│ │ │ ├── sloglint_kv_only.go
│ │ │ ├── sloglint_kv_only.yml
│ │ │ ├── sloglint_no_raw_keys.go
│ │ │ ├── sloglint_no_raw_keys.yml
│ │ │ ├── sloglint_static_msg.go
│ │ │ └── sloglint_static_msg.yml
│ │ ├── spancheck/
│ │ │ ├── spancheck.go
│ │ │ ├── spancheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── go.mod
│ │ │ ├── go.sum
│ │ │ ├── spancheck.go
│ │ │ ├── spancheck_cgo.go
│ │ │ ├── spancheck_enable_all.go
│ │ │ ├── spancheck_enable_all.yml
│ │ │ ├── spancheck_keep_default.go
│ │ │ └── spancheck_keep_default.yml
│ │ ├── sqlclosecheck/
│ │ │ ├── sqlclosecheck.go
│ │ │ ├── sqlclosecheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── sqlclosecheck.go
│ │ │ └── sqlclosecheck_cgo.go
│ │ ├── staticcheck/
│ │ │ ├── staticcheck.go
│ │ │ ├── staticcheck_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ ├── gosimple.go
│ │ │ │ │ ├── staticcheck.go
│ │ │ │ │ └── stylecheck.go
│ │ │ │ └── out/
│ │ │ │ ├── gosimple.go
│ │ │ │ ├── staticcheck.go
│ │ │ │ └── stylecheck.go
│ │ │ ├── gosimple.go
│ │ │ ├── gosimple.yml
│ │ │ ├── gosimple_cgo.go
│ │ │ ├── staticcheck.go
│ │ │ ├── staticcheck.yml
│ │ │ ├── staticcheck_cgo.go
│ │ │ ├── stylecheck.go
│ │ │ ├── stylecheck.yml
│ │ │ ├── stylecheck_cgo.go
│ │ │ ├── stylecheck_empty.go
│ │ │ ├── stylecheck_empty.yml
│ │ │ ├── stylecheck_nil.go
│ │ │ └── stylecheck_nil.yml
│ │ ├── swaggo/
│ │ │ ├── swaggo.go
│ │ │ ├── swaggo_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── swaggo.go
│ │ │ │ └── out/
│ │ │ │ └── swaggo.go
│ │ │ ├── swaggo.go
│ │ │ └── swaggo.yml
│ │ ├── tagalign/
│ │ │ ├── tagalign.go
│ │ │ ├── tagalign_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── fix/
│ │ │ │ ├── in/
│ │ │ │ │ └── tagalign.go
│ │ │ │ └── out/
│ │ │ │ └── tagalign.go
│ │ │ ├── tagalign.go
│ │ │ ├── tagalign_align_only.go
│ │ │ ├── tagalign_align_only.yml
│ │ │ ├── tagalign_cgo.go
│ │ │ ├── tagalign_order_only.go
│ │ │ ├── tagalign_order_only.yml
│ │ │ ├── tagalign_sort_only.go
│ │ │ ├── tagalign_sort_only.yml
│ │ │ ├── tagalign_strict.go
│ │ │ └── tagalign_strict.yml
│ │ ├── tagliatelle/
│ │ │ ├── tagliatelle.go
│ │ │ ├── tagliatelle_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── tagliatelle.go
│ │ │ ├── tagliatelle_cgo.go
│ │ │ ├── tagliatelle_ignored_fields.go
│ │ │ ├── tagliatelle_ignored_fields.yml
│ │ │ ├── tagliatelle_initialism_overrides.go
│ │ │ └── tagliatelle_initialism_overrides.yml
│ │ ├── testableexamples/
│ │ │ ├── testableexamples.go
│ │ │ ├── testableexamples_integration_test.go
│ │ │ └── testdata/
│ │ │ ├── testableexamples_test.go
│ │ │ └── testableexamples_test_cgo.go
│ │ ├── testifylint/
│ │ │ ├── testdata/
│ │ │ │ ├── fix/
│ │ │ │ │ ├── in/
│ │ │ │ │ │ └── testifylint.go
│ │ │ │ │ └── out/
│ │ │ │ │ └── testifylint.go
│ │ │ │ ├── testifylint.go
│ │ │ │ ├── testifylint_bool_compare_only.go
│ │ │ │ ├── testifylint_bool_compare_only.yml
│ │ │ │ ├── testifylint_cgo.go
│ │ │ │ ├── testifylint_formatter_dont_require_string_msg.go
│ │ │ │ ├── testifylint_formatter_dont_require_string_msg.yml
│ │ │ │ ├── testifylint_formatter_only.go
│ │ │ │ ├── testifylint_formatter_only.yml
│ │ │ │ ├── testifylint_require_error_only.go
│ │ │ │ └── testifylint_require_error_only.yml
│ │ │ ├── testifylint.go
│ │ │ └── testifylint_integration_test.go
│ │ ├── testpackage/
│ │ │ ├── testdata/
│ │ │ │ └── testpackage_test.go
│ │ │ ├── testpackage.go
│ │ │ └── testpackage_integration_test.go
│ │ ├── thelper/
│ │ │ ├── testdata/
│ │ │ │ ├── thelper.go
│ │ │ │ ├── thelper.yml
│ │ │ │ ├── thelper_cgo.go
│ │ │ │ ├── thelper_fuzz.go
│ │ │ │ └── thelper_with_options.go
│ │ │ ├── thelper.go
│ │ │ └── thelper_integration_test.go
│ │ ├── tparallel/
│ │ │ ├── testdata/
│ │ │ │ ├── tparallel_cgo.go
│ │ │ │ ├── tparallel_happy_path_test.go
│ │ │ │ ├── tparallel_missing_subtest_test.go
│ │ │ │ └── tparallel_missing_toplevel_test.go
│ │ │ ├── tparallel.go
│ │ │ └── tparallel_integration_test.go
│ │ ├── typecheck.go
│ │ ├── unconvert/
│ │ │ ├── testdata/
│ │ │ │ ├── unconvert.go
│ │ │ │ └── unconvert_cgo.go
│ │ │ ├── unconvert.go
│ │ │ └── unconvert_integration_test.go
│ │ ├── unparam/
│ │ │ ├── testdata/
│ │ │ │ ├── unparam.go
│ │ │ │ └── unparam_cgo.go
│ │ │ ├── unparam.go
│ │ │ └── unparam_integration_test.go
│ │ ├── unqueryvet/
│ │ │ ├── testdata/
│ │ │ │ ├── unqueryvet.go
│ │ │ │ ├── unqueryvet_custom.go
│ │ │ │ └── unqueryvet_custom.yml
│ │ │ ├── unqueryvet.go
│ │ │ └── unqueryvet_integration_test.go
│ │ ├── unused/
│ │ │ ├── testdata/
│ │ │ │ ├── unused.go
│ │ │ │ └── unused_cgo.go
│ │ │ ├── unused.go
│ │ │ └── unused_integration_test.go
│ │ ├── usestdlibvars/
│ │ │ ├── testdata/
│ │ │ │ ├── fix/
│ │ │ │ │ ├── in/
│ │ │ │ │ │ └── usestdlibvars.go
│ │ │ │ │ └── out/
│ │ │ │ │ └── usestdlibvars.go
│ │ │ │ ├── usestdlibvars.go
│ │ │ │ ├── usestdlibvars_cgo.go
│ │ │ │ ├── usestdlibvars_non_default.go
│ │ │ │ └── usestdlibvars_non_default.yml
│ │ │ ├── usestdlibvars.go
│ │ │ └── usestdlibvars_integration_test.go
│ │ ├── usetesting/
│ │ │ ├── testdata/
│ │ │ │ ├── fix/
│ │ │ │ │ ├── in/
│ │ │ │ │ │ └── usetesting.go
│ │ │ │ │ └── out/
│ │ │ │ │ └── usetesting.go
│ │ │ │ ├── usetesting.go
│ │ │ │ ├── usetesting_cgo.go
│ │ │ │ ├── usetesting_configuration.go
│ │ │ │ └── usetesting_configuration.yml
│ │ │ ├── usetesting.go
│ │ │ └── usetesting_integration_test.go
│ │ ├── varnamelen/
│ │ │ ├── testdata/
│ │ │ │ ├── varnamelen.go
│ │ │ │ ├── varnamelen_cgo.go
│ │ │ │ ├── varnamelen_configuration.go
│ │ │ │ └── varnamelen_configuration.yml
│ │ │ ├── varnamelen.go
│ │ │ └── varnamelen_integration_test.go
│ │ ├── wastedassign/
│ │ │ ├── testdata/
│ │ │ │ ├── wastedassign.go
│ │ │ │ └── wastedassign_cgo.go
│ │ │ ├── wastedassign.go
│ │ │ └── wastedassign_integration_test.go
│ │ ├── whitespace/
│ │ │ ├── testdata/
│ │ │ │ ├── fix/
│ │ │ │ │ ├── in/
│ │ │ │ │ │ └── whitespace.go
│ │ │ │ │ └── out/
│ │ │ │ │ └── whitespace.go
│ │ │ │ ├── whitespace-fix.yml
│ │ │ │ ├── whitespace.go
│ │ │ │ ├── whitespace.yml
│ │ │ │ └── whitespace_cgo.go
│ │ │ ├── whitespace.go
│ │ │ └── whitespace_integration_test.go
│ │ ├── wrapcheck/
│ │ │ ├── testdata/
│ │ │ │ ├── wrapcheck.go
│ │ │ │ └── wrapcheck_cgo.go
│ │ │ ├── wrapcheck.go
│ │ │ └── wrapcheck_integration_test.go
│ │ ├── wsl/
│ │ │ ├── testdata/
│ │ │ │ ├── fix/
│ │ │ │ │ ├── in/
│ │ │ │ │ │ ├── wsl_v4.go
│ │ │ │ │ │ └── wsl_v5.go
│ │ │ │ │ └── out/
│ │ │ │ │ ├── wsl_v4.go
│ │ │ │ │ └── wsl_v5.go
│ │ │ │ ├── ws_v4_cgo.go
│ │ │ │ ├── wsl_v4.go
│ │ │ │ ├── wsl_v4.yml
│ │ │ │ ├── wsl_v5.go
│ │ │ │ ├── wsl_v5_config.go
│ │ │ │ └── wsl_v5_config.yml
│ │ │ ├── wsl.go
│ │ │ ├── wsl_integration_test.go
│ │ │ └── wsl_v5.go
│ │ └── zerologlint/
│ │ ├── testdata/
│ │ │ ├── go.mod
│ │ │ ├── go.sum
│ │ │ ├── zerologlint.go
│ │ │ └── zerologlint_cgo.go
│ │ ├── zerologlint.go
│ │ └── zerologlint_integration_test.go
│ ├── goutil/
│ │ ├── env.go
│ │ ├── version.go
│ │ └── version_test.go
│ ├── lint/
│ │ ├── context.go
│ │ ├── linter/
│ │ │ ├── config.go
│ │ │ ├── context.go
│ │ │ └── linter.go
│ │ ├── lintersdb/
│ │ │ ├── builder_linter.go
│ │ │ ├── builder_plugin_go.go
│ │ │ ├── builder_plugin_module.go
│ │ │ ├── manager.go
│ │ │ ├── manager_test.go
│ │ │ ├── validator.go
│ │ │ └── validator_test.go
│ │ ├── package.go
│ │ ├── package_test.go
│ │ └── runner.go
│ ├── logutils/
│ │ ├── log.go
│ │ ├── logutils.go
│ │ ├── mock.go
│ │ ├── out.go
│ │ └── stderr_log.go
│ ├── printers/
│ │ ├── checkstyle.go
│ │ ├── checkstyle_test.go
│ │ ├── codeclimate.go
│ │ ├── codeclimate_test.go
│ │ ├── html.go
│ │ ├── html_test.go
│ │ ├── json.go
│ │ ├── json_test.go
│ │ ├── junitxml.go
│ │ ├── junitxml_test.go
│ │ ├── printer.go
│ │ ├── printer_test.go
│ │ ├── sarif.go
│ │ ├── sarif_test.go
│ │ ├── tab.go
│ │ ├── tab_test.go
│ │ ├── teamcity.go
│ │ ├── teamcity_test.go
│ │ ├── testdata/
│ │ │ ├── golden-json.json
│ │ │ ├── golden-line-number.txt
│ │ │ ├── golden-teamcity.txt
│ │ │ ├── in-issues.json
│ │ │ └── in-report-data.json
│ │ ├── text.go
│ │ └── text_test.go
│ ├── report/
│ │ ├── data.go
│ │ └── log.go
│ ├── result/
│ │ ├── issue.go
│ │ └── processors/
│ │ ├── base_rule.go
│ │ ├── cgo.go
│ │ ├── diff.go
│ │ ├── exclusion_generated_file_filter.go
│ │ ├── exclusion_generated_file_filter_test.go
│ │ ├── exclusion_generated_file_matcher.go
│ │ ├── exclusion_generated_file_matcher_test.go
│ │ ├── exclusion_paths.go
│ │ ├── exclusion_paths_test.go
│ │ ├── exclusion_presets.go
│ │ ├── exclusion_rules.go
│ │ ├── exclusion_rules_test.go
│ │ ├── filename_unadjuster.go
│ │ ├── fixer.go
│ │ ├── invalid_issue.go
│ │ ├── invalid_issue_test.go
│ │ ├── issues.go
│ │ ├── max_from_linter.go
│ │ ├── max_from_linter_test.go
│ │ ├── max_per_file_from_linter.go
│ │ ├── max_per_file_from_linter_test.go
│ │ ├── max_same_issues.go
│ │ ├── max_same_issues_test.go
│ │ ├── nolint_filter.go
│ │ ├── nolint_filter_test.go
│ │ ├── path_absoluter.go
│ │ ├── path_prettifier.go
│ │ ├── path_prettifier_test.go
│ │ ├── path_relativity.go
│ │ ├── path_shortener.go
│ │ ├── processor.go
│ │ ├── processor_test.go
│ │ ├── severity.go
│ │ ├── severity_test.go
│ │ ├── sort_results.go
│ │ ├── sort_results_test.go
│ │ ├── source_code.go
│ │ ├── testdata/
│ │ │ ├── exclusion_generated_file_filter/
│ │ │ │ ├── exclude.go
│ │ │ │ ├── exclude_block_comment.go
│ │ │ │ ├── exclude_doc.go
│ │ │ │ ├── exclude_long_line.go
│ │ │ │ ├── go_strict.go
│ │ │ │ └── go_strict_invalid.go
│ │ │ ├── exclusion_rules/
│ │ │ │ ├── case_sensitive.go
│ │ │ │ └── exclusion_rules.go
│ │ │ ├── nolint_filter/
│ │ │ │ ├── apply_to_unknown.go
│ │ │ │ ├── bad_names.go
│ │ │ │ ├── nolint.go
│ │ │ │ ├── nolint2.go
│ │ │ │ ├── unused.go
│ │ │ │ └── whole_file.go
│ │ │ └── severity/
│ │ │ ├── exclude_rules.go
│ │ │ └── severity_rules.go
│ │ ├── uniq_by_line.go
│ │ └── uniq_by_line_test.go
│ └── timeutils/
│ └── stopwatch.go
├── scripts/
│ ├── bench/
│ │ ├── bench_local.sh
│ │ ├── bench_version.sh
│ │ └── readme.md
│ ├── gen_github_action_config/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── main.go
│ │ ├── main_test.go
│ │ ├── testdata/
│ │ │ ├── all-releases-v2.json
│ │ │ ├── all-releases.json
│ │ │ ├── github-action-config-v1.json
│ │ │ ├── github-action-config-v2.json
│ │ │ └── github-action-config.json
│ │ └── types.go
│ ├── print_ast/
│ │ └── main.go
│ └── website/
│ ├── copy_jsonschema/
│ │ └── main.go
│ ├── dump_info/
│ │ ├── cmd_help.go
│ │ ├── default_exclusions.go
│ │ ├── formatters.go
│ │ ├── linters.go
│ │ ├── main.go
│ │ ├── thanks.go
│ │ └── thanks_test.go
│ ├── expand_templates/
│ │ ├── .gitignore
│ │ ├── changelog.go
│ │ ├── configuration.go
│ │ ├── configuration_test.go
│ │ ├── main.go
│ │ └── plugins.go
│ ├── github/
│ │ └── github.go
│ └── types/
│ └── types.go
├── test/
│ ├── bench/
│ │ └── bench_test.go
│ ├── configuration_file_test.go
│ ├── enabled_linters_test.go
│ ├── fix_test.go
│ ├── linters_test.go
│ ├── output_test.go
│ ├── run_test.go
│ ├── testdata/
│ │ ├── autogenerated/
│ │ │ ├── autogenerated.go
│ │ │ ├── do_not_edit.go
│ │ │ ├── go_bindata.go
│ │ │ ├── mockgen.go
│ │ │ └── protoc_gen_foo.go
│ │ ├── cgo/
│ │ │ └── main.go
│ │ ├── cgo_with_issues/
│ │ │ └── main.go
│ │ ├── configs/
│ │ │ ├── custom_linter_goplugin.yml
│ │ │ ├── custom_linter_module.yml
│ │ │ ├── custom_linter_notype.yml
│ │ │ ├── default_exclude.yml
│ │ │ ├── multiple-issues-fix.yml
│ │ │ ├── output.yml
│ │ │ └── path-except.yml
│ │ ├── default_exclude.go
│ │ ├── fix/
│ │ │ ├── in/
│ │ │ │ └── multiple-issues-fix.go
│ │ │ └── out/
│ │ │ └── multiple-issues-fix.go
│ │ ├── linedirective/
│ │ │ ├── dupl.yml
│ │ │ ├── gomodguard.yml
│ │ │ ├── hello.go
│ │ │ ├── hello.tmpl
│ │ │ └── lll.yml
│ │ ├── minimalpkg/
│ │ │ └── minimalpkg.go
│ │ ├── nogofiles/
│ │ │ └── test.txt
│ │ ├── notcompiles/
│ │ │ ├── typecheck.go
│ │ │ └── typecheck_many_issues.go
│ │ ├── output.go
│ │ ├── path_except.go
│ │ ├── path_except_test.go
│ │ ├── quicktemplate/
│ │ │ ├── hello.qtpl
│ │ │ └── hello.qtpl.go
│ │ ├── sort_results/
│ │ │ └── main.go
│ │ ├── symlink_loop/
│ │ │ └── realpkg/
│ │ │ └── p.go
│ │ ├── unsafe/
│ │ │ └── pkg.go
│ │ ├── used_only_in_tests/
│ │ │ ├── a.go
│ │ │ └── a_test.go
│ │ ├── withconfig/
│ │ │ ├── .golangci.yml
│ │ │ └── pkg/
│ │ │ └── pkg.go
│ │ ├── withtests/
│ │ │ ├── p.go
│ │ │ └── p_test.go
│ │ └── withxtest/
│ │ ├── p.go
│ │ └── p_test.go
│ ├── testdata_etc/
│ │ ├── abspath/
│ │ │ └── with_issue.go
│ │ └── unused_exported/
│ │ ├── golangci.yml
│ │ ├── lib/
│ │ │ ├── bar_test.go
│ │ │ └── foo.go
│ │ └── main.go
│ └── testshared/
│ ├── analysis.go
│ ├── analysis_test.go
│ ├── directives.go
│ ├── directives_test.go
│ ├── install.go
│ ├── integration/
│ │ ├── fix.go
│ │ └── run.go
│ ├── runner.go
│ ├── runner_test.go
│ ├── runner_unix.go
│ ├── runner_windows.go
│ └── testdata/
│ └── all.go
└── third_party/
├── dogsled/
│ └── LICENSE
├── gochecknoglobals/
│ └── LICENSE
├── gochecknoinits/
│ └── LICENSE
├── gometalinter/
│ └── LICENSE
├── lll/
│ └── LICENSE
├── nakedret/
│ └── LICENSE
└── x_tools/
└── LICENSE
================================================
FILE CONTENTS
================================================
================================================
FILE: .custom-gcl.reference.yml
================================================
# The golangci-lint version used to build the custom binary.
# Required.
version: v2.0.0
# The name of the custom binary.
# Optional.
# Default: custom-gcl
name: custom-golangci-lint
# The directory path used to store the custom binary.
# Optional.
# Default: .
destination: ./my/path/
# The list of the plugins to integrate inside the custom binary.
plugins:
# a plugin from a Go proxy
- module: 'github.com/example/plugin3'
version: v1.2.3
# a plugin from a Go proxy (with a specific import path)
- module: 'github.com/example/plugin4'
import: 'github.com/example/plugin4/foo'
version: v1.0.0
# a plugin from local source (with absolute path)
- module: 'github.com/example/plugin2'
path: /my/local/path/plugin2
# a plugin from local source (with relative path)
- module: 'github.com/example/plugin1'
path: ./my/local/path/plugin1
# a plugin from local source (with absolute path and a specific import path)
- module: 'github.com/example/plugin2'
import: 'github.com/example/plugin4/foo'
path: /my/local/path/plugin2
================================================
FILE: .gitattributes
================================================
go.sum linguist-generated
assets/* linguist-generated
* text=auto eol=lf
*.ps1 text eol=crlf
================================================
FILE: .github/CONTRIBUTING.md
================================================
See [contributing quick start](https://golangci-lint.run/docs/contributing/) on our website.
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: 🐞 Bug Report
description: "Create a report to help us improve."
labels: [bug]
body:
- type: checkboxes
id: terms
attributes:
label: Welcome
options:
- label: Yes, I'm using a binary release within 2 latest [releases](https://github.com/golangci/golangci-lint/releases). Only such installations are supported.
required: true
- label: Yes, I've searched similar [issues on GitHub](https://github.com/golangci/golangci-lint/issues) and didn't find any.
required: true
- label: Yes, I've read the `typecheck` section of the [FAQ](https://golangci-lint.run/docs/welcome/faq/#why-do-you-have-typecheck-errors).
required: true
- label: Yes, I've tried with the standalone [linter](https://golangci-lint.run/docs/linters/) if available (e.g., gocritic, go vet, etc.).
required: true
- label: I agree to follow this project's [Code of Conduct](https://github.com/golangci/golangci-lint?tab=coc-ov-file)
required: true
- type: dropdown
id: install
attributes:
label: How did you install golangci-lint?
options:
- I don't know
- Official GitHub Action
- Official binary
- Brew
- MacPorts
- Chocolatey
- Scoop
- Docker
- go install
- Tools pattern
- go tool
- AUR
- Nix
- Deb
- RPM
- Other Linux package manager
- Via editor/IDE
- asdf/mise-en-place
- Other
validations:
required: true
- type: textarea
id: problem
attributes:
label: Description of the problem
placeholder: Your problem description
validations:
required: true
- type: textarea
id: version
attributes:
label: Version of golangci-lint
value: |-
```console
$ golangci-lint --version
# Paste output here
```
validations:
required: true
- type: textarea
id: config
attributes:
label: Configuration
value: |-
```console
# paste configuration file or CLI flags here
```
validations:
required: true
- type: textarea
id: go-env
attributes:
label: Go environment
value: |-
```console
$ go version && go env
# paste output here
```
validations:
required: true
- type: textarea
id: verbose-output
attributes:
label: Verbose output of running
value: |-
```console
$ golangci-lint cache clean
$ golangci-lint run -v
# paste output here
```
validations:
required: true
- type: textarea
id: code-example
attributes:
label: A minimal reproducible example or link to a public repository
description: if your problem is related to a private repository, a minimal reproducible example is required.
value: |-
```go
// add your code here
```
validations:
required: true
- type: checkboxes
id: validation
attributes:
label: Validation
options:
- label: Yes, I've included all information above (version, config, etc.).
required: true
- type: checkboxes
id: supporter
attributes:
label: Supporter
options:
- label: I am a [sponsor/backer](https://donate.golangci.org) of this project.
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: 📖 Documentation
url: https://golangci-lint.run
about: Please take a look to our documentation.
- name: ❓ Questions
url: https://github.com/golangci/golangci-lint/discussions
about: If you have a question, or are looking for advice, please post on our Discussions forum!
- name: 💬 Chat on Slack
url: https://gophers.slack.com/archives/CS0TBRKPC
about: Maybe chatting with the community can help
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: 💡 Feature request
description: "Suggest an idea for this project."
labels: [enhancement]
body:
- type: checkboxes
id: terms
attributes:
label: Welcome
options:
- label: Yes, I've searched similar [issues on GitHub](https://github.com/golangci/golangci-lint/issues) and didn't find any.
required: true
- label: I agree to follow this project's [Code of Conduct](https://github.com/golangci/golangci-lint?tab=coc-ov-file)
required: true
- type: dropdown
id: install
attributes:
label: How did you install golangci-lint?
options:
- I don't know
- Official GitHub Action
- Official binary
- Brew
- MacPorts
- Chocolatey
- Scoop
- Docker
- go install
- Tools pattern
- go tool
- AUR
- Nix
- Deb
- RPM
- Other Linux package manager
- Via editor/IDE
- asdf/mise-en-place
- Other
validations:
required: true
- type: textarea
id: problem
attributes:
label: Your feature request related to a problem? Please describe
placeholder: "A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]"
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
placeholder: "A clear and concise description of what you want to happen."
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
placeholder: "A clear and concise description of any alternative solutions or features you've considered."
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional context
placeholder: "Add any other context or screenshots about the feature request here."
validations:
required: false
- type: checkboxes
id: supporter
attributes:
label: Supporter
options:
- label: I am a [sponsor/backer](https://donate.golangci.org) of this project.
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
================================================
FILE: .github/boring-cyborg.yml
================================================
firstPRWelcomeComment: Hey, thank you for opening your first Pull Request !
# Comment to be posted to on first time issues
firstIssueWelcomeComment: >
Hey, thank you for opening your first Issue ! 🙂
If you would like to contribute we have a [guide for contributors](https://golangci-lint.run/docs/contributing/).
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: gomod
directory: "/"
schedule:
interval: weekly
day: "sunday"
time: "11:00" # 11am UTC
ignore:
# Ignore forked linters because of their versioning issues.
- dependency-name: "github.com/golangci/dupl"
- dependency-name: "github.com/golangci/gofmt"
- dependency-name: "github.com/golangci/swaggoswag"
- dependency-name: "github.com/golangci/unconvert"
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
groups:
github-actions:
patterns:
- "*" # Group all updates into a single larger pull request.
- package-ecosystem: docker
directory: "/build"
schedule:
interval: weekly
groups:
docker:
patterns:
- "*" # Group all updates into a single larger pull request.
- package-ecosystem: gomod
directory: "/scripts/gen_github_action_config"
schedule:
interval: weekly
groups:
scripts:
patterns:
- "*" # Group all updates into a single larger pull request.
- package-ecosystem: gomod
directories:
- pkg/golinters/arangolint/testdata/
- pkg/golinters/ginkgolinter/testdata/
- pkg/golinters/loggercheck/testdata/
- pkg/golinters/protogetter/testdata/
- pkg/golinters/spancheck/testdata/
- pkg/golinters/zerologlint/testdata/
groups:
linter-testdata:
patterns:
- "*" # Group all updates into a single larger pull request.
schedule:
interval: monthly
day: "wednesday"
time: "11:00" # 11am UTC
================================================
FILE: .github/new-linter-checklist.md
================================================
In order for a pull request adding a linter to be reviewed, the linter and the PR must follow some requirements.
- [ ] The CLA must be signed
### Pull Request Description
- [ ] It must have a link to the linter repository.
- [ ] It must provide a short description of the linter.
### Linter
- [ ] It must not be a duplicate of another linter or a rule of a linter (the team will help to verify that).
- [ ] It must have a valid license (AGPL is not allowed), and the file must contain the required information by the license, ex: author, year, etc.
- [ ] It must use Go version <= 1.22.0
- [ ] The linter repository must have a CI and tests.
- [ ] It must use [`go/analysis`](https://golangci-lint.run/docs/contributing/new-linters/).
- [ ] It must have a valid tag, ex: `v1.0.0`, `v0.1.0`.
- [ ] It must not contain `init()`.
- [ ] It must not contain `panic()`.
- [ ] It must not contain `log.Fatal()`, `os.Exit()`, or similar.
- [ ] It must not modify the AST.
- [ ] It must not have false positives/negatives (the team will help to verify that).
- [ ] It must have tests inside golangci-lint.
### The Linter Tests Inside Golangci-lint
- [ ] They must have at least one std lib import.
- [ ] They must have integration tests without configuration (default).
- [ ] They must have integration tests with configuration (if the linter has a configuration).
### `.golangci.next.reference.yml`
- [ ] The file `.golangci.next.reference.yml` must be updated.
- [ ] The file `.golangci.reference.yml` must NOT be edited.
- [ ] The linter must be added to the lists of available linters (alphabetical case-insensitive order).
- `enable` and `disable` options
- [ ] If the linter has a configuration, the exhaustive configuration of the linter must be added (alphabetical case-insensitive order)
- The values must be different from the default ones.
- The default values must be defined in a comment.
- The option must have a short description.
### Others Requirements
- [ ] The files (tests and linter) inside golangci-lint must have the same name as the linter.
- [ ] The `.golangci.yml` of golangci-lint itself must not be edited and the linter must not be added to this file.
- [ ] The linters must be sorted in the alphabetical order (case-insensitive) in the `lintersdb/builder_linter.go` and `.golangci.next.reference.yml`.
- [ ] The load mode (`WithLoadMode(...)`):
- if the linter uses `goanalysis.LoadModeSyntax` -> no `WithLoadForGoAnalysis()` in `lintersdb/builder_linter.go`
- if the linter uses `goanalysis.LoadModeTypesInfo`, it requires `WithLoadForGoAnalysis()` in `lintersdb/builder_linter.go`
- [ ] The version in `WithSince(...)` must be the next minor version (`v1.X.0`) of golangci-lint.
- [ ] `WithURL()` must contain the URL of the repository.
### Recommendations
- [ ] The file `jsonschema/golangci.next.jsonschema.json` should be updated.
- [ ] The file `jsonschema/golangci.jsonschema.json` must NOT be edited.
- [ ] The linter repository should have a readme and linting.
- [ ] The linter should be published as a binary (useful to diagnose bug origins).
- [ ] The linter repository should have a `.gitignore` (IDE files, binaries, OS files, etc. should not be committed)
- [ ] A tag should never be recreated.
- [ ] Use `main` as the default branch name.
---
The golangci-lint team will edit this comment to check the boxes before and during the review.
The code review will start after the completion of those checkboxes (except for the specific items that the team will help to verify).
The reviews should be addressed as commits (no squash).
If the author of the PR is a member of the golangci-lint team, he should not edit this message.
**This checklist does not imply that we will accept the linter.**
================================================
FILE: .github/peril/.gitignore
================================================
node_modules/
================================================
FILE: .github/peril/README.md
================================================
Based on https://github.com/gatsbyjs/gatsby/tree/HEAD/peril.
## Update a code
```bash
heroku ps:restart web --app golangci-peril
heroku logs --app golangci-peril -t
```
================================================
FILE: .github/peril/package.json
================================================
{
"dependencies": {
"jest": "^29.0.3"
},
"scripts": {
"test": "jest"
},
"jest": {
"rootDir": "../",
"roots": [
"/peril"
],
"transform": {
"^.+\\.tsx?$": "/node_modules/ts-jest/preprocessor.js"
},
"moduleFileExtensions": [
"js",
"jsx",
"ts",
"tsx",
"json"
]
}
}
================================================
FILE: .github/peril/rules/invite-collaborator.ts
================================================
import { danger } from "danger";
const comment = (username: string) => `
Hey, @${username} — we just merged your PR to \`golangci-lint\`! 🔥🚀
\`golangci-lint\` is built by awesome people like you. Let us say “thanks”: **we just invited you to join the [GolangCI](https://github.com/golangci) organization on GitHub.**
This will add you to our team of maintainers. Accept the invite by visiting [this link](https://github.com/orgs/golangci/invitation).
By joining the team, you’ll be able to label issues, review pull requests, and merge approved pull requests.
More information about contributing is [here](https://golangci-lint.run/docs/contributing/).
Thanks again!
`;
const teamId = `3840765`;
export const inviteCollaborator = async () => {
const gh = danger.github;
const api = gh.api;
// Details about the repo.
const owner = gh.thisPR.owner;
const repo = gh.thisPR.repo;
const number = gh.thisPR.number;
// Details about the collaborator.
const username = gh.pr.user.login;
// Check whether or not we’ve already invited this contributor.
try {
const inviteCheck = (await api.teams.getMembership({
team_id: teamId,
username,
} as any)) as any;
const isInvited = inviteCheck.headers.status !== "404";
// If we’ve already invited them, don’t spam them with more messages.
if (isInvited) {
console.log(
`@${username} has already been invited to this org. Doing nothing.`
);
return;
}
} catch (err) {
console.info(
`Error checking membership of ${username} in team ${teamId}: ${err.stack}`
);
// If the user hasn’t been invited, the invite check throws an error.
}
try {
const invite = await api.teams.addOrUpdateMembership({
team_id: teamId,
username,
} as any);
if (invite.data.state === "active") {
console.log(
`@${username} is already a ${invite.data.role} for this team.`
);
} else {
console.log(`We’ve invited @${username} to join this team.`);
}
} catch (err) {
console.log("Something went wrong.");
console.log(err);
return;
}
// For new contributors, roll out the welcome wagon!
await api.issues.createComment({
owner,
repo,
number,
body: comment(username),
});
};
export default async () => {
await inviteCollaborator();
};
================================================
FILE: .github/peril/settings.json
================================================
{
"$schema": "https://raw.githubusercontent.com/danger/peril/HEAD/peril-settings-json.schema",
"settings": {
"ignored_repos": [],
"env_vars": ["SLACK_WEBHOOK_URL", "GITHUB_ACCESS_TOKEN"]
},
"repos": {
"golangci/golangci-lint": {
"pull_request.closed (pull_request.merged == true)": [
".github/peril/rules/invite-collaborator.ts"
]
}
}
}
================================================
FILE: .github/peril/tests/invite-collaborator.test.ts
================================================
jest.mock("danger", () => jest.fn());
import * as danger from "danger";
const dm = danger as any;
import { inviteCollaborator } from "../rules/invite-collaborator";
beforeEach(() => {
dm.danger = {
github: {
thisPR: {
owner: "gatsbyjs",
repo: "peril-gatsbyjs",
number: 1,
},
pr: {
user: {
login: "someUser",
},
},
api: {
teams: {
getMembership: () => Promise.resolve({ meta: { status: "404" } }),
addOrUpdateMembership: jest.fn(() =>
Promise.resolve({ data: { state: "pending" } })
),
},
issues: {
createComment: jest.fn(),
},
},
},
};
});
describe("a closed pull request", () => {
it("was merged and authored by a first-time contributor", async () => {
dm.danger.github.pr.merged = true;
await inviteCollaborator();
expect(dm.danger.github.api.issues.createComment).toBeCalled();
expect(dm.danger.github.api.orgs.addTeamMembership).toBeCalled();
});
it("was merged and authored by an existing collaborator", async () => {
dm.danger.github.pr.merged = true;
dm.danger.github.api.orgs.getTeamMembership = () =>
Promise.resolve({ headers: { status: "204 No Content" } });
await inviteCollaborator();
expect(dm.danger.github.api.issues.createComment).not.toBeCalled();
});
it("does not comment if invitation failed", async () => {
dm.danger.github.pr.merged = true;
dm.danger.github.api.orgs.addTeamMembership = () =>
Promise.reject({ headers: { status: "422 Unprocessable Entity" } });
await inviteCollaborator();
expect(dm.danger.github.api.issues.createComment).not.toBeCalled();
});
});
================================================
FILE: .github/peril/tsconfig.json
================================================
{
"compilerOptions": {
"esModuleInterop": false,
"target": "es5",
"module": "commonjs",
"lib": ["es2017"],
"strict": true
}
}
================================================
FILE: .github/stale.yml
================================================
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 366
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 30
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- blocked
- protected
- triaged
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
name: "CodeQL"
on:
push:
branches:
- main
pull_request:
# The branches below must be a subset of the branches above
branches:
- main
schedule:
- cron: '0 17 * * 5'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
# required for all workflows
security-events: write
strategy:
fail-fast: false
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
# TODO: Enable for javascript later
language: [ 'go']
steps:
- name: Checkout repository
uses: actions/checkout@v6
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
================================================
FILE: .github/workflows/deploy-documentation.yml
================================================
name: Deploy Documentation
on:
push:
branches:
- main
jobs:
doc:
name: Build and deploy documentation
runs-on: ubuntu-latest
env:
# https://github.com/actions/setup-go#supported-version-syntax
# ex:
# - 1.18beta1 -> 1.18.0-beta.1
# - 1.18rc1 -> 1.18.0-rc.1
GO_VERSION: '1.26'
HUGO_VERSION: 0.148.1
CGO_ENABLED: 0
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- run: go mod download
- name: Setup Hugo
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Build Documentation
run: make docs_build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
publish_dir: docs/public
force_orphan: true
github_token: ${{ secrets.GOLANGCI_LINT_TOKEN }}
================================================
FILE: .github/workflows/new-linter-checklist.yml
================================================
name: Add new linter checklist
on:
workflow_dispatch:
inputs:
pr:
description: PR number
required: true
type: number
permissions:
pull-requests: write
jobs:
add-comment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Add checklist
run: |
# Avoid adding multiple comments for the same PR.
comment_exist=$(gh pr view "$NUMBER" \
--json comments \
--jq '.comments[].author | select(.login=="github-actions") | .login' \
| wc -l)
[ "$comment_exist" -gt 0 ] && edit_last="--edit-last"
gh pr comment "$NUMBER" --body "$(cat .github/new-linter-checklist.md)" $edit_last
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ inputs.pr }}
================================================
FILE: .github/workflows/post-release.yml
================================================
name: "Post release"
on:
release:
types:
- published
env:
# https://github.com/actions/setup-go#supported-version-syntax
# ex:
# - 1.18beta1 -> 1.18.0-beta.1
# - 1.18rc1 -> 1.18.0-rc.1
GO_VERSION: '1.26'
jobs:
update-gha-assets:
name: "Update GitHub Action assets"
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GOLANGCI_LINT_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Update GitHub Action config
run: make assets/github-action-config.json
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
with:
base: main
token: ${{ secrets.GOLANGCI_LINT_TOKEN }}
branch-suffix: timestamp
title: "docs: update GitHub Action assets"
delete-branch: true
update-assets:
name: "Update documentation assets"
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GOLANGCI_LINT_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Update reference files
run: cp .golangci.next.reference.yml .golangci.reference.yml
- name: Update JSON schema files
run: cp jsonschema/golangci.next.jsonschema.json jsonschema/golangci.jsonschema.json
- name: Update information
run: make website_dump_info
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
with:
base: main
token: ${{ secrets.GOLANGCI_LINT_TOKEN }}
branch-suffix: timestamp
title: "docs: update documentation assets"
delete-branch: true
body: |
- [ ] update changelog
- [ ] add previous version JSON Schema
check-install-script:
name: Installation script (remote)
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- run: curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b "./install-golangci-lint"
================================================
FILE: .github/workflows/pr-checks.yml
================================================
name: Checks
on:
push:
branches:
- main
pull_request:
env:
# https://github.com/actions/setup-go#supported-version-syntax
# ex:
# - 1.18beta1 -> 1.18.0-beta.1
# - 1.18rc1 -> 1.18.0-rc.1
GO_VERSION: '1.26'
jobs:
# Check if there is any dirty change for go mod tidy
go-mod:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Check go mod
run: |
go mod tidy
git diff --exit-code go.mod
git diff --exit-code go.sum
# This check is disabled because of GitHub API instability: 504 Gateway Timeout.
# Checks: GitHub action assets
# check-generated:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v6
# with:
# fetch-depth: 0
# - uses: actions/setup-go@v6
# with:
# go-version: ${{ env.GO_VERSION }}
# - name: Check generated files are up-to-date
# run: make fast_check_generated
# env:
# # needed for github-action-config.json generation
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
check-local-install-script:
name: Installation script (local)
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Check installation script
run: cat ./install.sh | sh -s -- -d -b "./install-golangci-lint"
# Note: the command `run` is tested by the other workflows (`make test`).
check-commands:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Build golangci-lint
run: make build
- run: ./golangci-lint
- run: ./golangci-lint fmt
- run: ./golangci-lint fmt --diff
- run: cat cmd/golangci-lint/main.go | ./golangci-lint fmt --stdin
- run: ./golangci-lint cache
- run: ./golangci-lint cache status
- run: ./golangci-lint cache clean
- run: ./golangci-lint completion
- run: ./golangci-lint completion bash
- run: ./golangci-lint completion bash --no-descriptions
- run: ./golangci-lint completion zsh
- run: ./golangci-lint completion zsh --no-descriptions
- run: ./golangci-lint completion fish
- run: ./golangci-lint completion fish --no-descriptions
- run: ./golangci-lint completion powershell
- run: ./golangci-lint completion powershell --no-descriptions
- run: ./golangci-lint config
- run: ./golangci-lint config path
- run: ./golangci-lint config path --json
- run: ./golangci-lint config verify --schema jsonschema/golangci.next.jsonschema.json
- run: ./golangci-lint help
- run: ./golangci-lint help linters
- run: ./golangci-lint help linters --json
- run: ./golangci-lint help formatters
- run: ./golangci-lint help formatters --json
- run: ./golangci-lint linters
- run: ./golangci-lint linters --json
- run: ./golangci-lint formatters
- run: ./golangci-lint formatters --json
- run: ./golangci-lint version
- run: ./golangci-lint version --short
- run: ./golangci-lint version --debug
- run: ./golangci-lint version --json
- run: ./golangci-lint version --json --debug
================================================
FILE: .github/workflows/pr-documentation.yml
================================================
name: Check Documentation
on:
pull_request:
jobs:
doc:
name: Build documentation
runs-on: ubuntu-latest
env:
# https://github.com/actions/setup-go#supported-version-syntax
# ex:
# - 1.18beta1 -> 1.18.0-beta.1
# - 1.18rc1 -> 1.18.0-rc.1
GO_VERSION: '1.26'
HUGO_VERSION: 0.148.1
CGO_ENABLED: 0
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- run: go mod download
- name: Setup Hugo
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Build Documentation
run: make docs_build
================================================
FILE: .github/workflows/pr-tests.yml
================================================
name: Tests
on:
push:
branches:
- main
pull_request:
env:
# https://github.com/actions/setup-go#supported-version-syntax
# ex:
# - 1.18beta1 -> 1.18.0-beta.1
# - 1.18rc1 -> 1.18.0-rc.1
GO_VERSION: '1.26'
jobs:
# Check if there is any dirty change for go mod tidy
go-mod:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Check go mod
run: |
go mod tidy
git diff --exit-code go.mod
git diff --exit-code go.sum
# We already run the current golangci-lint in tests, but here we test
# our GitHub action with the latest stable golangci-lint.
golangci-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
# https://github.com/actions/setup-go#supported-version-syntax
# ex:
# - 1.18beta1 -> 1.18.0-beta.1
# - 1.18rc1 -> 1.18.0-rc.1
# TODO(ldez) must be changed after the first release of golangci-lint with go1.25
# go-version: ${{ env.GO_VERSION }}
go-version: '1.25'
- name: lint
uses: golangci/golangci-lint-action@v9.2.0
with:
version: latest
tests-on-windows:
needs: golangci-lint # run after golangci-lint action to not produce duplicated errors
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }} # test only the latest go version to speed up CI
- name: Run tests
run: make.exe test
tests-on-macos:
needs: golangci-lint # run after golangci-lint action to not produce duplicated errors
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }} # test only the latest go version to speed up CI
- name: Run tests
run: make test
tests-on-unix:
needs: golangci-lint # run after golangci-lint action to not produce duplicated errors
strategy:
matrix:
os:
- ubuntu-latest
- ubuntu-24.04-arm
golang:
- '1.25'
- '1.26'
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: ${{ matrix.golang }}
- name: Run tests
run: make test
================================================
FILE: .github/workflows/release.yml
================================================
name: "Release a tag"
on:
push:
tags:
- v*
permissions:
# Allow the workflow to write attestations.
id-token: write
attestations: write
jobs:
release:
runs-on: ubuntu-latest
env:
# https://github.com/actions/setup-go#supported-version-syntax
# ex:
# - 1.18beta1 -> 1.18.0-beta.1
# - 1.18rc1 -> 1.18.0-rc.1
GO_VERSION: '1.26'
CHOCOLATEY_VERSION: 2.2.0
steps:
# temporary workaround for an error in free disk space action
# https://github.com/jlumbroso/free-disk-space/issues/14
- name: Update Package List and Remove Dotnet
run: |
sudo apt-get update
sudo apt-get remove -y '^dotnet-.*'
# https://github.com/marketplace/actions/free-disk-space-ubuntu
- name: Free Disk Space
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed
tool-cache: false
# all of these default to true
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: false
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
# - name: Install chocolatey
# run: |
# mono --version
# mkdir -p /opt/chocolatey
# wget -q -O - "https://github.com/chocolatey/choco/releases/download/${CHOCOLATEY_VERSION}/chocolatey.v${CHOCOLATEY_VERSION}.tar.gz" | tar -xz -C "/opt/chocolatey"
# echo '#!/bin/bash' >> /usr/local/bin/choco
# echo 'mono /opt/chocolatey/choco.exe $@' >> /usr/local/bin/choco
# chmod +x /usr/local/bin/choco
# choco --version
- name: Install snapcraft
run: sudo snap install snapcraft --classic
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login do docker.io
run: docker login -u golangci -p ${{ secrets.GOLANGCI_LINT_DOCKER_TOKEN }}
- name: Create release
id: goreleaser
uses: goreleaser/goreleaser-action@v7
with:
version: latest
args: release --clean --timeout=90m
env:
AUR_KEY: ${{ secrets.AUR_KEY }}
CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
GITHUB_TOKEN: ${{ secrets.GOLANGCI_LINT_TOKEN }}
- uses: actions/attest@v4
with:
subject-checksums: ./dist/golangci-lint-${{ fromJSON(steps.goreleaser.outputs.metadata).version }}-checksums.txt
github-token: ${{ secrets.GOLANGCI_LINT_TOKEN }}
- uses: actions/attest@v4
with:
subject-checksums: ./dist/digests.txt
github-token: ${{ secrets.GOLANGCI_LINT_TOKEN }}
================================================
FILE: .gitignore
================================================
*.test
.DS_Store
/*.pdf
/*.pprof
/*.txt
/test.lock
/.idea/
/.vscode/
/dist/
/golangci-lint
/golangci-lint.exe
/test/path
/tools/Dracula.itermcolors
/tools/dist/
/tools/godownloader
/tools/goreleaser
/tools/node_modules
/tools/svg-term
/vendor/
coverage.out
coverage.xml
/custom-golangci-lint
/custom-gcl
.custom-gcl.yml
.custom-gcl.yaml
**/testdata/fix.tmp/
================================================
FILE: .golangci.next.reference.yml
================================================
# This file contains all available configuration options
# with their default values (in comments).
#
# This file is not a configuration example,
# it contains the exhaustive configuration with explanations of the options.
# Defines the configuration version.
# The only possible value is "2".
version: "2"
linters:
# Default set of linters.
# The value can be:
# - `standard`: https://golangci-lint.run/docs/linters/#enabled-by-default
# - `all`: enables all linters by default.
# - `none`: disables all linters by default.
# - `fast`: enables only linters considered as "fast" (`golangci-lint help linters --json | jq '[ .[] | select(.fast==true) ] | map(.name)'`).
# Default: standard
default: all
# Enable specific linter.
enable:
- arangolint
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- embeddedstructfieldcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funcorder
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godoclint
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- iotamixing
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- modernize
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- noinlineerr
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unqueryvet
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- wsl_v5
- zerologlint
# Disable specific linters.
disable:
- arangolint
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- embeddedstructfieldcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funcorder
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godoclint
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- iotamixing
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- modernize
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- noinlineerr
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unqueryvet
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- wsl_v5
- zerologlint
# All available settings of specific linters.
settings:
asasalint:
# To specify a set of function names to exclude.
# The values are merged with the builtin exclusions.
# The builtin exclusions can be disabled by setting `use-builtin-exclusions` to `false`.
# Default: ["^(fmt|log|logger|t|)\.(Print|Fprint|Sprint|Fatal|Panic|Error|Warn|Warning|Info|Debug|Log)(|f|ln)$"]
exclude:
- Append
- \.Wrapf
# To enable/disable the asasalint builtin exclusions of function names.
# See the default value of `exclude` to get the builtin exclusions.
# Default: true
use-builtin-exclusions: false
bidichk:
# The following configurations check for all mentioned invisible Unicode runes.
# All runes are enabled by default.
left-to-right-embedding: false
right-to-left-embedding: false
pop-directional-formatting: false
left-to-right-override: false
right-to-left-override: false
left-to-right-isolate: false
right-to-left-isolate: false
first-strong-isolate: false
pop-directional-isolate: false
copyloopvar:
# Check all assigning the loop variable to another variable.
# Default: false
check-alias: true
cyclop:
# The maximal code complexity to report.
# Default: 10
max-complexity: 10
# The maximal average package complexity.
# If it's higher than 0.0 (float) the check is enabled.
# Default: 0.0
package-average: 0.5
decorder:
# Required order of `type`, `const`, `var` and `func` declarations inside a file.
# Default: types before constants before variables before functions.
dec-order:
- type
- const
- var
- func
# If true, underscore vars (vars with "_" as the name) will be ignored at all checks.
# Default: false (underscore vars are not ignored)
ignore-underscore-vars: false
# If true, order of declarations is not checked at all.
# Default: true (disabled)
disable-dec-order-check: false
# If true, `init` func can be anywhere in file (does not have to be declared before all other functions).
# Default: true (disabled)
disable-init-func-first-check: false
# If true, multiple global `type`, `const` and `var` declarations are allowed.
# Default: true (disabled)
disable-dec-num-check: false
# If true, type declarations will be ignored for dec num check.
# Default: false (type statements are not ignored)
disable-type-dec-num-check: false
# If true, const declarations will be ignored for dec num check.
# Default: false (const statements are not ignored)
disable-const-dec-num-check: false
# If true, var declarations will be ignored for dec num check.
# Default: false (var statements are not ignored)
disable-var-dec-num-check: false
depguard:
# Rules to apply.
#
# Variables:
# - File Variables
# Use an exclamation mark `!` to negate a variable.
# Example: `!$test` matches any file that is not a go test file.
#
# `$all` - matches all go files
# `$test` - matches all go test files
#
# - Package Variables
#
# `$gostd` - matches all of go's standard library (Pulled from `GOROOT`)
#
# Default (applies if no custom rules are defined): Only allow $gostd in all files.
rules:
# Name of a rule.
main:
# Defines package matching behavior. Available modes:
# - `original`: allowed if it doesn't match the deny list and either matches the allow list or the allow list is empty.
# - `strict`: allowed only if it matches the allow list and either doesn't match the deny list or the allow rule is more specific (longer) than the deny rule.
# - `lax`: allowed if it doesn't match the deny list or the allow rule is more specific (longer) than the deny rule.
# Default: "original"
list-mode: lax
# List of file globs that will match this list of settings to compare against.
# By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed.
# The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`.
# The placeholder '${config-path}' is substituted with a path relative to the configuration file.
# Default: $all
files:
- "!**/*_a _file.go"
# List of allowed packages.
# Entries can be a variable (starting with $), a string prefix, or an exact match (if ending with $).
# Default: []
allow:
- $gostd
- github.com/OpenPeeDeeP
# List of packages that are not allowed.
# Entries can be a variable (starting with $), a string prefix, or an exact match (if ending with $).
# Default: []
deny:
- pkg: "math/rand$"
desc: use math/rand/v2
- pkg: "github.com/sirupsen/logrus"
desc: not allowed
- pkg: "github.com/pkg/errors"
desc: Should be replaced by standard lib errors package
dogsled:
# Checks assignments with too many blank identifiers.
# Default: 2
max-blank-identifiers: 3
dupl:
# Tokens count to trigger issue.
# Default: 150
threshold: 100
dupword:
# Keywords for detecting duplicate words.
# If this list is not empty, only the words defined in this list will be detected.
# Default: []
keywords:
- "the"
- "and"
- "a"
# Keywords used to ignore detection.
# Default: []
ignore:
- "0C0C"
# Checks only comments, skip strings.
# Default: false
comments-only: true
embeddedstructfieldcheck:
# Checks that there is an empty space between the embedded fields and regular fields.
# Default: true
empty-line: false
# Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.
# Default: false
forbid-mutex: true
errcheck:
# Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
# Such cases aren't reported by default.
# Default: false
check-type-assertions: true
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`.
# Such cases aren't reported by default.
# Default: false
check-blank: true
# To disable the errcheck built-in exclude list.
# See `-excludeonly` option in https://github.com/kisielk/errcheck#excluding-functions for details.
# Default: false
disable-default-exclusions: true
# List of functions to exclude from checking, where each entry is a single function to exclude.
# See https://github.com/kisielk/errcheck#excluding-functions for details.
exclude-functions:
- io/ioutil.ReadFile
- io.Copy(*bytes.Buffer)
- io.Copy(os.Stdout)
# Display function signature instead of selector.
# Default: false
verbose: true
errchkjson:
# With check-error-free-encoding set to true, errchkjson does warn about errors
# from json encoding functions that are safe to be ignored,
# because they are not possible to happen.
#
# if check-error-free-encoding is set to true and errcheck linter is enabled,
# it is recommended to add the following exceptions to prevent from false positives:
#
# linters:
# settings:
# errcheck:
# exclude-functions:
# - encoding/json.Marshal
# - encoding/json.MarshalIndent
#
# Default: false
check-error-free-encoding: true
# Issue on struct encoding that doesn't have exported fields.
# Default: false
report-no-exported: false
errorlint:
# Check whether fmt.Errorf uses the %w verb for formatting errors.
# See the https://github.com/polyfloyd/go-errorlint for caveats.
# Default: true
errorf: false
# Permit more than 1 %w verb, valid per Go 1.20 (requires `errorf: true`).
# Default: true
errorf-multi: false
# Check for plain type assertions and type switches.
# Default: true
asserts: false
# Check for plain error comparisons.
# Default: true
comparison: false
# Allowed errors.
# Default: []
allowed-errors:
- err: "io.EOF"
fun: "example.com/pkg.Read"
# Allowed error "wildcards".
# Default: []
allowed-errors-wildcard:
- err: "example.com/pkg.ErrMagic"
fun: "example.com/pkg.Magic"
exhaustive:
# Program elements to check for exhaustiveness.
# Default: [ switch ]
check:
- switch
- map
# Presence of "default" case in switch statements satisfies exhaustiveness,
# even if all enum members are not listed.
# Default: false
default-signifies-exhaustive: true
# Enum members matching the supplied regex do not have to be listed in
# switch statements to satisfy exhaustiveness.
# Default: ""
ignore-enum-members: "Example.+"
# Enum types matching the supplied regex do not have to be listed in
# switch statements to satisfy exhaustiveness.
# Default: ""
ignore-enum-types: "Example.+"
# Consider enums only in package scopes, not in inner scopes.
# Default: false
package-scope-only: true
# Only run exhaustive check on switches with "//exhaustive:enforce" comment.
# Default: false
explicit-exhaustive-switch: true
# Only run exhaustive check on map literals with "//exhaustive:enforce" comment.
# Default: false
explicit-exhaustive-map: true
# Switch statement requires default case even if exhaustive.
# Default: false
default-case-required: true
exhaustruct:
# List of regular expressions to match type names that should be processed.
# Anonymous structs can be matched by '' alias.
#
# Each regular expression must match the full type name, including package path.
# For example, to match type `net/http.Cookie` regular expression should be `.*/http\.Cookie`,
# but not `http\.Cookie`.
# Default: []
include:
- '.+\.Test'
- 'example\.com/package\.ExampleStruct[\d]{1,2}'
# List of regular expressions to match type names that should be excluded from processing.
# Anonymous structs can be matched by '' alias.
# Has precedence over `include`.
# Each regular expression must match the full type name, including package path.
# For example, to match type `net/http.Cookie` regular expression should be `.*/http\.Cookie`,
# but not `http\.Cookie`.
# Default: []
exclude:
- '.+/cobra\.Command$'
# Allows empty structures, effectively excluding them from the check.
# Default: false
allow-empty: true
# List of regular expressions to match type names that should be allowed to be empty.
# Anonymous structs can be matched by '' alias.
# Each regular expression must match the full type name, including package path.
# For example, to match type `net/http.Cookie` regular expression should be `.*/http\.Cookie`,
# but not `http\.Cookie`.
# Default: []
allow-empty-rx:
- '.*/http\.Cookie'
# Allows empty structures in return statements.
# Default: false
allow-empty-returns: true
# Allows empty structures in variable declarations.
# Default: false
allow-empty-declarations: true
fatcontext:
# Check for potential fat contexts in struct pointers.
# May generate false positives.
# Default: false
check-struct-pointers: true
forbidigo:
# Forbid the following identifiers (list of regexp).
# Default: ["^(fmt\\.Print(|f|ln)|print|println)$"]
forbid:
# Built-in bootstrapping functions.
- pattern: ^print(ln)?$
# Optional message that gets included in error reports.
- pattern: ^fmt\.Print.*$
msg: Do not commit print statements.
# Alternatively, put messages at the end of the regex, surrounded by `(# )?`.
# Escape any special characters. Those messages get included in error reports.
- pattern: 'fmt\.Print.*(# Do not commit print statements\.)?'
# Forbid spew Dump, whether it is called as function or method.
# Depends on analyze-types below.
- pattern: ^spew\.(ConfigState\.)?Dump$
# The package name might be ambiguous.
# The full import path can be used as additional criteria.
# Depends on analyze-types below.
- pattern: ^v1.Dump$
pkg: ^example.com/pkg/api/v1$
# Exclude godoc examples from forbidigo checks.
# Default: true
exclude-godoc-examples: false
# Instead of matching the literal source code,
# use type information to replace expressions with strings that contain the package name
# and (for methods and fields) the type name.
# This makes it possible to handle import renaming and forbid struct fields and methods.
# Default: false
analyze-types: true
funcorder:
# Checks that constructors are placed after the structure declaration.
# Default: true
constructor: false
# Checks if the exported methods of a structure are placed before the non-exported ones.
# Default: true
struct-method: false
# Checks if the constructors and/or structure methods are sorted alphabetically.
# Default: false
alphabetical: true
funlen:
# Checks the number of lines in a function.
# If lower than 0, disable the check.
# Default: 60
lines: -1
# Checks the number of statements in a function.
# If lower than 0, disable the check.
# Default: 40
statements: -1
# Ignore comments when counting lines.
# Default: true
ignore-comments: false
ginkgolinter:
# Suppress the wrong length assertion warning.
# Default: false
suppress-len-assertion: true
# Suppress the wrong nil assertion warning.
# Default: false
suppress-nil-assertion: true
# Suppress the wrong error assertion warning.
# Default: false
suppress-err-assertion: true
# Suppress the wrong comparison assertion warning.
# Default: false
suppress-compare-assertion: true
# Suppress the function all in async assertion warning.
# Default: false
suppress-async-assertion: true
# Suppress warning for comparing values from different types, like `int32` and `uint32`.
# Default: false
suppress-type-compare-assertion: true
# Trigger warning for ginkgo focus containers like `FDescribe`, `FContext`, `FWhen` or `FIt`.
# Default: false
forbid-focus-container: true
# Don't trigger warnings for HaveLen(0)
# Default: false
allow-havelen-zero: true
# Force using `Expect` with `To`, `ToNot` or `NotTo`.
# Reject using `Expect` with `Should` or `ShouldNot`.
# Default: false
force-expect-to: true
# Best effort validation of async intervals (timeout and polling).
# Ignored the `suppress-async-assertion` is true.
# Default: false
validate-async-intervals: true
# Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.
# Default: false
forbid-spec-pollution: true
# Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.
# Default: false
force-succeed: true
# Force adding assertion descriptions to gomega matchers.
# Default: false
force-assertion-description: true
# Force using `ToNot`, `ShouldNot` instead of `To(Not())`.
# Default: false
force-tonot: true
gochecksumtype:
# Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.
# Default: true
default-signifies-exhaustive: false
# Include shared interfaces in the exhaustiveness check.
# Default: false
include-shared-interfaces: true
gocognit:
# Minimal code complexity to report.
# Default: 30 (but we recommend 10-20)
min-complexity: 10
goconst:
# Minimal length of string constant.
# Default: 3
min-len: 2
# Minimum occurrences of constant string count to trigger issue.
# Default: 3
min-occurrences: 2
# Look for existing constants matching the values.
# Default: true
match-constant: false
# Search also for duplicated numbers.
# Default: false
numbers: true
# Minimum value, only works with `goconst.numbers`.
# Default: 3
min: 2
# Maximum value, only works with `goconst.numbers`.
# Default: 3
max: 2
# Ignore when constant is not used as function argument.
# Default: true
ignore-calls: false
# Exclude strings matching the given regular expression.
# Default: ""
ignore-string-values:
- 'foo.+'
# Detects constants with identical values.
# Default: false
find-duplicates: true
# Evaluates of constant expressions like Prefix + "suffix".
# Default: false
eval-const-expressions: true
gocritic:
# Disable all checks.
# Default: false
disable-all: true
# Which checks should be enabled in addition to default checks; can't be combined with 'disabled-checks'.
# By default, list of stable checks is used (https://go-critic.com/overview#checks-overview):
# appendAssign, argOrder, assignOp, badCall, badCond, captLocal, caseOrder, codegenComment, commentFormatting,
# defaultCaseOrder, deprecatedComment, dupArg, dupBranchBody, dupCase, dupSubExpr, elseif, exitAfterDefer,
# flagDeref, flagName, ifElseChain, mapKey, newDeref, offBy1, regexpMust, singleCaseSwitch, sloppyLen,
# sloppyTypeAssert, switchTrue, typeSwitchVar, underef, unlambda, unslice, valSwap, wrapperFunc
# To see which checks are enabled run `GL_DEBUG=gocritic golangci-lint run --enable=gocritic`.
enabled-checks:
# Detects suspicious append result assignments.
# https://go-critic.com/overview.html#appendassign
- appendAssign
# Detects `append` chains to the same slice that can be done in a single `append` call.
# https://go-critic.com/overview.html#appendcombine
- appendCombine
# Detects suspicious arguments order.
# https://go-critic.com/overview.html#argorder
- argOrder
# Detects assignments that can be simplified by using assignment operators.
# https://go-critic.com/overview.html#assignop
- assignOp
# Detects suspicious function calls.
# https://go-critic.com/overview.html#badcall
- badCall
# Detects suspicious condition expressions.
# https://go-critic.com/overview.html#badcond
- badCond
# Detects suspicious mutex lock/unlock operations.
# https://go-critic.com/overview.html#badlock
- badLock
# Detects suspicious regexp patterns.
# https://go-critic.com/overview.html#badregexp
- badRegexp
# Detects bad usage of sort package.
# https://go-critic.com/overview.html#badsorting
- badSorting
# Detects bad usage of sync.OnceFunc.
# https://go-critic.com/overview.html#badsynconcefunc
- badSyncOnceFunc
# Detects bool expressions that can be simplified.
# https://go-critic.com/overview.html#boolexprsimplify
- boolExprSimplify
# Detects when predeclared identifiers are shadowed in assignments.
# https://go-critic.com/overview.html#builtinshadow
- builtinShadow
# Detects top-level declarations that shadow the predeclared identifiers.
# https://go-critic.com/overview.html#builtinshadowdecl
- builtinShadowDecl
# Detects capitalized names for local variables.
# https://go-critic.com/overview.html#captlocal
- captLocal
# Detects erroneous case order inside switch statements.
# https://go-critic.com/overview.html#caseorder
- caseOrder
# Detects malformed 'code generated' file comments.
# https://go-critic.com/overview.html#codegencomment
- codegenComment
# Detects comments with non-idiomatic formatting.
# https://go-critic.com/overview.html#commentformatting
- commentFormatting
# Detects commented-out code inside function bodies.
# https://go-critic.com/overview.html#commentedoutcode
- commentedOutCode
# Detects commented-out imports.
# https://go-critic.com/overview.html#commentedoutimport
- commentedOutImport
# Detects when default case in switch isn't on 1st or last position.
# https://go-critic.com/overview.html#defaultcaseorder
- defaultCaseOrder
# Detects loops inside functions that use defer.
# https://go-critic.com/overview.html#deferinloop
- deferInLoop
# Detects deferred function literals that can be simplified.
# https://go-critic.com/overview.html#deferunlambda
- deferUnlambda
# Detects malformed 'deprecated' doc-comments.
# https://go-critic.com/overview.html#deprecatedcomment
- deprecatedComment
# Detects comments that silence go lint complaints about doc-comment.
# https://go-critic.com/overview.html#docstub
- docStub
# Detects suspicious duplicated arguments.
# https://go-critic.com/overview.html#duparg
- dupArg
# Detects duplicated branch bodies inside conditional statements.
# https://go-critic.com/overview.html#dupbranchbody
- dupBranchBody
# Detects duplicated case clauses inside switch or select statements.
# https://go-critic.com/overview.html#dupcase
- dupCase
# Detects multiple imports of the same package under different aliases.
# https://go-critic.com/overview.html#dupimport
- dupImport
# Detects duplicated option function arguments in variadic function calls.
# https://go-critic.com/overview.html#dupoption
- dupOption
# Detects suspicious duplicated sub-expressions.
# https://go-critic.com/overview.html#dupsubexpr
- dupSubExpr
# Detects suspicious formatting strings usage.
# https://go-critic.com/overview.html#dynamicfmtstring
- dynamicFmtString
# Detects else with nested if statement that can be replaced with else-if.
# https://go-critic.com/overview.html#elseif
- elseif
# Detects suspicious empty declarations blocks.
# https://go-critic.com/overview.html#emptydecl
- emptyDecl
# Detects fallthrough that can be avoided by using multi case values.
# https://go-critic.com/overview.html#emptyfallthrough
- emptyFallthrough
# Detects empty string checks that can be written more idiomatically.
# https://go-critic.com/overview.html#emptystringtest
- emptyStringTest
# Detects unoptimal strings/bytes case-insensitive comparison.
# https://go-critic.com/overview.html#equalfold
- equalFold
# Detects unwanted dependencies on the evaluation order.
# https://go-critic.com/overview.html#evalorder
- evalOrder
# Detects calls to exit/fatal inside functions that use defer.
# https://go-critic.com/overview.html#exitafterdefer
- exitAfterDefer
# Detects exposed methods from sync.Mutex and sync.RWMutex.
# https://go-critic.com/overview.html#exposedsyncmutex
- exposedSyncMutex
# Detects suspicious reassignment of error from another package.
# https://go-critic.com/overview.html#externalerrorreassign
- externalErrorReassign
# Detects problems in filepath.Join() function calls.
# https://go-critic.com/overview.html#filepathjoin
- filepathJoin
# Detects immediate dereferencing of `flag` package pointers.
# https://go-critic.com/overview.html#flagderef
- flagDeref
# Detects suspicious flag names.
# https://go-critic.com/overview.html#flagname
- flagName
# Detects hex literals that have mixed case letter digits.
# https://go-critic.com/overview.html#hexliteral
- hexLiteral
# Detects nil usages in http.NewRequest calls, suggesting http.NoBody as an alternative.
# https://go-critic.com/overview.html#httpnobody
- httpNoBody
# Detects params that incur excessive amount of copying.
# https://go-critic.com/overview.html#hugeparam
- hugeParam
# Detects repeated if-else statements and suggests to replace them with switch statement.
# https://go-critic.com/overview.html#ifelsechain
- ifElseChain
# Detects when imported package names shadowed in the assignments.
# https://go-critic.com/overview.html#importshadow
- importShadow
# Detects strings.Index calls that may cause unwanted allocs.
# https://go-critic.com/overview.html#indexalloc
- indexAlloc
# Detects non-assignment statements inside if/switch init clause.
# https://go-critic.com/overview.html#initclause
- initClause
# Detects suspicious map literal keys.
# https://go-critic.com/overview.html#mapkey
- mapKey
# Detects method expression call that can be replaced with a method call.
# https://go-critic.com/overview.html#methodexprcall
- methodExprCall
# Finds where nesting level could be reduced.
# https://go-critic.com/overview.html#nestingreduce
- nestingReduce
# Detects immediate dereferencing of `new` expressions.
# https://go-critic.com/overview.html#newderef
- newDeref
# Detects return statements those results evaluate to nil.
# https://go-critic.com/overview.html#nilvalreturn
- nilValReturn
# Detects old-style octal literals.
# https://go-critic.com/overview.html#octalliteral
- octalLiteral
# Detects various off-by-one kind of errors.
# https://go-critic.com/overview.html#offby1
- offBy1
# Detects if function parameters could be combined by type and suggest the way to do it.
# https://go-critic.com/overview.html#paramtypecombine
- paramTypeCombine
# Detects expressions like []rune(s)[0] that may cause unwanted rune slice allocation.
# https://go-critic.com/overview.html#preferdecoderune
- preferDecodeRune
# Detects concatenation with os.PathSeparator which can be replaced with filepath.Join.
# https://go-critic.com/overview.html#preferfilepathjoin
- preferFilepathJoin
# Detects fmt.Sprint(f/ln) calls which can be replaced with fmt.Fprint(f/ln).
# https://go-critic.com/overview.html#preferfprint
- preferFprint
# Detects w.Write or io.WriteString calls which can be replaced with w.WriteString.
# https://go-critic.com/overview.html#preferstringwriter
- preferStringWriter
# Detects WriteRune calls with rune literal argument that is single byte and reports to use WriteByte instead.
# https://go-critic.com/overview.html#preferwritebyte
- preferWriteByte
# Detects input and output parameters that have a type of pointer to referential type.
# https://go-critic.com/overview.html#ptrtorefparam
- ptrToRefParam
# Detects append all its data while range it.
# https://go-critic.com/overview.html#rangeappendall
- rangeAppendAll
# Detects expensive copies of `for` loop range expressions.
# https://go-critic.com/overview.html#rangeexprcopy
- rangeExprCopy
# Detects loops that copy big objects during each iteration.
# https://go-critic.com/overview.html#rangevalcopy
- rangeValCopy
# Detects redundant fmt.Sprint calls.
# https://go-critic.com/overview.html#redundantsprint
- redundantSprint
# Detects `regexp.Compile*` that can be replaced with `regexp.MustCompile*`.
# https://go-critic.com/overview.html#regexpmust
- regexpMust
# Detects suspicious regexp patterns.
# https://go-critic.com/overview.html#regexppattern
- regexpPattern
# Detects regexp patterns that can be simplified.
# https://go-critic.com/overview.html#regexpsimplify
- regexpSimplify
# Detects suspicious http.Error call without following return.
# https://go-critic.com/overview.html#returnafterhttperror
- returnAfterHttpError
# Runs user-defined rules using ruleguard linter.
# https://go-critic.com/overview.html#ruleguard
- ruleguard
# Detects switch statements that could be better written as if statement.
# https://go-critic.com/overview.html#singlecaseswitch
- singleCaseSwitch
# Detects slice clear loops, suggests an idiom that is recognized by the Go compiler.
# https://go-critic.com/overview.html#sliceclear
- sliceClear
# Detects usage of `len` when result is obvious or doesn't make sense.
# https://go-critic.com/overview.html#sloppylen
- sloppyLen
# Detects suspicious/confusing re-assignments.
# https://go-critic.com/overview.html#sloppyreassign
- sloppyReassign
# Detects redundant type assertions.
# https://go-critic.com/overview.html#sloppytypeassert
- sloppyTypeAssert
# Detects suspicious sort.Slice calls.
# https://go-critic.com/overview.html#sortslice
- sortSlice
# Detects "%s" formatting directives that can be replaced with %q.
# https://go-critic.com/overview.html#sprintfquotedstring
- sprintfQuotedString
# Detects issue in Query() and Exec() calls.
# https://go-critic.com/overview.html#sqlquery
- sqlQuery
# Detects string concat operations that can be simplified.
# https://go-critic.com/overview.html#stringconcatsimplify
- stringConcatSimplify
# Detects redundant conversions between string and []byte.
# https://go-critic.com/overview.html#stringxbytes
- stringXbytes
# Detects strings.Compare usage.
# https://go-critic.com/overview.html#stringscompare
- stringsCompare
# Detects switch-over-bool statements that use explicit `true` tag value.
# https://go-critic.com/overview.html#switchtrue
- switchTrue
# Detects sync.Map load+delete operations that can be replaced with LoadAndDelete.
# https://go-critic.com/overview.html#syncmaploadanddelete
- syncMapLoadAndDelete
# Detects manual conversion to milli- or microseconds.
# https://go-critic.com/overview.html#timeexprsimplify
- timeExprSimplify
# Detects TODO comments without detail/assignee.
# https://go-critic.com/overview.html#todocommentwithoutdetail
- todoCommentWithoutDetail
# Detects function with too many results.
# https://go-critic.com/overview.html#toomanyresultschecker
- tooManyResultsChecker
# Detects potential truncation issues when comparing ints of different sizes.
# https://go-critic.com/overview.html#truncatecmp
- truncateCmp
# Detects repeated type assertions and suggests to replace them with type switch statement.
# https://go-critic.com/overview.html#typeassertchain
- typeAssertChain
# Detects method declarations preceding the type definition itself.
# https://go-critic.com/overview.html#typedeffirst
- typeDefFirst
# Detects type switches that can benefit from type guard clause with variable.
# https://go-critic.com/overview.html#typeswitchvar
- typeSwitchVar
# Detects unneeded parenthesis inside type expressions and suggests to remove them.
# https://go-critic.com/overview.html#typeunparen
- typeUnparen
# Detects unchecked errors in if statements.
# https://go-critic.com/overview.html#uncheckedinlineerr
- uncheckedInlineErr
# Detects dereference expressions that can be omitted.
# https://go-critic.com/overview.html#underef
- underef
# Detects redundant statement labels.
# https://go-critic.com/overview.html#unlabelstmt
- unlabelStmt
# Detects function literals that can be simplified.
# https://go-critic.com/overview.html#unlambda
- unlambda
# Detects unnamed results that may benefit from names.
# https://go-critic.com/overview.html#unnamedresult
- unnamedResult
# Detects unnecessary braced statement blocks.
# https://go-critic.com/overview.html#unnecessaryblock
- unnecessaryBlock
# Detects redundantly deferred calls.
# https://go-critic.com/overview.html#unnecessarydefer
- unnecessaryDefer
# Detects slice expressions that can be simplified to sliced expression itself.
# https://go-critic.com/overview.html#unslice
- unslice
# Detects value swapping code that are not using parallel assignment.
# https://go-critic.com/overview.html#valswap
- valSwap
# Detects conditions that are unsafe due to not being exhaustive.
# https://go-critic.com/overview.html#weakcond
- weakCond
# Ensures that `//nolint` comments include an explanation.
# https://go-critic.com/overview.html#whynolint
- whyNoLint
# Detects function calls that can be replaced with convenience wrappers.
# https://go-critic.com/overview.html#wrapperfunc
- wrapperFunc
# Detects Yoda style expressions and suggests to replace them.
# https://go-critic.com/overview.html#yodastyleexpr
- yodaStyleExpr
# Detects bytes.Repeat with 0 value.
# https://go-critic.com/overview.html#zerobyterepeat
- zeroByteRepeat
# Enable all checks.
# Default: false
enable-all: true
# Which checks should be disabled; can't be combined with 'enabled-checks'.
# Default: []
disabled-checks:
- appendAssign
- appendCombine
- argOrder
- assignOp
- badCall
- badCond
- badLock
- badRegexp
- badSorting
- badSyncOnceFunc
- boolExprSimplify
- builtinShadow
- builtinShadowDecl
- captLocal
- caseOrder
- codegenComment
- commentFormatting
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deferInLoop
- deferUnlambda
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupImport
- dupSubExpr
- dynamicFmtString
- elseif
- emptyDecl
- emptyFallthrough
- emptyStringTest
- equalFold
- evalOrder
- exitAfterDefer
- exposedSyncMutex
- externalErrorReassign
- filepathJoin
- flagDeref
- flagName
- hexLiteral
- httpNoBody
- hugeParam
- ifElseChain
- importShadow
- indexAlloc
- initClause
- mapKey
- methodExprCall
- nestingReduce
- newDeref
- nilValReturn
- octalLiteral
- offBy1
- paramTypeCombine
- preferDecodeRune
- preferFilepathJoin
- preferFprint
- preferStringWriter
- preferWriteByte
- ptrToRefParam
- rangeAppendAll
- rangeExprCopy
- rangeValCopy
- redundantSprint
- regexpMust
- regexpPattern
- regexpSimplify
- returnAfterHttpError
- ruleguard
- singleCaseSwitch
- sliceClear
- sloppyLen
- sloppyReassign
- sloppyTypeAssert
- sortSlice
- sprintfQuotedString
- sqlQuery
- stringConcatSimplify
- stringXbytes
- stringsCompare
- switchTrue
- syncMapLoadAndDelete
- timeExprSimplify
- todoCommentWithoutDetail
- tooManyResultsChecker
- truncateCmp
- typeAssertChain
- typeDefFirst
- typeSwitchVar
- typeUnparen
- uncheckedInlineErr
- underef
- unlabelStmt
- unlambda
- unnamedResult
- unnecessaryBlock
- unnecessaryDefer
- unslice
- valSwap
- weakCond
- whyNoLint
- wrapperFunc
- yodaStyleExpr
# Enable multiple checks by tags in addition to default checks.
# Run `GL_DEBUG=gocritic golangci-lint run --enable=gocritic` to see all tags and checks.
# See https://github.com/go-critic/go-critic#usage -> section "Tags".
# Default: []
enabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
disabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
# Settings passed to gocritic.
# The settings key is the name of a supported gocritic checker.
# The list of supported checkers can be found at https://go-critic.com/overview.
settings:
# Must be valid enabled check name.
captLocal:
# Whether to restrict checker to params only.
# Default: true
paramsOnly: false
commentedOutCode:
# Min length of the comment that triggers a warning.
# Default: 15
minLength: 50
elseif:
# Whether to skip balanced if-else pairs.
# Default: true
skipBalanced: false
hugeParam:
# Size in bytes that makes the warning trigger.
# Default: 80
sizeThreshold: 70
ifElseChain:
# Min number of if-else blocks that makes the warning trigger.
# Default: 2
minThreshold: 4
nestingReduce:
# Min number of statements inside a branch to trigger a warning.
# Default: 5
bodyWidth: 4
rangeExprCopy:
# Size in bytes that makes the warning trigger.
# Default: 512
sizeThreshold: 516
# Whether to check test functions
# Default: true
skipTestFuncs: false
rangeValCopy:
# Size in bytes that makes the warning trigger.
# Default: 128
sizeThreshold: 32
# Whether to check test functions.
# Default: true
skipTestFuncs: false
ruleguard:
# Enable debug to identify which 'Where' condition was rejected.
# The value of the parameter is the name of a function in a ruleguard file.
#
# When a rule is evaluated:
# If:
# The Match() clause is accepted; and
# One of the conditions in the Where() clause is rejected,
# Then:
# ruleguard prints the specific Where() condition that was rejected.
#
# The option is passed to the ruleguard 'debug-group' argument.
# Default: ""
debug: 'emptyDecl'
# Determines the behavior when an error occurs while parsing ruleguard files.
# If flag is not set, log error and skip rule files that contain an error.
# If flag is set, the value must be a comma-separated list of error conditions.
# - 'all': fail on all errors.
# - 'import': ruleguard rule imports a package that cannot be found.
# - 'dsl': gorule file does not comply with the ruleguard DSL.
# Default: ""
failOn: dsl,import
# Comma-separated list of file paths containing ruleguard rules.
# By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed.
# The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`.
# The placeholder '${config-path}' is substituted with a path relative to the configuration file.
# Glob patterns such as 'rules-*.go' may be specified.
# Default: ""
rules: '${base-path}/ruleguard/rules-*.go,${base-path}/myrule1.go'
# Comma-separated list of enabled groups or skip empty to enable everything.
# Tags can be defined with # character prefix.
# Default: ""
enable: "myGroupName,#myTagName"
# Comma-separated list of disabled groups or skip empty to enable everything.
# Tags can be defined with # character prefix.
# Default: ""
disable: "myGroupName,#myTagName"
tooManyResultsChecker:
# Maximum number of results.
# Default: 5
maxResults: 10
truncateCmp:
# Whether to skip int/uint/uintptr types.
# Default: true
skipArchDependent: false
underef:
# Whether to skip (*x).method() calls where x is a pointer receiver.
# Default: true
skipRecvDeref: false
unnamedResult:
# Whether to check exported functions.
# Default: false
checkExported: true
gocyclo:
# Minimal code complexity to report.
# Default: 30 (but we recommend 10-20)
min-complexity: 10
godoclint:
# Default set of rules to enable.
# Possible values are: `basic`, `all` or `none`.
# Default: `basic` (enables `pkg-doc`, `single-pkg-doc`, `start-with-name`, and `deprecated`)
default: all
# List of rules to enable in addition to the default set.
# Default: empty
enable:
# Check proper package-level godoc, if any.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#pkg-doc
- pkg-doc
# Assert at most one godoc per package.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#single-pkg-doc
- single-pkg-doc
# Require all packages to have a godoc.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#require-pkg-doc
- require-pkg-doc
# Assert symbol godocs start with the symbol name.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#start-with-name
- start-with-name
# Require godoc for all public symbols.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#require-doc
- require-doc
# Assert correct formatting of deprecation notes.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#deprecated
- deprecated
# Assert maximum line length for godocs.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#max-len
- max-len
# Assert no unused link in godocs.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#no-unused-link
- no-unused-link
# Require proper doc links to standard library declarations where applicable.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#require-stdlib-doclink
- require-stdlib-doclink
# List of rules to disable.
# Default: empty
disable:
- pkg-doc
- single-pkg-doc
- require-pkg-doc
- start-with-name
- require-doc
- deprecated
- max-len
- no-unused-link
- require-stdlib-doclink
# A map for fine-tuning individual rules.
# All subkeys are optional.
options:
max-len:
# Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.
# Default: 77
length: 127
require-doc:
# Ignore exported (public) symbols when applying the `require-doc` rule.
# Default: false
ignore-exported: true
# Ignore unexported (private) symbols when applying the `require-doc` rule.
# Default: true
ignore-unexported: false
start-with-name:
# Include unexported symbols when applying the `start-with-name` rule.
# Default: false
include-unexported: true
godot:
# Comments to be checked: `declarations`, `toplevel`, `noinline` or `all`.
# Default: declarations
scope: toplevel
# List of regexps for excluding particular comment lines from check.
# Default: []
exclude:
# Exclude todo and fixme comments.
- "^fixme:"
- "^todo:"
# Check that each sentence ends with a period.
# Default: true
period: false
# Check that each sentence starts with a capital letter.
# Default: false
capital: true
godox:
# Report any comments starting with keywords, this is useful for TODO or FIXME comments that
# might be left in the code accidentally and should be resolved before merging.
# Default: ["TODO", "BUG", "FIXME"]
keywords:
- NOTE
- OPTIMIZE # marks code that should be optimized before merging
- HACK # marks hack-around that should be removed before merging
goheader:
# Supports two types 'const` and `regexp`.
# Values can be used recursively.
# Default: {}
values:
const:
# Define here const type values in format k:v.
# For example:
COMPANY: MY COMPANY
regexp:
# Define here regexp type values.
# for example:
AUTHOR: .*@mycompany\.com
# The template used for checking.
# Put here copyright header template for source code files.
# Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
# Default: ""
template: |-
{{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
# As alternative of directive 'template', you may put the path to file with the template source.
# Useful if you need to load the template from a specific file.
# By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed.
# The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`.
# The placeholder '${config-path}' is substituted with a path relative to the configuration file.
# Default: ""
template-path: /path/to/my/template.tmpl
gomoddirectives:
# Allow local `replace` directives.
# Default: false
replace-local: true
# List of allowed `replace` directives.
# Default: []
replace-allow-list:
- launchpad.net/gocheck
# Allow to not explain why the version has been retracted in the `retract` directives.
# Default: false
retract-allow-no-explanation: true
# Forbid the use of the `exclude` directives.
# Default: false
exclude-forbidden: true
# Forbid the use of the `ignore` directives (>= go1.25).
# Default: false
ignore-forbidden: true
# Forbid the use of the `toolchain` directive.
# Default: false
toolchain-forbidden: true
# Defines a pattern to validate `toolchain` directive.
# Default: '' (no match)
toolchain-pattern: 'go1\.23\.\d+$'
# Forbid the use of the `tool` directives.
# Default: false
tool-forbidden: true
# Forbid the use of the `godebug` directive.
# Default: false
go-debug-forbidden: true
# Defines a pattern to validate `go` minimum version directive.
# Default: '' (no match)
go-version-pattern: '\d\.\d+(\.0)?'
# Check the validity of the module path.
# Default: false
check-module-path: true
gomodguard:
allowed:
# List of allowed modules.
# Default: []
modules:
- gopkg.in/yaml.v2
# List of allowed module domains.
# Default: []
domains:
- golang.org
blocked:
# List of blocked modules.
# Default: []
modules:
# Blocked module.
- github.com/uudashr/go-module:
# Recommended modules that should be used instead. (Optional)
recommendations:
- golang.org/x/mod
# Reason why the recommended module should be used. (Optional)
reason: "`mod` is the official go.mod parser library."
# List of blocked module version constraints.
# Default: []
versions:
# Blocked module with version constraint.
- github.com/mitchellh/go-homedir:
# Version constraint, see https://github.com/Masterminds/semver#basic-comparisons.
version: "< 1.1.0"
# Reason why the version constraint exists. (Optional)
reason: "testing if blocked version constraint works."
# Set to true to raise lint issues for packages that are loaded from a local path via replace directive.
# Default: false
local-replace-directives: false
gosec:
# To select a subset of rules to run.
# Available rules: https://github.com/securego/gosec#available-rules
# Default: [] - means include all rules
includes:
- G101 # Look for hardcoded credentials
- G102 # Bind to all interfaces
- G103 # Audit the use of unsafe block
- G104 # Audit errors not checked
- G106 # Audit the use of ssh.InsecureIgnoreHostKey function
- G107 # Url provided to HTTP request as taint input
- G108 # Profiling endpoint is automatically exposed
- G109 # Converting strconv.Atoi result to int32/int16
- G110 # Detect io.Copy instead of io.CopyN when decompression
- G111 # Detect http.Dir('/') as a potential risk
- G112 # Detect ReadHeaderTimeout not configured as a potential risk
- G113 # HTTP request smuggling via conflicting headers or bare LF in body parsing
- G114 # Use of net/http serve function that has no support for setting timeouts
- G115 # Type conversion which leads to integer overflow
- G116 # Detect Trojan Source attacks using bidirectional Unicode characters
- G117 # Potential exposure of secrets via JSON/YAML/XML/TOML marshaling
- G118 # Context propagation failure leading to goroutine/resource leaks
- G119 # Unsafe redirect policy may propagate sensitive headers
- G120 # Unbounded form parsing in HTTP handlers can cause memory exhaustion
- G121 # Unsafe CrossOriginProtection bypass patterns
- G122 # Filesystem TOCTOU race risk in filepath.Walk/WalkDir callbacks
- G123 # TLS resumption may bypass VerifyPeerCertificate when VerifyConnection is unset
- G201 # SQL query construction using format string
- G202 # SQL query construction using string concatenation
- G203 # Use of unescaped data in HTML templates
- G204 # Audit use of command execution
- G301 # Poor file permissions used when creating a directory
- G302 # Poor file permissions used when creation file or using chmod
- G303 # Creating tempfile using a predictable path
- G304 # File path provided as taint input
- G305 # File path traversal when extracting zip archive
- G306 # Poor file permissions used when writing to a file
- G307 # Poor file permissions used when creating a file with os.Create
- G401 # Detect the usage of MD5 or SHA1
- G402 # Look for bad TLS connection settings
- G403 # Ensure minimum RSA key length of 2048 bits
- G404 # Insecure random number source (rand)
- G405 # Detect the usage of DES or RC4
- G406 # Detect the usage of deprecated MD4 or RIPEMD160
- G408 # Stateful misuse of ssh.PublicKeyCallback leading to auth bypass
- G501 # Import blocklist: crypto/md5
- G502 # Import blocklist: crypto/des
- G503 # Import blocklist: crypto/rc4
- G504 # Import blocklist: net/http/cgi
- G505 # Import blocklist: crypto/sha1
- G506 # Import blocklist: golang.org/x/crypto/md4
- G507 # Import blocklist: golang.org/x/crypto/ripemd160
- G601 # Implicit memory aliasing in RangeStmt
- G602 # Possible slice bounds out of range
- G701 # SQL injection via taint analysis
- G702 # Command injection via taint analysis
- G703 # Path traversal via taint analysis
- G704 # SSRF via taint analysis
- G705 # XSS via taint analysis
- G706 # Log injection via taint analysis
- G707 # SMTP command/header injection via taint analysis
# To specify a set of rules to explicitly exclude.
# Available rules: https://github.com/securego/gosec#available-rules
# Default: []
excludes:
- G101 # Look for hardcoded credentials
- G102 # Bind to all interfaces
- G103 # Audit the use of unsafe block
- G104 # Audit errors not checked
- G106 # Audit the use of ssh.InsecureIgnoreHostKey function
- G107 # Url provided to HTTP request as taint input
- G108 # Profiling endpoint is automatically exposed
- G109 # Converting strconv.Atoi result to int32/int16
- G110 # Detect io.Copy instead of io.CopyN when decompression
- G111 # Detect http.Dir('/') as a potential risk
- G112 # Detect ReadHeaderTimeout not configured as a potential risk
- G114 # Use of net/http serve function that has no support for setting timeouts
- G115 # Type conversion which leads to integer overflow
- G116 # Detect Trojan Source attacks using bidirectional Unicode characters
- G201 # SQL query construction using format string
- G202 # SQL query construction using string concatenation
- G203 # Use of unescaped data in HTML templates
- G204 # Audit use of command execution
- G301 # Poor file permissions used when creating a directory
- G302 # Poor file permissions used when creation file or using chmod
- G303 # Creating tempfile using a predictable path
- G304 # File path provided as taint input
- G305 # File path traversal when extracting zip archive
- G306 # Poor file permissions used when writing to a file
- G307 # Poor file permissions used when creating a file with os.Create
- G401 # Detect the usage of MD5 or SHA1
- G402 # Look for bad TLS connection settings
- G403 # Ensure minimum RSA key length of 2048 bits
- G404 # Insecure random number source (rand)
- G405 # Detect the usage of DES or RC4
- G406 # Detect the usage of deprecated MD4 or RIPEMD160
- G501 # Import blocklist: crypto/md5
- G502 # Import blocklist: crypto/des
- G503 # Import blocklist: crypto/rc4
- G504 # Import blocklist: net/http/cgi
- G505 # Import blocklist: crypto/sha1
- G506 # Import blocklist: golang.org/x/crypto/md4
- G507 # Import blocklist: golang.org/x/crypto/ripemd160
- G601 # Implicit memory aliasing in RangeStmt
- G602 # Possible slice bounds out of range
# Filter out the issues with a lower severity than the given value.
# Valid options are: low, medium, high.
# Default: low
severity: medium
# Filter out the issues with a lower confidence than the given value.
# Valid options are: low, medium, high.
# Default: low
confidence: medium
# Concurrency value.
# Default: the number of logical CPUs usable by the current process.
concurrency: 12
# To specify the configuration of rules.
config:
# Globals are applicable to all rules.
global:
# If true, ignore #nosec in comments (and an alternative as well).
# Default: false
nosec: true
# Add an alternative comment prefix to #nosec (both will work at the same time).
# Default: ""
"#nosec": "#my-custom-nosec"
# Define whether nosec issues are counted as finding or not.
# Default: false
show-ignored: true
# Audit mode enables addition checks that for normal code analysis might be too nosy.
# Default: false
audit: true
G101:
# Regexp pattern for variables and constants to find.
# Default: "(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred"
pattern: "(?i)example"
# If true, complain about all cases (even with low entropy).
# Default: false
ignore_entropy: false
# Maximum allowed entropy of the string.
# Default: "80.0"
entropy_threshold: "80.0"
# Maximum allowed value of entropy/string length.
# Is taken into account if entropy >= entropy_threshold/2.
# Default: "3.0"
per_char_threshold: "3.0"
# Calculate entropy for first N chars of the string.
# Default: "16"
truncate: "32"
# Additional functions to ignore while checking unhandled errors.
# Following functions always ignored:
# bytes.Buffer:
# - Write
# - WriteByte
# - WriteRune
# - WriteString
# fmt:
# - Print
# - Printf
# - Println
# - Fprint
# - Fprintf
# - Fprintln
# strings.Builder:
# - Write
# - WriteByte
# - WriteRune
# - WriteString
# io.PipeWriter:
# - CloseWithError
# hash.Hash:
# - Write
# os:
# - Unsetenv
# Default: {}
G104:
fmt:
- Fscanf
G111:
# Regexp pattern to find potential directory traversal.
# Default: "http\\.Dir\\(\"\\/\"\\)|http\\.Dir\\('\\/'\\)"
pattern: "custom\\.Dir\\(\\)"
# Maximum allowed permissions mode for os.Mkdir and os.MkdirAll.
# Default: "0750"
G301: "0750"
# Maximum allowed permissions mode for os.OpenFile and os.Chmod.
# Default: "0600"
G302: "0600"
# Maximum allowed permissions mode for os.WriteFile and ioutil.WriteFile.
# Default: "0600"
G306: "0600"
gosmopolitan:
# Allow and ignore `time.Local` usages.
#
# Default: false
allow-time-local: true
# List of fully qualified names in the `full/pkg/path.name` form, to act as "i18n escape hatches".
# String literals inside call-like expressions to, or struct literals of those names,
# are exempt from the writing system check.
#
# Default: []
escape-hatches:
- 'github.com/nicksnyder/go-i18n/v2/i18n.Message'
- 'example.com/your/project/i18n/markers.Raw'
- 'example.com/your/project/i18n/markers.OK'
- 'example.com/your/project/i18n/markers.TODO'
- 'command-line-arguments.Simple'
# List of Unicode scripts to watch for any usage in string literals.
# https://pkg.go.dev/unicode#pkg-variables
#
# Default: ["Han"]
watch-for-scripts:
- Devanagari
- Han
- Hangul
- Hiragana
- Katakana
govet:
# Disable all analyzers.
# Default: false
disable-all: true
# Enable analyzers by name.
# (In addition to default:
# appends, asmdecl, assign, atomic, bools, buildtag, cgocall, composites, copylocks, defers, directive, errorsas,
# framepointer, httpresponse, ifaceassert, loopclosure, lostcancel, nilfunc, printf, shift, sigchanyzer, slog,
# stdmethods, stringintconv, structtag, testinggoroutine, tests, timeformat, unmarshal, unreachable, unsafeptr,
# unusedresult
# ).
# Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers.
# Default: []
enable:
# Check for missing values after append.
- appends
# Report mismatches between assembly files and Go declarations.
- asmdecl
# Check for useless assignments.
- assign
# Check for common mistakes using the sync/atomic package.
- atomic
# Check for non-64-bits-aligned arguments to sync/atomic functions.
- atomicalign
# Check for common mistakes involving boolean operators.
- bools
# Check //go:build and // +build directives.
- buildtag
# Detect some violations of the cgo pointer passing rules.
- cgocall
# Check for unkeyed composite literals.
- composites
# Check for locks erroneously passed by value.
- copylocks
# Check for calls of reflect.DeepEqual on error values.
- deepequalerrors
# Report common mistakes in defer statements.
- defers
# Check Go toolchain directives such as //go:debug.
- directive
# Report passing non-pointer or non-error values to errors.As.
- errorsas
# Find structs that would use less memory if their fields were sorted.
- fieldalignment
# Find calls to a particular function.
- findcall
# Report assembly that clobbers the frame pointer before saving it.
- framepointer
# Check format of addresses passed to net.Dial.
- hostport
# Report using Go 1.22 enhanced ServeMux patterns in older Go versions.
- httpmux
# Check for mistakes using HTTP responses.
- httpresponse
# Detect impossible interface-to-interface type assertions.
- ifaceassert
# Check references to loop variables from within nested functions.
- loopclosure
# Check cancel func returned by context.WithCancel is called.
- lostcancel
# Check for useless comparisons between functions and nil.
- nilfunc
# Check for redundant or impossible nil comparisons.
- nilness
# Check consistency of Printf format strings and arguments.
- printf
# Check for comparing reflect.Value values with == or reflect.DeepEqual.
- reflectvaluecompare
# Check for possible unintended shadowing of variables.
- shadow
# Check for shifts that equal or exceed the width of the integer.
- shift
# Check for unbuffered channel of os.Signal.
- sigchanyzer
# Check for invalid structured logging calls.
- slog
# Check the argument type of sort.Slice.
- sortslice
# Check signature of methods of well-known interfaces.
- stdmethods
# Report uses of too-new standard library symbols.
- stdversion
# Check for string(int) conversions.
- stringintconv
# Check that struct field tags conform to reflect.StructTag.Get.
- structtag
# Report calls to (*testing.T).Fatal from goroutines started by a test.
- testinggoroutine
# Check for common mistaken usages of tests and examples.
- tests
# Check for calls of (time.Time).Format or time.Parse with 2006-02-01.
- timeformat
# Report passing non-pointer or non-interface values to unmarshal.
- unmarshal
# Check for unreachable code.
- unreachable
# Check for invalid conversions of uintptr to unsafe.Pointer.
- unsafeptr
# Check for unused results of calls to some functions.
- unusedresult
# Checks for unused writes.
- unusedwrite
# Check for misuses of sync.WaitGroup.
- waitgroup
# Enable all analyzers.
# Default: false
enable-all: true
# Disable analyzers by name.
# (In addition to default
# atomicalign, deepequalerrors, fieldalignment, findcall, nilness, reflectvaluecompare, shadow, sortslice,
# timeformat, unusedwrite
# ).
# Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers.
# Default: []
disable:
- appends
- asmdecl
- assign
- atomic
- atomicalign
- bools
- buildtag
- cgocall
- composites
- copylocks
- deepequalerrors
- defers
- directive
- errorsas
- fieldalignment
- findcall
- framepointer
- hostport
- httpmux
- httpresponse
- ifaceassert
- loopclosure
- lostcancel
- nilfunc
- nilness
- printf
- reflectvaluecompare
- shadow
- shift
- sigchanyzer
- slog
- sortslice
- stdmethods
- stdversion
- stringintconv
- structtag
- testinggoroutine
- tests
- timeformat
- unmarshal
- unreachable
- unsafeptr
- unusedresult
- unusedwrite
- waitgroup
# Settings per analyzer.
settings:
# Analyzer name, run `go tool vet help` to see all analyzers.
printf:
# Comma-separated list of print function names to check (in addition to default, see `go tool vet help printf`).
# Default: []
funcs:
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Fatalf
shadow:
# Whether to be strict about shadowing; can be noisy.
# Default: false
strict: true
unusedresult:
# Comma-separated list of functions whose results must be used.
# (In addition to default:
# context.WithCancel, context.WithDeadline, context.WithTimeout, context.WithValue, errors.New, fmt.Errorf,
# fmt.Sprint, fmt.Sprintf, sort.Reverse
# ).
# Default: []
funcs:
- pkg.MyFunc
# Comma-separated list of names of methods of type func() string whose results must be used.
# (In addition to default Error,String).
# Default: []
stringmethods:
- MyMethod
grouper:
# Require the use of a single global 'const' declaration only.
# Default: false
const-require-single-const: true
# Require the use of grouped global 'const' declarations.
# Default: false
const-require-grouping: true
# Require the use of a single 'import' declaration only.
# Default: false
import-require-single-import: true
# Require the use of grouped 'import' declarations.
# Default: false
import-require-grouping: true
# Require the use of a single global 'type' declaration only.
# Default: false
type-require-single-type: true
# Require the use of grouped global 'type' declarations.
# Default: false
type-require-grouping: true
# Require the use of a single global 'var' declaration only.
# Default: false
var-require-single-var: true
# Require the use of grouped global 'var' declarations.
# Default: false
var-require-grouping: true
iface:
# List of analyzers.
# Default: ["identical"]
enable:
- identical # Identifies interfaces in the same package that have identical method sets.
- unused # Identifies interfaces that are not used anywhere in the same package where the interface is defined.
- opaque # Identifies functions that return interfaces, but the actual returned value is always a single concrete implementation.
- unexported # Identifies interfaces that are not exported but are used in exported functions or methods.
settings:
unused:
# List of packages path to exclude from the check.
# Default: []
exclude:
- github.com/example/log
importas:
# Do not allow unaliased imports of aliased packages.
# Default: false
no-unaliased: true
# Do not allow non-required aliases.
# Default: false
no-extra-aliases: true
# List of aliases
# Default: []
alias:
# Using `servingv1` alias for `knative.dev/serving/pkg/apis/serving/v1` package.
- pkg: knative.dev/serving/pkg/apis/serving/v1
alias: servingv1
# Using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package.
- pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
alias: autoscalingv1alpha1
# You can specify the package path by regular expression,
# and alias by regular expression expansion syntax like below.
# See https://github.com/julz/importas#use-regular-expression for details.
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
alias: $1$2
# An explicit empty alias can be used to ensure no aliases are used for a package.
# This can be useful if `no-extra-aliases: true` doesn't fit your need.
# Multiple packages can use an empty alias.
- pkg: errors
alias: ""
inamedparam:
# Skips check for interface methods with only a single parameter.
# Default: false
skip-single-param: true
ineffassign:
# Check escaping variables of type error, may cause false positives.
# Default: false
check-escaping-errors: true
interfacebloat:
# The maximum number of methods allowed for an interface.
# Default: 10
max: 5
iotamixing:
# Whether to report individual consts rather than just the const block.
# Default: false
report-individual: true
ireturn:
# List of interfaces to allow.
# Lists of the keywords and regular expressions matched to interface or package names can be used.
# `allow` and `reject` settings cannot be used at the same time.
#
# Keywords:
# - `empty` for `interface{}`
# - `error` for errors
# - `stdlib` for standard library
# - `anon` for anonymous interfaces
# - `generic` for generic interfaces added in go 1.18
#
# Default: [anon, error, empty, stdlib]
allow:
- anon
# You can specify idiomatic endings for interface
- (or|er)$
# List of interfaces to reject.
# Lists of the keywords and regular expressions matched to interface or package names can be used.
# `allow` and `reject` settings cannot be used at the same time.
#
# Keywords:
# - `empty` for `interface{}`
# - `error` for errors
# - `stdlib` for standard library
# - `anon` for anonymous interfaces
# - `generic` for generic interfaces added in go 1.18
#
# Default: []
reject:
- github.com\/user\/package\/v4\.Type
lll:
# Max line length, lines longer will be reported.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option.
# Default: 120.
line-length: 120
# Tab width in spaces.
# Default: 1
tab-width: 1
loggercheck:
# Allow check for the github.com/go-kit/log library.
# Default: true
kitlog: false
# Allow check for the k8s.io/klog/v2 library.
# Default: true
klog: false
# Allow check for the github.com/go-logr/logr library.
# Default: true
logr: false
# Allow check for the log/slog library.
# Default: true
slog: false
# Allow check for the "sugar logger" from go.uber.org/zap library.
# Default: true
zap: false
# Require all logging keys to be inlined constant strings.
# Default: false
require-string-key: true
# Require printf-like format specifier (%s, %d for example) not present.
# Default: false
no-printf-like: true
# List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.
# For example: https://github.com/timonwong/loggercheck/blob/7395ab86595781e33f7afba27ad7b55e6956ebcd/testdata/custom-rules.txt
# Default: empty
rules:
- k8s.io/klog/v2.InfoS # package level exported functions
- (github.com/go-logr/logr.Logger).Error # "Methods"
- (*go.uber.org/zap.SugaredLogger).With # Also "Methods", but with a pointer receiver
maintidx:
# Show functions with maintainability index lower than N.
# A high index indicates better maintainability (it's kind of the opposite of complexity).
# Default: 20
under: 100
makezero:
# Allow only slices initialized with a length of zero.
# Default: false
always: true
misspell:
# Correct spellings using locale preferences for US or UK.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
# Default is to use a neutral variety of English.
locale: US
# Typos to ignore.
# Should be in lower case.
# Default: []
ignore-rules:
- someword
# Extra word corrections.
# `typo` and `correction` should only contain letters.
# The words are case-insensitive.
# Default: []
extra-words:
- typo: "iff"
correction: "if"
- typo: "cancelation"
correction: "cancellation"
# Mode of the analysis:
# - default: checks all the file content.
# - restricted: checks only comments.
# Default: ""
mode: restricted
mnd:
# List of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
# Default: ["argument", "case", "condition", "operation", "return", "assign"]
checks:
- argument
- case
- condition
- operation
- return
- assign
# List of numbers to exclude from analysis.
# The numbers should be written as string.
# Values always ignored: "1", "1.0", "0" and "0.0".
# Default: []
ignored-numbers:
- '0666'
- '0755'
- '42'
# List of file patterns to exclude from analysis.
# Values always ignored: `.+_test.go`.
# Default: []
ignored-files:
- 'magic1_.+\.go$'
# List of function patterns to exclude from analysis.
# Following functions are always ignored: `time.Date`,
# `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`,
# `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`.
# Default: []
ignored-functions:
- '^math\.'
- '^http\.StatusText$'
modernize:
# List of analyzers to disable.
# By default, all analyzers are enabled.
disable:
# Replace interface{} with any.
- any
# Replace []byte(fmt.Sprintf) with fmt.Appendf.
- fmtappendf
# Remove redundant re-declaration of loop variables.
- forvar
# Replace explicit loops over maps with calls to maps package.
- mapsloop
# Replace if/else statements with calls to min or max.
- minmax
# Simplify code by using go1.26's new(expr).
- newexpr
# Suggest replacing omitempty with omitzero for struct fields.
- omitzero
# Remove obsolete //+build comments.
- plusbuild
# Replace 3-clause for loops with for-range over integers.
- rangeint
# Replace reflect.TypeOf(x) with TypeFor[T]().
- reflecttypefor
# Replace loops with slices.Contains or slices.ContainsFunc.
- slicescontains
# Replace sort.Slice with slices.Sort for basic types.
- slicessort
# Use iterators instead of Len/At-style APIs.
- stditerators
# Replace strings.Index etc. with strings.Cut.
- stringscut
# Replace HasPrefix/TrimPrefix with CutPrefix.
- stringscutprefix
# Replace ranging over Split/Fields with SplitSeq/FieldsSeq.
- stringsseq
# Replace += with strings.Builder.
- stringsbuilder
# Replace context.WithCancel with t.Context in tests.
- testingcontext
# Replace unsafe pointer arithmetic with function calls.
- unsafefuncs
# Replace wg.Add(1)/go/wg.Done() with wg.Go.
- waitgroup
musttag:
# A set of custom functions to check in addition to the builtin ones.
# Default: json, xml, gopkg.in/yaml.v3, BurntSushi/toml, mitchellh/mapstructure, jmoiron/sqlx
functions:
# The full name of the function, including the package.
- name: github.com/hashicorp/hcl/v2/hclsimple.DecodeFile
# The struct tag whose presence should be ensured.
tag: hcl
# The position of the argument to check.
arg-pos: 2
nakedret:
# Make an issue if func has more lines of code than this setting, and it has naked returns.
# Default: 30
max-func-lines: 31
nestif:
# Minimal complexity of if statements to report.
# Default: 5
min-complexity: 4
nilnil:
# To check functions with only two return values (`return nil, nil`).
# If disabled then returns like `return nil, nil, ..., nil` are supported.
# Default: true
only-two: false
# In addition, detect opposite situation (simultaneous return of non-nil error and valid value).
# E.g, `return clone, fh.indexer.Update(clone)` will be considered as invalid.
# Default: false
detect-opposite: true
# List of return types to check.
# Default: ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
checked-types:
- chan
- func
- iface
- map
- ptr
- uintptr
- unsafeptr
nlreturn:
# Size of the block (including return statement that is still "OK"),
# so no return split required.
# Default: 1
block-size: 2
nolintlint:
# Disable to ensure that all nolint directives actually have an effect.
# Default: false
allow-unused: true
# Exclude following linters from requiring an explanation.
# Default: []
allow-no-explanation: [ ]
# Enable to require an explanation of nonzero length after each nolint directive.
# Default: false
require-explanation: true
# Enable to require nolint directives to mention the specific linter being suppressed.
# Default: false
require-specific: true
nonamedreturns:
# Report named error if it is assigned inside defer.
# Default: false
report-error-in-defer: true
paralleltest:
# Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.
# Default: false
ignore-missing: true
# Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are
# still required to have `t.Parallel`, but subtests are allowed to skip it.
# Default: false
ignore-missing-subtests: true
perfsprint:
# Enable/disable optimization of integer formatting.
# Default: true
integer-format: false
# Optimizes even if it requires an int or uint type cast.
# Default: true
int-conversion: false
# Enable/disable optimization of error formatting.
# Default: true
error-format: false
# Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.
# Default: false
err-error: true
# Optimizes `fmt.Errorf`.
# Default: true
errorf: false
# Enable/disable optimization of string formatting.
# Default: true
string-format: false
# Optimizes `fmt.Sprintf` with only one argument.
# Default: true
sprintf1: false
# Optimizes into strings concatenation.
# Default: true
strconcat: false
# Enable/disable optimization of bool formatting.
# Default: true
bool-format: false
# Enable/disable optimization of hex formatting.
# Default: true
hex-format: false
# Enable/disable optimization of concat loop.
# Default: true
concat-loop: false
# Optimization of `concat-loop` even with other operations.
# Default: false
loop-other-ops: true
prealloc:
# IMPORTANT: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization.
# Report pre-allocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# Default: true
simple: false
# Report pre-allocation suggestions on range loops.
# Default: true
range-loops: false
# Report pre-allocation suggestions on for loops.
# Default: false
for-loops: true
predeclared:
# List of predeclared identifiers to not report on.
# Default: []
ignore:
- new
- int
# Include method names and field names in checks.
# Default: false
qualified-name: true
promlinter:
# Promlinter cannot infer all metrics name in static analysis.
# Enable strict mode will also include the errors caused by failing to parse the args.
# Default: false
strict: true
# Please refer to https://github.com/yeya24/promlinter#usage for detailed usage.
# Default: []
disabled-linters:
# Help detects issues related to the help text for a metric.
- Help
# MetricUnits detects issues with metric unit names.
- MetricUnits
# Counter detects issues specific to counters, as well as patterns that should only be used with counters.
- Counter
# HistogramSummaryReserved detects when other types of metrics use names or labels reserved for use by histograms and/or summaries.
- HistogramSummaryReserved
# MetricTypeInName detects when metric types are included in the metric name.
- MetricTypeInName
# ReservedChars detects colons in metric names.
- ReservedChars
# CamelCase detects metric names and label names written in camelCase.
- CamelCase
# UnitAbbreviations detects abbreviated units in the metric name.
- UnitAbbreviations
protogetter:
# Skip files generated by specified generators from the checking.
# Checks only the file's initial comment, which must follow the format: "// Code generated by ".
# Files generated by protoc-gen-go, protoc-gen-go-grpc, and protoc-gen-grpc-gateway are always excluded automatically.
# Default: []
skip-generated-by: ["protoc-gen-go-my-own-generator"]
# Skip files matching the specified glob pattern from the checking.
# Default: []
skip-files:
- "*.pb.go"
- "*/vendor/*"
- "/full/path/to/file.go"
# Skip any generated files from the checking.
# Default: false
skip-any-generated: true
# Skip first argument of append function.
# Default: false
replace-first-arg-in-append: true
reassign:
# Patterns for global variable names that are checked for reassignment.
# See https://github.com/curioswitch/go-reassign#usage
# Default: ["EOF", "Err.*"]
patterns:
- ".*"
recvcheck:
# Disables the built-in method exclusions:
# - `MarshalText`
# - `MarshalJSON`
# - `MarshalYAML`
# - `MarshalXML`
# - `MarshalBinary`
# - `GobEncode`
# Default: false
disable-builtin: true
# User-defined method exclusions.
# The format is `struct_name.method_name` (ex: `Foo.MethodName`).
# A wildcard `*` can use as a struct name (ex: `*.MethodName`).
# Default: []
exclusions:
- "*.Value"
revive:
# Maximum number of open files at the same time.
# See https://github.com/mgechev/revive#command-line-flags
# Defaults to unlimited.
max-open-files: 2048
# Sets the default severity.
# See https://github.com/mgechev/revive#configuration
# Default: warning
severity: error
# Enable all available rules.
# Default: false
enable-all-rules: true
# By default, the default rules are enabled,
# but if you explicitly define or configure a rule, the default rules will be disabled.
# This option, when set to `true`, allows you to avoid explicitly redefining default rules when adding a rule.
# Default: false
enable-default-rules: true
# Enable validation of comment directives.
# See https://github.com/mgechev/revive#comment-directives
directives:
- name: specify-disable-reason
severity: error
# Sets the default failure confidence.
# This means that linting errors with less than 0.8 confidence will be ignored.
# Default: 0.8
confidence: 0.1
# Revive handles the default rules in a way that can be unexpected:
# - If there are no explicit rules, the default rules are used.
# - If there is at least one explicit rule, the default rules are not used, unless `enable-default-rules` is `true`.
# Run `GL_DEBUG=revive golangci-lint run --enable-only=revive` to see default, all available rules, and enabled rules.
rules:
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#add-constant
- name: add-constant
severity: warning
disabled: false
exclude: [""]
arguments:
- max-lit-count: "3"
allow-strs: '""'
allow-ints: "0,1,2"
allow-floats: "0.0,0.,1.0,1.,2.0,2."
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#argument-limit
- name: argument-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 4 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#atomic
- name: atomic
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#banned-characters
- name: banned-characters
severity: warning
disabled: false
exclude: [""]
arguments: [ "Ω","Σ","σ", "7" ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#bare-return
- name: bare-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#blank-imports
- name: blank-imports
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#bool-literal-in-expr
- name: bool-literal-in-expr
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#call-to-gc
- name: call-to-gc
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#cognitive-complexity
- name: cognitive-complexity
severity: warning
disabled: false
exclude: [""]
arguments: [ 7 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#comment-spacings
- name: comment-spacings
severity: warning
disabled: false
exclude: [""]
arguments:
- mypragma
- otherpragma
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#comments-density
- name: comments-density
severity: warning
disabled: false
exclude: [""]
arguments: [ 15 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#confusing-naming
- name: confusing-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#confusing-results
- name: confusing-results
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#constant-logical-expr
- name: constant-logical-expr
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#context-as-argument
- name: context-as-argument
severity: warning
disabled: false
exclude: [""]
arguments:
- allow-types-before: "*testing.T,*github.com/user/repo/testing.Harness"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#context-keys-type
- name: context-keys-type
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#cyclomatic
- name: cyclomatic
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#datarace
- name: datarace
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#deep-exit
- name: deep-exit
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#defer
- name: defer
severity: warning
disabled: false
exclude: [""]
arguments:
- "call-chain"
- "loop"
- "method-call"
- "recover"
- "immediate-recover"
- "return"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#dot-imports
- name: dot-imports
severity: warning
disabled: false
exclude: [""]
arguments:
- allowed-packages: ["github.com/onsi/ginkgo/v2", "github.com/onsi/gomega"]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#duplicated-imports
- name: duplicated-imports
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#early-return
- name: early-return
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserve-scope"
- "allow-jump"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#empty-block
- name: empty-block
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#empty-lines
- name: empty-lines
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-map-style
- name: enforce-map-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "make"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-repeated-arg-type-style
- name: enforce-repeated-arg-type-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "short"
# Or this parameter:
- func-arg-style: "full"
func-ret-val-style: "short"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-slice-style
- name: enforce-slice-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "make"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-switch-style
- name: enforce-switch-style
severity: warning
disabled: false
exclude: [""]
arguments: [ "allowNoDefault" ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#epoch-naming
- name: epoch-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-naming
- name: error-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-return
- name: error-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-strings
- name: error-strings
severity: warning
disabled: false
exclude: [""]
arguments:
- "xerrors.New"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#errorf
- name: errorf
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#exported
- name: exported
severity: warning
disabled: false
exclude: [""]
arguments:
- "check-private-receivers"
- "disable-stuttering-check"
- "say-repetitive-instead-of-stutters"
- "check-public-interface"
- "disable-checks-on-constants"
- "disable-checks-on-functions"
- "disable-checks-on-methods"
- "disable-checks-on-types"
- "disable-checks-on-variables"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#file-header
- name: file-header
severity: warning
disabled: false
exclude: [""]
arguments:
- This is the text that must appear at the top of source files.
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#file-length-limit
- name: file-length-limit
severity: warning
disabled: false
exclude: [""]
arguments:
- max: 100
skip-comments: true
skip-blank-lines: true
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#filename-format
- name: filename-format
severity: warning
disabled: false
exclude: [""]
arguments:
- "^[_a-z][_a-z0-9]*\\.go$"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#flag-parameter
- name: flag-parameter
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#forbidden-call-in-wg-go
- name: forbidden-call-in-wg-go
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#function-length
- name: function-length
severity: warning
disabled: false
exclude: [""]
arguments: [ 10, 0 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#function-result-limit
- name: function-result-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#get-return
- name: get-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-branches
- name: identical-branches
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-ifelseif-branches
- name: identical-ifelseif-branches
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-ifelseif-conditions
- name: identical-ifelseif-conditions
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-switch-branches
- name: identical-switch-branches
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-switch-conditions
- name: identical-switch-conditions
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#if-return
- name: if-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#import-alias-naming
- name: import-alias-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- "^[a-z][a-z0-9]{0,}$"
# Or this parameter:
- allow-regex: "^[a-z][a-z0-9]{0,}$"
deny-regex: '^v\d+$'
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#import-shadowing
- name: import-shadowing
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#imports-blocklist
- name: imports-blocklist
severity: warning
disabled: false
exclude: [""]
arguments:
- "crypto/md5"
- "crypto/sha1"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#increment-decrement
- name: increment-decrement
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#indent-error-flow
- name: indent-error-flow
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserve-scope"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#inefficient-map-lookup
- name: inefficient-map-lookup
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#line-length-limit
- name: line-length-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 80 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#max-control-nesting
- name: max-control-nesting
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#max-public-structs
- name: max-public-structs
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#modifies-parameter
- name: modifies-parameter
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#modifies-value-receiver
- name: modifies-value-receiver
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#nested-structs
- name: nested-structs
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#optimize-operands-order
- name: optimize-operands-order
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#package-comments
- name: package-comments
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#package-directory-mismatch
- name: package-directory-mismatch
severity: warning
disabled: false
exclude: [""]
arguments:
- ignore-directories: ["testcases", "testinfo"]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#package-naming
- name: package-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- skip-convention-name-check: true
convention-name-check-regex: "^[a-z][a-zA-Z0-9]*$"
skip-top-level-check: true
skip-default-bad-name-check: true
check-extra-bad-name: true
user-defined-bad-names:
- foo
- bar
skip-collision-with-common-std: true
check-collision-with-all-std: true
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range
- name: range
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range-val-address
- name: range-val-address
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range-val-in-closure
- name: range-val-in-closure
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#receiver-naming
- name: receiver-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- max-length: 2
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redefines-builtin-id
- name: redefines-builtin-id
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redundant-build-tag
- name: redundant-build-tag
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redundant-import-alias
- name: redundant-import-alias
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redundant-test-main-exit
- name: redundant-test-main-exit
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#string-format
- name: string-format
severity: warning
disabled: false
exclude: [""]
arguments:
- - 'core.WriteError[1].Message'
- '/^([^A-Z]|$)/'
- must not start with a capital letter
- - 'fmt.Errorf[0]'
- '/(^|[^\.!?])$/'
- must not end in punctuation
- - panic
- '/^[^\n]*$/'
- must not contain line breaks
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#string-of-int
- name: string-of-int
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#struct-tag
- name: struct-tag
severity: warning
disabled: false
exclude: [""]
arguments:
- "!validate"
- "json,inline"
- "bson,outline,gnu"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#superfluous-else
- name: superfluous-else
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserve-scope"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#time-date
- name: time-date
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#time-equal
- name: time-equal
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#time-naming
- name: time-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unchecked-type-assertion
- name: unchecked-type-assertion
severity: warning
disabled: false
exclude: [""]
arguments:
- accept-ignored-assertion-result: true
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unconditional-recursion
- name: unconditional-recursion
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unexported-naming
- name: unexported-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unexported-return
- name: unexported-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unhandled-error
- name: unhandled-error
severity: warning
disabled: false
exclude: [""]
arguments:
- "^fmt.Printf"
- "myFunction"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unnecessary-format
- name: unnecessary-format
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unnecessary-if
- name: unnecessary-if
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unnecessary-stmt
- name: unnecessary-stmt
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unreachable-code
- name: unreachable-code
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-slices-sort
- name: use-slices-sort
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unsecure-url-scheme
- name: unsecure-url-scheme
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unused-parameter
- name: unused-parameter
severity: warning
disabled: false
exclude: [""]
arguments:
- allow-regex: "^_"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unused-receiver
- name: unused-receiver
severity: warning
disabled: false
exclude: [""]
arguments:
- allow-regex: "^_"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-any
- name: use-any
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-errors-new
- name: use-errors-new
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-fmt-print
- name: use-fmt-print
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-slices-sort
- name: use-slices-sort
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-waitgroup-go
- name: use-waitgroup-go
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#useless-break
- name: useless-break
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#useless-fallthrough
- name: useless-fallthrough
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#var-declaration
- name: var-declaration
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#var-naming
- name: var-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- [ "ID" ] # AllowList
- [ "VM" ] # DenyList
- - skip-initialism-name-checks: true
upper-case-const: true
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#waitgroup-by-value
- name: waitgroup-by-value
severity: warning
disabled: false
exclude: [""]
rowserrcheck:
# database/sql is always checked.
# Default: []
packages:
- github.com/jmoiron/sqlx
sloglint:
# Enforce not mixing key-value pairs and attributes.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-mixed-arguments
# Default: true
no-mixed-args: false
# Enforce using key-value pairs only (overrides no-mixed-args, incompatible with attr-only).
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#key-value-pairs-only
# Default: false
kv-only: true
# Enforce using attributes only (overrides no-mixed-args, incompatible with kv-only).
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#attributes-only
# Default: false
attr-only: true
# Enforce not using global loggers.
# Values:
# - "": disabled
# - "all": report all global loggers
# - "default": report only the default slog logger
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-global
# Default: ""
no-global: "all"
# Enforce using methods that accept a context.
# Values:
# - "": disabled
# - "all": report all contextless calls
# - "scope": report only if a context exists in the scope of the outermost function
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#context-only
# Default: ""
context: "all"
# Enforce using static values for log messages.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#static-messages
# Default: false
static-msg: true
# Enforce message style.
# Values: lowercased, capitalized
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#message-style
# Default: ""
msg-style: capitalized
# Enforce using constants instead of raw keys.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-raw-keys
# Default: false
no-raw-keys: true
# Enforce key naming convention.
# Values: snake, kebab, camel, pascal
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#key-naming-convention
# Default: ""
key-naming-case: snake
# Enforce not using specific keys.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#forbidden-keys
# Default: []
forbidden-keys:
- time
- level
- msg
- source
- foo
# Enforce putting arguments on separate lines.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#arguments-on-separate-lines
# Default: false
args-on-sep-lines: true
spancheck:
# Checks to enable.
# Options include:
# - `end`: check that `span.End()` is called
# - `record-error`: check that `span.RecordError(err)` is called when an error is returned
# - `set-status`: check that `span.SetStatus(codes.Error, msg)` is called when an error is returned
# Default: ["end"]
checks:
- end
- record-error
- set-status
# A list of regexes for function signatures that silence `record-error` and `set-status` reports
# if found in the call path to a returned error.
# https://github.com/jjti/go-spancheck#ignore-check-signatures
# Default: []
ignore-check-signatures:
- "telemetry.RecordError"
# A list of regexes for additional function signatures that create spans.
# This is useful if you have a utility method to create spans.
# Each entry should be of the form `:`, where `telemetry-type` can be `opentelemetry` or `opencensus`.
# https://github.com/jjti/go-spancheck#extra-start-span-signatures
# Default: []
extra-start-span-signatures:
- "github.com/user/repo/telemetry/trace.Start:opentelemetry"
staticcheck:
# https://staticcheck.dev/docs/configuration/options/#dot_import_whitelist
# Default: ["github.com/mmcloughlin/avo/build", "github.com/mmcloughlin/avo/operand", "github.com/mmcloughlin/avo/reg"]
dot-import-whitelist:
- fmt
# https://staticcheck.dev/docs/configuration/options/#initialisms
# Default: ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"]
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ]
# https://staticcheck.dev/docs/configuration/options/#http_status_code_whitelist
# Default: ["200", "400", "404", "500"]
http-status-code-whitelist: [ "200", "400", "404", "500" ]
# SAxxxx checks in https://staticcheck.dev/docs/configuration/options/#checks
# Example (to disable some checks): [ "all", "-SA1000", "-SA1001"]
# Run `GL_DEBUG=staticcheck golangci-lint run --enable=staticcheck` to see all available checks and enabled by config checks.
# Default: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"]
checks:
# Invalid regular expression.
# https://staticcheck.dev/docs/checks/#SA1000
- SA1000
# Invalid template.
# https://staticcheck.dev/docs/checks/#SA1001
- SA1001
# Invalid format in 'time.Parse'.
# https://staticcheck.dev/docs/checks/#SA1002
- SA1002
# Unsupported argument to functions in 'encoding/binary'.
# https://staticcheck.dev/docs/checks/#SA1003
- SA1003
# Suspiciously small untyped constant in 'time.Sleep'.
# https://staticcheck.dev/docs/checks/#SA1004
- SA1004
# Invalid first argument to 'exec.Command'.
# https://staticcheck.dev/docs/checks/#SA1005
- SA1005
# 'Printf' with dynamic first argument and no further arguments.
# https://staticcheck.dev/docs/checks/#SA1006
- SA1006
# Invalid URL in 'net/url.Parse'.
# https://staticcheck.dev/docs/checks/#SA1007
- SA1007
# Non-canonical key in 'http.Header' map.
# https://staticcheck.dev/docs/checks/#SA1008
- SA1008
# '(*regexp.Regexp).FindAll' called with 'n == 0', which will always return zero results.
# https://staticcheck.dev/docs/checks/#SA1010
- SA1010
# Various methods in the "strings" package expect valid UTF-8, but invalid input is provided.
# https://staticcheck.dev/docs/checks/#SA1011
- SA1011
# A nil 'context.Context' is being passed to a function, consider using 'context.TODO' instead.
# https://staticcheck.dev/docs/checks/#SA1012
- SA1012
# 'io.Seeker.Seek' is being called with the whence constant as the first argument, but it should be the second.
# https://staticcheck.dev/docs/checks/#SA1013
- SA1013
# Non-pointer value passed to 'Unmarshal' or 'Decode'.
# https://staticcheck.dev/docs/checks/#SA1014
- SA1014
# Using 'time.Tick' in a way that will leak. Consider using 'time.NewTicker', and only use 'time.Tick' in tests, commands and endless functions.
# https://staticcheck.dev/docs/checks/#SA1015
- SA1015
# Trapping a signal that cannot be trapped.
# https://staticcheck.dev/docs/checks/#SA1016
- SA1016
# Channels used with 'os/signal.Notify' should be buffered.
# https://staticcheck.dev/docs/checks/#SA1017
- SA1017
# 'strings.Replace' called with 'n == 0', which does nothing.
# https://staticcheck.dev/docs/checks/#SA1018
- SA1018
# Using a deprecated function, variable, constant or field.
# https://staticcheck.dev/docs/checks/#SA1019
- SA1019
# Using an invalid host:port pair with a 'net.Listen'-related function.
# https://staticcheck.dev/docs/checks/#SA1020
- SA1020
# Using 'bytes.Equal' to compare two 'net.IP'.
# https://staticcheck.dev/docs/checks/#SA1021
- SA1021
# Modifying the buffer in an 'io.Writer' implementation.
# https://staticcheck.dev/docs/checks/#SA1023
- SA1023
# A string cutset contains duplicate characters.
# https://staticcheck.dev/docs/checks/#SA1024
- SA1024
# It is not possible to use '(*time.Timer).Reset''s return value correctly.
# https://staticcheck.dev/docs/checks/#SA1025
- SA1025
# Cannot marshal channels or functions.
# https://staticcheck.dev/docs/checks/#SA1026
- SA1026
# Atomic access to 64-bit variable must be 64-bit aligned.
# https://staticcheck.dev/docs/checks/#SA1027
- SA1027
# 'sort.Slice' can only be used on slices.
# https://staticcheck.dev/docs/checks/#SA1028
- SA1028
# Inappropriate key in call to 'context.WithValue'.
# https://staticcheck.dev/docs/checks/#SA1029
- SA1029
# Invalid argument in call to a 'strconv' function.
# https://staticcheck.dev/docs/checks/#SA1030
- SA1030
# Overlapping byte slices passed to an encoder.
# https://staticcheck.dev/docs/checks/#SA1031
- SA1031
# Wrong order of arguments to 'errors.Is'.
# https://staticcheck.dev/docs/checks/#SA1032
- SA1032
# 'sync.WaitGroup.Add' called inside the goroutine, leading to a race condition.
# https://staticcheck.dev/docs/checks/#SA2000
- SA2000
# Empty critical section, did you mean to defer the unlock?.
# https://staticcheck.dev/docs/checks/#SA2001
- SA2001
# Called 'testing.T.FailNow' or 'SkipNow' in a goroutine, which isn't allowed.
# https://staticcheck.dev/docs/checks/#SA2002
- SA2002
# Deferred 'Lock' right after locking, likely meant to defer 'Unlock' instead.
# https://staticcheck.dev/docs/checks/#SA2003
- SA2003
# 'TestMain' doesn't call 'os.Exit', hiding test failures.
# https://staticcheck.dev/docs/checks/#SA3000
- SA3000
# Assigning to 'b.N' in benchmarks distorts the results.
# https://staticcheck.dev/docs/checks/#SA3001
- SA3001
# Binary operator has identical expressions on both sides.
# https://staticcheck.dev/docs/checks/#SA4000
- SA4000
# '&*x' gets simplified to 'x', it does not copy 'x'.
# https://staticcheck.dev/docs/checks/#SA4001
- SA4001
# Comparing unsigned values against negative values is pointless.
# https://staticcheck.dev/docs/checks/#SA4003
- SA4003
# The loop exits unconditionally after one iteration.
# https://staticcheck.dev/docs/checks/#SA4004
- SA4004
# Field assignment that will never be observed. Did you mean to use a pointer receiver?.
# https://staticcheck.dev/docs/checks/#SA4005
- SA4005
# A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?.
# https://staticcheck.dev/docs/checks/#SA4006
- SA4006
# The variable in the loop condition never changes, are you incrementing the wrong variable?.
# https://staticcheck.dev/docs/checks/#SA4008
- SA4008
# A function argument is overwritten before its first use.
# https://staticcheck.dev/docs/checks/#SA4009
- SA4009
# The result of 'append' will never be observed anywhere.
# https://staticcheck.dev/docs/checks/#SA4010
- SA4010
# Break statement with no effect. Did you mean to break out of an outer loop?.
# https://staticcheck.dev/docs/checks/#SA4011
- SA4011
# Comparing a value against NaN even though no value is equal to NaN.
# https://staticcheck.dev/docs/checks/#SA4012
- SA4012
# Negating a boolean twice ('!!b') is the same as writing 'b'. This is either redundant, or a typo.
# https://staticcheck.dev/docs/checks/#SA4013
- SA4013
# An if/else if chain has repeated conditions and no side-effects; if the condition didn't match the first time, it won't match the second time, either.
# https://staticcheck.dev/docs/checks/#SA4014
- SA4014
# Calling functions like 'math.Ceil' on floats converted from integers doesn't do anything useful.
# https://staticcheck.dev/docs/checks/#SA4015
- SA4015
# Certain bitwise operations, such as 'x ^ 0', do not do anything useful.
# https://staticcheck.dev/docs/checks/#SA4016
- SA4016
# Discarding the return values of a function without side effects, making the call pointless.
# https://staticcheck.dev/docs/checks/#SA4017
- SA4017
# Self-assignment of variables.
# https://staticcheck.dev/docs/checks/#SA4018
- SA4018
# Multiple, identical build constraints in the same file.
# https://staticcheck.dev/docs/checks/#SA4019
- SA4019
# Unreachable case clause in a type switch.
# https://staticcheck.dev/docs/checks/#SA4020
- SA4020
# "x = append(y)" is equivalent to "x = y".
# https://staticcheck.dev/docs/checks/#SA4021
- SA4021
# Comparing the address of a variable against nil.
# https://staticcheck.dev/docs/checks/#SA4022
- SA4022
# Impossible comparison of interface value with untyped nil.
# https://staticcheck.dev/docs/checks/#SA4023
- SA4023
# Checking for impossible return value from a builtin function.
# https://staticcheck.dev/docs/checks/#SA4024
- SA4024
# Integer division of literals that results in zero.
# https://staticcheck.dev/docs/checks/#SA4025
- SA4025
# Go constants cannot express negative zero.
# https://staticcheck.dev/docs/checks/#SA4026
- SA4026
# '(*net/url.URL).Query' returns a copy, modifying it doesn't change the URL.
# https://staticcheck.dev/docs/checks/#SA4027
- SA4027
# 'x % 1' is always zero.
# https://staticcheck.dev/docs/checks/#SA4028
- SA4028
# Ineffective attempt at sorting slice.
# https://staticcheck.dev/docs/checks/#SA4029
- SA4029
# Ineffective attempt at generating random number.
# https://staticcheck.dev/docs/checks/#SA4030
- SA4030
# Checking never-nil value against nil.
# https://staticcheck.dev/docs/checks/#SA4031
- SA4031
# Comparing 'runtime.GOOS' or 'runtime.GOARCH' against impossible value.
# https://staticcheck.dev/docs/checks/#SA4032
- SA4032
# Assignment to nil map.
# https://staticcheck.dev/docs/checks/#SA5000
- SA5000
# Deferring 'Close' before checking for a possible error.
# https://staticcheck.dev/docs/checks/#SA5001
- SA5001
# The empty for loop ("for {}") spins and can block the scheduler.
# https://staticcheck.dev/docs/checks/#SA5002
- SA5002
# Defers in infinite loops will never execute.
# https://staticcheck.dev/docs/checks/#SA5003
- SA5003
# "for { select { ..." with an empty default branch spins.
# https://staticcheck.dev/docs/checks/#SA5004
- SA5004
# The finalizer references the finalized object, preventing garbage collection.
# https://staticcheck.dev/docs/checks/#SA5005
- SA5005
# Infinite recursive call.
# https://staticcheck.dev/docs/checks/#SA5007
- SA5007
# Invalid struct tag.
# https://staticcheck.dev/docs/checks/#SA5008
- SA5008
# Invalid Printf call.
# https://staticcheck.dev/docs/checks/#SA5009
- SA5009
# Impossible type assertion.
# https://staticcheck.dev/docs/checks/#SA5010
- SA5010
# Possible nil pointer dereference.
# https://staticcheck.dev/docs/checks/#SA5011
- SA5011
# Passing odd-sized slice to function expecting even size.
# https://staticcheck.dev/docs/checks/#SA5012
- SA5012
# Using 'regexp.Match' or related in a loop, should use 'regexp.Compile'.
# https://staticcheck.dev/docs/checks/#SA6000
- SA6000
# Missing an optimization opportunity when indexing maps by byte slices.
# https://staticcheck.dev/docs/checks/#SA6001
- SA6001
# Storing non-pointer values in 'sync.Pool' allocates memory.
# https://staticcheck.dev/docs/checks/#SA6002
- SA6002
# Converting a string to a slice of runes before ranging over it.
# https://staticcheck.dev/docs/checks/#SA6003
- SA6003
# Inefficient string comparison with 'strings.ToLower' or 'strings.ToUpper'.
# https://staticcheck.dev/docs/checks/#SA6005
- SA6005
# Using io.WriteString to write '[]byte'.
# https://staticcheck.dev/docs/checks/#SA6006
- SA6006
# Defers in range loops may not run when you expect them to.
# https://staticcheck.dev/docs/checks/#SA9001
- SA9001
# Using a non-octal 'os.FileMode' that looks like it was meant to be in octal.
# https://staticcheck.dev/docs/checks/#SA9002
- SA9002
# Empty body in an if or else branch.
# https://staticcheck.dev/docs/checks/#SA9003
- SA9003
# Only the first constant has an explicit type.
# https://staticcheck.dev/docs/checks/#SA9004
- SA9004
# Trying to marshal a struct with no public fields nor custom marshaling.
# https://staticcheck.dev/docs/checks/#SA9005
- SA9005
# Dubious bit shifting of a fixed size integer value.
# https://staticcheck.dev/docs/checks/#SA9006
- SA9006
# Deleting a directory that shouldn't be deleted.
# https://staticcheck.dev/docs/checks/#SA9007
- SA9007
# 'else' branch of a type assertion is probably not reading the right value.
# https://staticcheck.dev/docs/checks/#SA9008
- SA9008
# Ineffectual Go compiler directive.
# https://staticcheck.dev/docs/checks/#SA9009
- SA9009
# Incorrect or missing package comment.
# https://staticcheck.dev/docs/checks/#ST1000
- ST1000
# Dot imports are discouraged.
# https://staticcheck.dev/docs/checks/#ST1001
- ST1001
# Poorly chosen identifier.
# https://staticcheck.dev/docs/checks/#ST1003
- ST1003
# Incorrectly formatted error string.
# https://staticcheck.dev/docs/checks/#ST1005
- ST1005
# Poorly chosen receiver name.
# https://staticcheck.dev/docs/checks/#ST1006
- ST1006
# A function's error value should be its last return value.
# https://staticcheck.dev/docs/checks/#ST1008
- ST1008
# Poorly chosen name for variable of type 'time.Duration'.
# https://staticcheck.dev/docs/checks/#ST1011
- ST1011
# Poorly chosen name for error variable.
# https://staticcheck.dev/docs/checks/#ST1012
- ST1012
# Should use constants for HTTP error codes, not magic numbers.
# https://staticcheck.dev/docs/checks/#ST1013
- ST1013
# A switch's default case should be the first or last case.
# https://staticcheck.dev/docs/checks/#ST1015
- ST1015
# Use consistent method receiver names.
# https://staticcheck.dev/docs/checks/#ST1016
- ST1016
# Don't use Yoda conditions.
# https://staticcheck.dev/docs/checks/#ST1017
- ST1017
# Avoid zero-width and control characters in string literals.
# https://staticcheck.dev/docs/checks/#ST1018
- ST1018
# Importing the same package multiple times.
# https://staticcheck.dev/docs/checks/#ST1019
- ST1019
# The documentation of an exported function should start with the function's name.
# https://staticcheck.dev/docs/checks/#ST1020
- ST1020
# The documentation of an exported type should start with type's name.
# https://staticcheck.dev/docs/checks/#ST1021
- ST1021
# The documentation of an exported variable or constant should start with variable's name.
# https://staticcheck.dev/docs/checks/#ST1022
- ST1022
# Redundant type in variable declaration.
# https://staticcheck.dev/docs/checks/#ST1023
- ST1023
# Use plain channel send or receive instead of single-case select.
# https://staticcheck.dev/docs/checks/#S1000
- S1000
# Replace for loop with call to copy.
# https://staticcheck.dev/docs/checks/#S1001
- S1001
# Omit comparison with boolean constant.
# https://staticcheck.dev/docs/checks/#S1002
- S1002
# Replace call to 'strings.Index' with 'strings.Contains'.
# https://staticcheck.dev/docs/checks/#S1003
- S1003
# Replace call to 'bytes.Compare' with 'bytes.Equal'.
# https://staticcheck.dev/docs/checks/#S1004
- S1004
# Drop unnecessary use of the blank identifier.
# https://staticcheck.dev/docs/checks/#S1005
- S1005
# Use "for { ... }" for infinite loops.
# https://staticcheck.dev/docs/checks/#S1006
- S1006
# Simplify regular expression by using raw string literal.
# https://staticcheck.dev/docs/checks/#S1007
- S1007
# Simplify returning boolean expression.
# https://staticcheck.dev/docs/checks/#S1008
- S1008
# Omit redundant nil check on slices, maps, and channels.
# https://staticcheck.dev/docs/checks/#S1009
- S1009
# Omit default slice index.
# https://staticcheck.dev/docs/checks/#S1010
- S1010
# Use a single 'append' to concatenate two slices.
# https://staticcheck.dev/docs/checks/#S1011
- S1011
# Replace 'time.Now().Sub(x)' with 'time.Since(x)'.
# https://staticcheck.dev/docs/checks/#S1012
- S1012
# Use a type conversion instead of manually copying struct fields.
# https://staticcheck.dev/docs/checks/#S1016
- S1016
# Replace manual trimming with 'strings.TrimPrefix'.
# https://staticcheck.dev/docs/checks/#S1017
- S1017
# Use "copy" for sliding elements.
# https://staticcheck.dev/docs/checks/#S1018
- S1018
# Simplify "make" call by omitting redundant arguments.
# https://staticcheck.dev/docs/checks/#S1019
- S1019
# Omit redundant nil check in type assertion.
# https://staticcheck.dev/docs/checks/#S1020
- S1020
# Merge variable declaration and assignment.
# https://staticcheck.dev/docs/checks/#S1021
- S1021
# Omit redundant control flow.
# https://staticcheck.dev/docs/checks/#S1023
- S1023
# Replace 'x.Sub(time.Now())' with 'time.Until(x)'.
# https://staticcheck.dev/docs/checks/#S1024
- S1024
# Don't use 'fmt.Sprintf("%s", x)' unnecessarily.
# https://staticcheck.dev/docs/checks/#S1025
- S1025
# Simplify error construction with 'fmt.Errorf'.
# https://staticcheck.dev/docs/checks/#S1028
- S1028
# Range over the string directly.
# https://staticcheck.dev/docs/checks/#S1029
- S1029
# Use 'bytes.Buffer.String' or 'bytes.Buffer.Bytes'.
# https://staticcheck.dev/docs/checks/#S1030
- S1030
# Omit redundant nil check around loop.
# https://staticcheck.dev/docs/checks/#S1031
- S1031
# Use 'sort.Ints(x)', 'sort.Float64s(x)', and 'sort.Strings(x)'.
# https://staticcheck.dev/docs/checks/#S1032
- S1032
# Unnecessary guard around call to "delete".
# https://staticcheck.dev/docs/checks/#S1033
- S1033
# Use result of type assertion to simplify cases.
# https://staticcheck.dev/docs/checks/#S1034
- S1034
# Redundant call to 'net/http.CanonicalHeaderKey' in method call on 'net/http.Header'.
# https://staticcheck.dev/docs/checks/#S1035
- S1035
# Unnecessary guard around map access.
# https://staticcheck.dev/docs/checks/#S1036
- S1036
# Elaborate way of sleeping.
# https://staticcheck.dev/docs/checks/#S1037
- S1037
# Unnecessarily complex way of printing formatted string.
# https://staticcheck.dev/docs/checks/#S1038
- S1038
# Unnecessary use of 'fmt.Sprint'.
# https://staticcheck.dev/docs/checks/#S1039
- S1039
# Type assertion to current type.
# https://staticcheck.dev/docs/checks/#S1040
- S1040
# Apply De Morgan's law.
# https://staticcheck.dev/docs/checks/#QF1001
- QF1001
# Convert untagged switch to tagged switch.
# https://staticcheck.dev/docs/checks/#QF1002
- QF1002
# Convert if/else-if chain to tagged switch.
# https://staticcheck.dev/docs/checks/#QF1003
- QF1003
# Use 'strings.ReplaceAll' instead of 'strings.Replace' with 'n == -1'.
# https://staticcheck.dev/docs/checks/#QF1004
- QF1004
# Expand call to 'math.Pow'.
# https://staticcheck.dev/docs/checks/#QF1005
- QF1005
# Lift 'if'+'break' into loop condition.
# https://staticcheck.dev/docs/checks/#QF1006
- QF1006
# Merge conditional assignment into variable declaration.
# https://staticcheck.dev/docs/checks/#QF1007
- QF1007
# Omit embedded fields from selector expression.
# https://staticcheck.dev/docs/checks/#QF1008
- QF1008
# Use 'time.Time.Equal' instead of '==' operator.
# https://staticcheck.dev/docs/checks/#QF1009
- QF1009
# Convert slice of bytes to string when printing it.
# https://staticcheck.dev/docs/checks/#QF1010
- QF1010
# Omit redundant type from variable declaration.
# https://staticcheck.dev/docs/checks/#QF1011
- QF1011
# Use 'fmt.Fprintf(x, ...)' instead of 'x.Write(fmt.Sprintf(...))'.
# https://staticcheck.dev/docs/checks/#QF1012
- QF1012
tagalign:
# Align and sort can be used together or separately.
#
# Whether enable align. If true, the struct tags will be aligned.
# E.g.:
# type FooBar struct {
# Bar string `json:"bar" validate:"required"`
# FooFoo int8 `json:"foo_foo" validate:"required"`
# }
# will be formatted to:
# type FooBar struct {
# Bar string `json:"bar" validate:"required"`
# FooFoo int8 `json:"foo_foo" validate:"required"`
# }
# Default: true.
align: false
# Whether enable tags sort.
# If true, the tags will be sorted by name in ascending order.
# E.g.: `xml:"bar" json:"bar" validate:"required"` -> `json:"bar" validate:"required" xml:"bar"`.
# Default: true
sort: false
# Specify the order of tags, the other tags will be sorted by name.
# This option will be ignored if `sort` is false.
# Default: []
order:
- json
- yaml
- yml
- toml
- mapstructure
- binding
- validate
# Whether enable strict style.
# In this style, the tags will be sorted and aligned in the dictionary order,
# and the tags with the same name will be aligned together.
# Note: This option will be ignored if 'align' or 'sort' is false.
# Default: false
strict: true
tagliatelle:
# Checks the struct tag name case.
case:
# Defines the association between tag name and case.
# Any struct tag name can be used.
# Supported string cases:
# - `camel`
# - `pascal`
# - `kebab`
# - `snake`
# - `upperSnake`
# - `goCamel`
# - `goPascal`
# - `goKebab`
# - `goSnake`
# - `upper`
# - `lower`
# - `header`
rules:
json: camel
yaml: camel
xml: camel
toml: camel
bson: camel
avro: snake
mapstructure: kebab
env: upperSnake
envconfig: upperSnake
whatever: snake
# Defines the association between tag name and case.
# Important: the `extended-rules` overrides `rules`.
# Default: empty
extended-rules:
json:
# Supported string cases:
# - `camel`
# - `pascal`
# - `kebab`
# - `snake`
# - `upperSnake`
# - `goCamel`
# - `goPascal`
# - `goKebab`
# - `goSnake`
# - `header`
# - `lower`
# - `header`
#
# Required
case: camel
# Adds 'AMQP', 'DB', 'GID', 'RTP', 'SIP', 'TS' to initialisms,
# and removes 'LHS', 'RHS' from initialisms.
# Default: false
extra-initialisms: true
# Defines initialism additions and overrides.
# Default: empty
initialism-overrides:
DB: true # add a new initialism
LHS: false # disable a default initialism.
# ...
# Uses the struct field name to check the name of the struct tag.
# Default: false
use-field-name: true
# The field names to ignore.
# Default: []
ignored-fields:
- Bar
- Foo
# Overrides the default/root configuration.
# Default: []
overrides:
-
# The package path (uses `/` only as a separator).
# Required
pkg: foo/bar
# Default: empty or the same as the default/root configuration.
rules:
json: snake
xml: pascal
# Default: empty or the same as the default/root configuration.
extended-rules:
# Same options as the base `extended-rules`.
# Default: false (WARNING: it doesn't follow the default/root configuration)
use-field-name: true
# The field names to ignore.
# Default: [] or the same as the default/root configuration.
ignored-fields:
- Bar
- Foo
# Ignore the package (takes precedence over all other configurations).
# Default: false
ignore: true
testifylint:
# Enable all checkers (https://github.com/Antonboom/testifylint#checkers).
# Default: false
enable-all: true
# Disable checkers by name
# (in addition to default
# suite-thelper
# ).
disable:
- blank-import
- bool-compare
- compares
- contains
- empty
- encoded-compare
- equal-values
- error-is-as
- error-nil
- expected-actual
- float-compare
- formatter
- go-require
- len
- negative-positive
- nil-compare
- regexp
- require-error
- suite-broken-parallel
- suite-dont-use-pkg
- suite-extra-assert-call
- suite-method-signature
- suite-subtest-run
- suite-thelper
- useless-assert
# Disable all checkers (https://github.com/Antonboom/testifylint#checkers).
# Default: false
disable-all: true
# Enable checkers by name
# (in addition to default
# blank-import, bool-compare, compares, contains, empty, encoded-compare, equal-values, error-is-as, error-nil,
# expected-actual, go-require, float-compare, formatter, len, negative-positive, nil-compare, regexp, require-error,
# suite-broken-parallel, suite-dont-use-pkg, suite-extra-assert-call, suite-subtest-run, suite-method-signature,
# useless-assert
# ).
enable:
- blank-import
- bool-compare
- compares
- contains
- empty
- encoded-compare
- equal-values
- error-is-as
- error-nil
- expected-actual
- float-compare
- formatter
- go-require
- len
- negative-positive
- nil-compare
- regexp
- require-error
- suite-broken-parallel
- suite-dont-use-pkg
- suite-extra-assert-call
- suite-method-signature
- suite-subtest-run
- suite-thelper
- useless-assert
bool-compare:
# To ignore user defined types (over builtin bool).
# Default: false
ignore-custom-types: true
expected-actual:
# Regexp for expected variable name.
# Default: (^(exp(ected)?|want(ed)?)([A-Z]\w*)?$)|(^(\w*[a-z])?(Exp(ected)?|Want(ed)?)$)
pattern: ^expected
formatter:
# To enable go vet's printf checks.
# Default: true
check-format-string: false
# To require f-assertions (e.g. `assert.Equalf`) if format string is used, even if there are no variable-length
# variables, i.e. it requires `require.NoErrorf` for both these cases:
# - require.NoErrorf(t, err, "unexpected error")
# - require.NoErrorf(t, err, "unexpected error for sid: %v", sid)
# To understand this behavior, please read the
# https://github.com/Antonboom/testifylint?tab=readme-ov-file#historical-reference-of-formatter.
# Default: false
require-f-funcs: true
# To require that the first element of msgAndArgs (msg) has a string type.
# For example, in such case assertion like `assert.True(t, b, tt.case)` will be considered as invalid.
# Default: true
require-string-msg: false
go-require:
# To ignore HTTP handlers (like http.HandlerFunc).
# Default: false
ignore-http-handlers: true
require-error:
# Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.
# Default: ""
fn-pattern: ^(Errorf?|NoErrorf?)$
suite-extra-assert-call:
# To require or remove extra Assert() call?
# Default: remove
mode: require
testpackage:
# Regexp pattern to skip files.
# Default: "(export|internal)_test\\.go"
skip-regexp: (export|internal)_test\.go
# List of packages that don't end with _test that tests are allowed to be in.
# Default: "main"
allow-packages:
- example
- main
thelper:
test:
# Check *testing.T is first param (or after context.Context) of helper function.
# Default: true
first: false
# Check *testing.T param has name t.
# Default: true
name: false
# Check t.Helper() begins helper function.
# Default: true
begin: false
benchmark:
# Check *testing.B is first param (or after context.Context) of helper function.
# Default: true
first: false
# Check *testing.B param has name b.
# Default: true
name: false
# Check b.Helper() begins helper function.
# Default: true
begin: false
tb:
# Check *testing.TB is first param (or after context.Context) of helper function.
# Default: true
first: false
# Check *testing.TB param has name tb.
# Default: true
name: false
# Check tb.Helper() begins helper function.
# Default: true
begin: false
fuzz:
# Check *testing.F is first param (or after context.Context) of helper function.
# Default: true
first: false
# Check *testing.F param has name f.
# Default: true
name: false
# Check f.Helper() begins helper function.
# Default: true
begin: false
usestdlibvars:
# Suggest the use of http.MethodXX.
# Default: true
http-method: false
# Suggest the use of http.StatusXX.
# Default: true
http-status-code: false
# Suggest the use of time.Month in time.Date.
# Default: false
time-date-month: true
# Suggest the use of time.Weekday.String().
# Default: true
time-weekday: true
# Suggest the use of time.Month.String().
# Default: false
time-month: true
# Suggest the use of time.Layout.
# Default: false
time-layout: true
# Suggest the use of crypto.Hash.String().
# Default: false
crypto-hash: true
# Suggest the use of rpc.DefaultXXPath.
# Default: false
default-rpc-path: true
# Suggest the use of sql.LevelXX.String().
# Default: false
sql-isolation-level: true
# Suggest the use of tls.SignatureScheme.String().
# Default: false
tls-signature-scheme: true
# Suggest the use of constant.Kind.String().
# Default: false
constant-kind: true
usetesting:
# Enable/disable `os.CreateTemp("", ...)` detections.
# Default: true
os-create-temp: false
# Enable/disable `os.MkdirTemp()` detections.
# Default: true
os-mkdir-temp: false
# Enable/disable `os.Setenv()` detections.
# Default: true
os-setenv: false
# Enable/disable `os.TempDir()` detections.
# Default: false
os-temp-dir: true
# Enable/disable `os.Chdir()` detections.
# Disabled if Go < 1.24.
# Default: true
os-chdir: false
# Enable/disable `context.Background()` detections.
# Disabled if Go < 1.24.
# Default: false
context-background: true
# Enable/disable `context.TODO()` detections.
# Disabled if Go < 1.24.
# Default: false
context-todo: true
unconvert:
# Remove conversions that force intermediate rounding.
# Default: false
fast-math: true
# Be more conservative (experimental).
# Default: false
safe: true
unparam:
# Inspect exported functions.
# Set to true if no external program/library imports your code.
#
# IMPORTANT: If you enable this setting, unparam reports many false positives in text editors:
# when run on a subdirectory it cannot find external interfaces.
# Most editor integrations invoke golangci-lint on the directory containing the changed file.
#
# Default: false
check-exported: true
unqueryvet:
# Enable SQL builder checking.
# Default: true
check-sql-builders: false
# Enable aliased wildcard detection like `SELECT t.*`.
# Default: true
check-aliased-wildcard: false
# Enable string concatenation analysis.
# Default: true
check-string-concat: false
# Enable format string analysis like `fmt.Sprintf`.
# Default: true
check-format-strings: false
# Enable strings.Builder analysis.
# Default: true
check-string-builder: false
# Enable subquery analysis.
# Default: true
check-subqueries: false
# Detects N+1 Query.
# Default: false
check-n1: true
# Detects SQL injection.
# Default: false
check-sql-injection: true
# Detects transaction leaks.
# Default: false
check-tx-leaks: true
# Regex patterns for acceptable `SELECT *` usage.
# Default:
# - "SELECT \\* FROM information_schema\\..*"
# - "SELECT \\* FROM pg_catalog\\..*"
# - "SELECT COUNT\\(\\*\\)"
# - "SELECT MAX\\(\\*\\)"
# - "SELECT MIN\\(\\*\\)"
allowed-patterns:
- "SELECT \\* FROM temp_.*"
- "SELECT \\* FROM.*-- migration"
# Allow is a list of SQL patterns to allow (whitelist).
# Default: []
allow:
- foo
# Functions to ignore (regex patterns)
# Default: []
ignored-functions:
- "debug\\..*"
- "test.*"
# SQL builder libraries to check.
# Default: all true.
sql-builders:
squirrel: false
gorm: false
sqlx: false
ent: false
pgx: false
bun: false
sqlboiler: false
jet: false
# List of user-defined DSL rules.
# https://github.com/MirrexOne/unqueryvet?tab=readme-ov-file#custom-rules-dsl
# Default: []
custom-rules:
- id: allow-temp-tables
pattern: "SELECT * FROM $TABLE"
when: "isTempTable(table)"
action: allow
- id: dangerous-delete
pattern: "DELETE FROM $TABLE"
when: "!has_where"
message: "DELETE without WHERE clause"
unused:
# Mark all struct fields that have been written to as used.
# Default: true
field-writes-are-uses: false
# Treat IncDec statement (e.g. `i++` or `i--`) as both read and write operation instead of just write.
# Default: false
post-statements-are-reads: true
# Mark all exported fields as used.
# default: true
exported-fields-are-used: false
# Mark all function parameters as used.
# default: true
parameters-are-used: false
# Mark all local variables as used.
# default: true
local-variables-are-used: false
# Mark all identifiers inside generated files as used.
# Default: true
generated-is-used: false
varnamelen:
# The longest distance, in source lines, that is being considered a "small scope".
# Variables used in at most this many lines will be ignored.
# Default: 5
max-distance: 6
# The minimum length of a variable's name that is considered "long".
# Variable names that are at least this long will be ignored.
# Default: 3
min-name-length: 2
# Check method receivers.
# Default: false
check-receiver: true
# Check named return values.
# Default: false
check-return: true
# Check type parameters.
# Default: false
check-type-param: true
# Ignore "ok" variables that hold the bool return value of a type assertion.
# Default: false
ignore-type-assert-ok: true
# Ignore "ok" variables that hold the bool return value of a map index.
# Default: false
ignore-map-index-ok: true
# Ignore "ok" variables that hold the bool return value of a channel receive.
# Default: false
ignore-chan-recv-ok: true
# Optional list of variable names that should be ignored completely.
# Default: []
ignore-names:
- err
# Optional list of variable declarations that should be ignored completely.
# Entries must be in one of the following forms (see below for examples):
# - for variables, parameters, named return values, method receivers, or type parameters:
# ( can also be a pointer/slice/map/chan/...)
# - for constants: const
#
# Default: []
ignore-decls:
- c echo.Context
- t testing.T
- f *foo.Bar
- e error
- i int
- const C
- T any
- m map[string]int
whitespace:
# Enforces newlines (or comments) after every multi-line if statement.
# Default: false
multi-if: true
# Enforces newlines (or comments) after every multi-line function signature.
# Default: false
multi-func: true
wrapcheck:
# An array of strings specifying additional substrings of signatures to ignore.
# Unlike 'ignore-sigs', this option extends the default set (or the set specified in 'ignore-sigs') without replacing it entirely.
# This allows you to add specific signatures to the ignore list
# while retaining the defaults or any items in 'ignore-sigs'.
# Default: []
extra-ignore-sigs:
- .CustomError(
- .SpecificWrap(
# An array of strings that specify substrings of signatures to ignore.
# If this set, it will override the default set of ignored signatures.
# See https://github.com/tomarrell/wrapcheck#configuration for more information.
# Default: [".Errorf(", "errors.New(", "errors.Unwrap(", "errors.Join(", ".Wrap(", ".Wrapf(", ".WithMessage(", ".WithMessagef(", ".WithStack("]
ignore-sigs:
- .Errorf(
- errors.New(
- errors.Unwrap(
- errors.Join(
- .Wrap(
- .Wrapf(
- .WithMessage(
- .WithMessagef(
- .WithStack(
# An array of strings that specify regular expressions of signatures to ignore.
# Default: []
ignore-sig-regexps:
- \.New.*Error\(
# An array of strings that specify globs of packages to ignore.
# Default: []
ignore-package-globs:
- encoding/*
- github.com/pkg/*
# An array of strings that specify regular expressions of interfaces to ignore.
# Default: []
ignore-interface-regexps:
- ^(?i)c(?-i)ach(ing|e)
# Determines whether wrapcheck should report errors returned from inside the package.
# Default: false
report-internal-errors: true
wsl:
# Do strict checking when assigning from append (x = append(x, y)).
# If this is set to true - the append call must append either a variable
# assigned, called or used on the line above.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#strict-append
# Default: true
strict-append: false
# Allows assignments to be cuddled with variables used in calls on
# line above and calls to be cuddled with assignments of variables
# used in call on line above.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-assign-and-call
# Default: true
allow-assign-and-call: false
# Allows assignments to be cuddled with anything.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-assign-and-anything
# Default: false
allow-assign-and-anything: true
# Allows cuddling to assignments even if they span over multiple lines.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-multiline-assign
# Default: true
allow-multiline-assign: false
# If the number of lines in a case block is equal to or lager than this number,
# the case *must* end white a newline.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-case-trailing-whitespace
# Default: 0
force-case-trailing-whitespace: 1
# Allow blocks to end with comments.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-trailing-comment
# Default: false
allow-trailing-comment: true
# Allow multiple comments in the beginning of a block separated with newline.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-separated-leading-comment
# Default: false
allow-separated-leading-comment: true
# Allow multiple var/declaration statements to be cuddled.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-cuddle-declarations
# Default: false
allow-cuddle-declarations: true
# A list of call idents that everything can be cuddled with.
# Defaults: [ "Lock", "RLock" ]
allow-cuddle-with-calls: [ "Foo", "Bar" ]
# AllowCuddleWithRHS is a list of right hand side variables that is allowed
# to be cuddled with anything.
# Defaults: [ "Unlock", "RUnlock" ]
allow-cuddle-with-rhs: [ "Foo", "Bar" ]
# Allow cuddling with any block as long as the variable is used somewhere in
# the block.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-cuddle-used-in-block
# Default: false
allow-cuddle-used-in-block: true
# Causes an error when an If statement that checks an error variable doesn't
# cuddle with the assignment of that variable.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-err-cuddling
# Default: false
force-err-cuddling: true
# When force-err-cuddling is enabled this is a list of names
# used for error variables to check for in the conditional.
# Default: [ "err" ]
error-variable-names: [ "foo" ]
# Causes an error if a short declaration (:=) cuddles with anything other than
# another short declaration.
# This logic overrides force-err-cuddling among others.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-short-decl-cuddling
# Default: false
force-short-decl-cuddling: true
wsl_v5:
# Allow cuddling a variable if it's used first in the immediate following block,
# even if the statement with the block doesn't use the variable.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration
# Default: true
allow-first-in-block: false
# Same as above,
# but allows cuddling if the variable is used anywhere in the following (or nested) block.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration
# Default: false
allow-whole-block: true
# If a block contains more than this number of lines,
# the branch statement needs to be separated by whitespace.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration
# Default: 2
branch-max-lines: 4
# If set to a non-negative number,
# case blocks need to end with whitespace if exceeding this number
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration
# Default: 0
case-max-lines: 2
# Default checks to use.
# Can be `all`, `none`, `default` or empty.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration
# Default: ""
default: all
# Enabled checks.
# Will be additive to any presets.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration
# Default: []
enable:
- assign
- branch
- decl
- defer
- expr
- for
- go
- if
- inc-dec
- label
- range
- return
- select
- send
- switch
- type-switch
- append
- assign-exclusive
- assign-expr
- err
- leading-whitespace
- trailing-whitespace
- after-block
# Disable checks.
# Will be subtractive to any preset.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration
# Default: []
disable:
- assign
- branch
- decl
- defer
- expr
- for
- go
- if
- inc-dec
- label
- range
- return
- select
- send
- switch
- type-switch
- append
- assign-exclusive
- assign-expr
- err
- leading-whitespace
- trailing-whitespace
- after-block
# The custom section can be used to define linter plugins to be loaded at runtime.
# See README documentation for more info.
custom:
# Each custom linter should have a unique name.
example:
# The plugin type.
# It can be `goplugin` or `module`.
# Default: goplugin
type: module
# The path to the plugin *.so. Can be absolute or local.
# Required for each custom linter.
path: /path/to/example.so
# The description of the linter.
# Optional.
description: This is an example usage of a plugin linter.
# Intended to point to the repo location of the linter.
# Optional.
original-url: github.com/golangci/example-linter
# Plugins settings/configuration.
# Only work with plugin based on `linterdb.PluginConstructor`.
# Optional.
settings:
foo: bar
# Defines a set of rules to ignore issues.
# It does not skip the analysis, and so does not ignore "typecheck" errors.
exclusions:
# Mode of the generated files analysis.
#
# - `strict`: sources are excluded by strictly following the Go generated file convention.
# Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\.$`
# This line must appear before the first non-comment, non-blank text in the file.
# https://go.dev/s/generatedcode
# - `lax`: sources are excluded if they contain lines like `autogenerated file`, `code generated`, `do not edit`, etc.
# - `disable`: disable the generated files exclusion.
#
# Default: strict
generated: lax
# Log a warning if an exclusion rule is unused.
# Default: false
warn-unused: true
# Predefined exclusion rules.
# Default: []
presets:
- comments
- std-error-handling
- common-false-positives
- legacy
# Excluding configuration per-path, per-linter, per-text and per-source.
rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
# Run some linter only for test files by excluding its issues for everything else.
- path-except: _test\.go
linters:
- forbidigo
# Exclude known linters from partially hard-vendored code,
# which is impossible to exclude via `nolint` comments.
# `/` will be replaced by the current OS file path separator to properly work on Windows.
- path: internal/hmac/
text: "weak cryptographic primitive"
linters:
- gosec
# Exclude some `staticcheck` messages.
- linters:
- staticcheck
text: "SA9003:"
# Exclude `lll` issues for long lines with `go:generate`.
- linters:
- lll
source: "^//go:generate "
# Which file paths to exclude: they will be analyzed, but issues from them won't be reported.
# "/" will be replaced by the current OS file path separator to properly work on Windows.
# Default: []
paths:
- ".*\\.my\\.go$"
- lib/bad.go
# Which file paths to not exclude.
# Default: []
paths-except:
- ".*\\.my\\.go$"
- lib/bad.go
formatters:
# Enable specific formatter.
# Default: [] (uses standard Go formatting)
enable:
- gci
- gofmt
- gofumpt
- goimports
- golines
- swaggo
# Formatters settings.
settings:
gci:
# Section configuration to compare against.
# Section names are case-insensitive and may contain parameters in ().
# The default order of sections is `standard > default > custom > blank > dot > alias > localmodule`.
# If `custom-order` is `true`, it follows the order of `sections` option.
# Default: ["standard", "default"]
sections:
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
- prefix(github.com/org/project) # Custom section: groups all imports with the specified Prefix.
- blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled.
- dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled.
- alias # Alias section: contains all alias imports. This section is not present unless explicitly enabled.
- localmodule # Local module section: contains all local packages. This section is not present unless explicitly enabled.
# Checks that no inline comments are present.
# Default: false
no-inline-comments: true
# Checks that no prefix comments (comment lines above an import) are present.
# Default: false
no-prefix-comments: true
# Enable custom order of sections.
# If `true`, make the section order the same as the order of `sections`.
# Default: false
custom-order: true
# Drops lexical ordering for custom sections.
# Default: false
no-lex-order: true
gofmt:
# Simplify code: gofmt with `-s` option.
# Default: true
simplify: false
# Apply the rewrite rules to the source before reformatting.
# https://pkg.go.dev/cmd/gofmt
# Default: []
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
- pattern: 'a[b:len(a)]'
replacement: 'a[b:]'
gofumpt:
# Module path which contains the source code being formatted.
# Default: ""
module-path: github.com/org/project
# Choose whether to use the extra rules.
# Default: false
extra-rules: true
goimports:
# A list of prefixes, which, if set, checks import paths
# with the given prefixes are grouped after 3rd-party packages.
# Default: []
local-prefixes:
- github.com/org/project
golines:
# Target maximum line length.
# Default: 100
max-len: 200
# Length of a tabulation.
# Default: 4
tab-len: 8
# Shorten single-line comments.
# Default: false
shorten-comments: true
# Default: true
reformat-tags: false
# Split chained methods on the dots as opposed to the arguments.
# Default: true
chain-split-dots: false
exclusions:
# Log a warning if an exclusion path is unused.
# Default: false
warn-unused: true
# Mode of the generated files analysis.
#
# - `strict`: sources are excluded by strictly following the Go generated file convention.
# Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\.$`
# This line must appear before the first non-comment, non-blank text in the file.
# https://go.dev/s/generatedcode
# - `lax`: sources are excluded if they contain lines like `autogenerated file`, `code generated`, `do not edit`, etc.
# - `disable`: disable the generated files exclusion.
#
# Default: lax
generated: strict
# Which file paths to exclude.
# This option is ignored when using `--stdin` as the path is unknown.
# Default: []
paths:
- ".*\\.my\\.go$"
- lib/bad.go
issues:
# Maximum issues count per one linter.
# Set to 0 to disable.
# Default: 50
max-issues-per-linter: 0
# Maximum count of issues with the same text.
# Set to 0 to disable.
# Default: 3
max-same-issues: 0
# Make issues output unique by line.
# Default: true
uniq-by-line: false
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing large codebase.
# It's not practical to fix all existing issues at the moment of integration:
# much better don't allow issues in new code.
#
# Default: false
new: true
# Show only new issues created after the best common ancestor (merge-base against HEAD).
# Default: ""
new-from-merge-base: main
# Show only new issues created after git revision `REV`.
# Default: ""
new-from-rev: HEAD
# Show only new issues created in git patch with set file path.
# Default: ""
new-from-patch: path/to/patch/file
# Show issues in any part of update files (requires new-from-rev or new-from-patch).
# Default: false
whole-files: true
# Apply the fixes detected by the linters and formatters (if it's supported by the linter).
# Default: false
fix: true
# Output configuration options.
output:
# The formats used to render issues.
formats:
# Prints issues in a text format with colors, line number, and linter name.
# This format is the default format.
text:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.txt
# Print linter name in the end of issue text.
# Default: true
print-linter-name: false
# Print lines of code with issue.
# Default: true
print-issued-lines: false
# Use colors.
# Default: true
colors: false
# Prints issues in a JSON representation.
json:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.json
# Prints issues in columns representation separated by tabulations.
tab:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.txt
# Print linter name in the end of issue text.
# Default: true
print-linter-name: true
# Use colors.
# Default: true
colors: false
# Prints issues in an HTML page.
# It uses the Cloudflare CDN (cdnjs) and React.
html:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.html
# Prints issues in the Checkstyle format.
checkstyle:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.xml
# Prints issues in the Code Climate format.
code-climate:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.json
# Prints issues in the JUnit XML format.
junit-xml:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.xml
# Support extra JUnit XML fields.
# Default: false
extended: true
# Prints issues in the TeamCity format.
teamcity:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.txt
# Prints issues in the SARIF format.
sarif:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.json
# Add a prefix to the output file references.
# This option is ignored when using `output.path-mode: abs` mode.
# Default: ""
path-prefix: ""
# By default, the report are related to the path obtained by `run.relative-path-mode`.
# The mode `abs` allows to show absolute file paths instead of relative file paths.
# The option `output.path-prefix` is ignored when using `abs` mode.
# Default: ""
path-mode: "abs"
# Order to use when sorting results.
# Possible values: `file`, `linter`, and `severity`.
#
# If the severity values are inside the following list, they are ordered in this order:
# 1. error
# 2. warning
# 3. high
# 4. medium
# 5. low
# Either they are sorted alphabetically.
#
# Default: ["linter", "file"]
sort-order:
- linter
- severity
- file # filepath, line, and column.
# Show statistics per linter.
# Default: true
show-stats: false
# Options for analysis running.
run:
# Timeout for total work, e.g. 30s, 5m, 5m30s.
# If the value is lower or equal to 0, the timeout is disabled.
# Default: 0 (disabled)
timeout: 5m
# The mode used to evaluate relative paths.
# It's used by exclusions, Go plugins, and some linters.
# The value can be:
# - `gomod`: the paths will be relative to the directory of the `go.mod` file.
# - `gitroot`: the paths will be relative to the git root (the parent directory of `.git`).
# - `cfg`: the paths will be relative to the configuration file.
# - `wd` (NOT recommended): the paths will be relative to the place where golangci-lint is run.
# Default: cfg
relative-path-mode: gomod
# Exit code when at least one issue was found.
# Default: 1
issues-exit-code: 2
# Include test files or not.
# Default: true
tests: false
# List of build tags, all linters use it.
# Default: []
build-tags:
- mytag
# If set, we pass it to "go list -mod={option}". From "go help modules":
# If invoked with -mod=readonly, the go command is disallowed from the implicit
# automatic updating of go.mod described above. Instead, it fails when any changes
# to go.mod are needed. This setting is most useful to check that go.mod does
# not need updates, such as in a continuous integration and testing system.
# If invoked with -mod=vendor, the go command assumes that the vendor
# directory holds the correct copies of dependencies and ignores
# the dependency descriptions in go.mod.
#
# Allowed values: readonly|vendor|mod
# Default: ""
modules-download-mode: readonly
# Uses version control information during the loading of packages.
# Default: false (implies `-buildvcs=false`)
enable-build-vcs: true
# Allow multiple parallel golangci-lint instances running.
# If false, golangci-lint acquires file lock on start.
# Default: false
allow-parallel-runners: true
# Allow multiple golangci-lint instances running, but serialize them around a lock.
# If false, golangci-lint exits with an error if it fails to acquire file lock on start.
# Default: false
allow-serial-runners: true
# Define the Go version limit.
# Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.22.
go: '1.23'
# Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously.
# Default: 0 (automatically set to match Linux container CPU quota and
# fall back to the number of logical CPUs in the machine)
concurrency: 4
severity:
# Set the default severity for issues.
#
# If severity rules are defined and the issues do not match or no severity is provided to the rule
# this will be the default severity applied.
# Severities should match the supported severity names of the selected out format.
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#SeverityLevel
# - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
# - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance
#
# `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
#
# Default: ""
default: error
# When a list of severity rules are provided, severity information will be added to lint issues.
# Severity rules have the same filtering capability as exclude rules
# except you are allowed to specify one matcher per severity rule.
#
# `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
#
# Only affects out formats that support setting severity information.
#
# Default: []
rules:
- linters:
- dupl
severity: info
================================================
FILE: .golangci.reference.yml
================================================
# This file contains all available configuration options
# with their default values (in comments).
#
# This file is not a configuration example,
# it contains the exhaustive configuration with explanations of the options.
# Defines the configuration version.
# The only possible value is "2".
version: "2"
linters:
# Default set of linters.
# The value can be:
# - `standard`: https://golangci-lint.run/docs/linters/#enabled-by-default
# - `all`: enables all linters by default.
# - `none`: disables all linters by default.
# - `fast`: enables only linters considered as "fast" (`golangci-lint help linters --json | jq '[ .[] | select(.fast==true) ] | map(.name)'`).
# Default: standard
default: all
# Enable specific linter.
enable:
- arangolint
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- embeddedstructfieldcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funcorder
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godoclint
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- iotamixing
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- modernize
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- noinlineerr
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unqueryvet
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- wsl_v5
- zerologlint
# Disable specific linters.
disable:
- arangolint
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- embeddedstructfieldcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funcorder
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godoclint
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- iotamixing
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- modernize
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- noinlineerr
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unqueryvet
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- wsl_v5
- zerologlint
# All available settings of specific linters.
settings:
asasalint:
# To specify a set of function names to exclude.
# The values are merged with the builtin exclusions.
# The builtin exclusions can be disabled by setting `use-builtin-exclusions` to `false`.
# Default: ["^(fmt|log|logger|t|)\.(Print|Fprint|Sprint|Fatal|Panic|Error|Warn|Warning|Info|Debug|Log)(|f|ln)$"]
exclude:
- Append
- \.Wrapf
# To enable/disable the asasalint builtin exclusions of function names.
# See the default value of `exclude` to get the builtin exclusions.
# Default: true
use-builtin-exclusions: false
bidichk:
# The following configurations check for all mentioned invisible Unicode runes.
# All runes are enabled by default.
left-to-right-embedding: false
right-to-left-embedding: false
pop-directional-formatting: false
left-to-right-override: false
right-to-left-override: false
left-to-right-isolate: false
right-to-left-isolate: false
first-strong-isolate: false
pop-directional-isolate: false
copyloopvar:
# Check all assigning the loop variable to another variable.
# Default: false
check-alias: true
cyclop:
# The maximal code complexity to report.
# Default: 10
max-complexity: 10
# The maximal average package complexity.
# If it's higher than 0.0 (float) the check is enabled.
# Default: 0.0
package-average: 0.5
decorder:
# Required order of `type`, `const`, `var` and `func` declarations inside a file.
# Default: types before constants before variables before functions.
dec-order:
- type
- const
- var
- func
# If true, underscore vars (vars with "_" as the name) will be ignored at all checks.
# Default: false (underscore vars are not ignored)
ignore-underscore-vars: false
# If true, order of declarations is not checked at all.
# Default: true (disabled)
disable-dec-order-check: false
# If true, `init` func can be anywhere in file (does not have to be declared before all other functions).
# Default: true (disabled)
disable-init-func-first-check: false
# If true, multiple global `type`, `const` and `var` declarations are allowed.
# Default: true (disabled)
disable-dec-num-check: false
# If true, type declarations will be ignored for dec num check.
# Default: false (type statements are not ignored)
disable-type-dec-num-check: false
# If true, const declarations will be ignored for dec num check.
# Default: false (const statements are not ignored)
disable-const-dec-num-check: false
# If true, var declarations will be ignored for dec num check.
# Default: false (var statements are not ignored)
disable-var-dec-num-check: false
depguard:
# Rules to apply.
#
# Variables:
# - File Variables
# Use an exclamation mark `!` to negate a variable.
# Example: `!$test` matches any file that is not a go test file.
#
# `$all` - matches all go files
# `$test` - matches all go test files
#
# - Package Variables
#
# `$gostd` - matches all of go's standard library (Pulled from `GOROOT`)
#
# Default (applies if no custom rules are defined): Only allow $gostd in all files.
rules:
# Name of a rule.
main:
# Defines package matching behavior. Available modes:
# - `original`: allowed if it doesn't match the deny list and either matches the allow list or the allow list is empty.
# - `strict`: allowed only if it matches the allow list and either doesn't match the deny list or the allow rule is more specific (longer) than the deny rule.
# - `lax`: allowed if it doesn't match the deny list or the allow rule is more specific (longer) than the deny rule.
# Default: "original"
list-mode: lax
# List of file globs that will match this list of settings to compare against.
# By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed.
# The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`.
# The placeholder '${config-path}' is substituted with a path relative to the configuration file.
# Default: $all
files:
- "!**/*_a _file.go"
# List of allowed packages.
# Entries can be a variable (starting with $), a string prefix, or an exact match (if ending with $).
# Default: []
allow:
- $gostd
- github.com/OpenPeeDeeP
# List of packages that are not allowed.
# Entries can be a variable (starting with $), a string prefix, or an exact match (if ending with $).
# Default: []
deny:
- pkg: "math/rand$"
desc: use math/rand/v2
- pkg: "github.com/sirupsen/logrus"
desc: not allowed
- pkg: "github.com/pkg/errors"
desc: Should be replaced by standard lib errors package
dogsled:
# Checks assignments with too many blank identifiers.
# Default: 2
max-blank-identifiers: 3
dupl:
# Tokens count to trigger issue.
# Default: 150
threshold: 100
dupword:
# Keywords for detecting duplicate words.
# If this list is not empty, only the words defined in this list will be detected.
# Default: []
keywords:
- "the"
- "and"
- "a"
# Keywords used to ignore detection.
# Default: []
ignore:
- "0C0C"
# Checks only comments, skip strings.
# Default: false
comments-only: true
embeddedstructfieldcheck:
# Checks that there is an empty space between the embedded fields and regular fields.
# Default: true
empty-line: false
# Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.
# Default: false
forbid-mutex: true
errcheck:
# Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
# Such cases aren't reported by default.
# Default: false
check-type-assertions: true
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`.
# Such cases aren't reported by default.
# Default: false
check-blank: true
# To disable the errcheck built-in exclude list.
# See `-excludeonly` option in https://github.com/kisielk/errcheck#excluding-functions for details.
# Default: false
disable-default-exclusions: true
# List of functions to exclude from checking, where each entry is a single function to exclude.
# See https://github.com/kisielk/errcheck#excluding-functions for details.
exclude-functions:
- io/ioutil.ReadFile
- io.Copy(*bytes.Buffer)
- io.Copy(os.Stdout)
# Display function signature instead of selector.
# Default: false
verbose: true
errchkjson:
# With check-error-free-encoding set to true, errchkjson does warn about errors
# from json encoding functions that are safe to be ignored,
# because they are not possible to happen.
#
# if check-error-free-encoding is set to true and errcheck linter is enabled,
# it is recommended to add the following exceptions to prevent from false positives:
#
# linters:
# settings:
# errcheck:
# exclude-functions:
# - encoding/json.Marshal
# - encoding/json.MarshalIndent
#
# Default: false
check-error-free-encoding: true
# Issue on struct encoding that doesn't have exported fields.
# Default: false
report-no-exported: false
errorlint:
# Check whether fmt.Errorf uses the %w verb for formatting errors.
# See the https://github.com/polyfloyd/go-errorlint for caveats.
# Default: true
errorf: false
# Permit more than 1 %w verb, valid per Go 1.20 (requires `errorf: true`).
# Default: true
errorf-multi: false
# Check for plain type assertions and type switches.
# Default: true
asserts: false
# Check for plain error comparisons.
# Default: true
comparison: false
# Allowed errors.
# Default: []
allowed-errors:
- err: "io.EOF"
fun: "example.com/pkg.Read"
# Allowed error "wildcards".
# Default: []
allowed-errors-wildcard:
- err: "example.com/pkg.ErrMagic"
fun: "example.com/pkg.Magic"
exhaustive:
# Program elements to check for exhaustiveness.
# Default: [ switch ]
check:
- switch
- map
# Presence of "default" case in switch statements satisfies exhaustiveness,
# even if all enum members are not listed.
# Default: false
default-signifies-exhaustive: true
# Enum members matching the supplied regex do not have to be listed in
# switch statements to satisfy exhaustiveness.
# Default: ""
ignore-enum-members: "Example.+"
# Enum types matching the supplied regex do not have to be listed in
# switch statements to satisfy exhaustiveness.
# Default: ""
ignore-enum-types: "Example.+"
# Consider enums only in package scopes, not in inner scopes.
# Default: false
package-scope-only: true
# Only run exhaustive check on switches with "//exhaustive:enforce" comment.
# Default: false
explicit-exhaustive-switch: true
# Only run exhaustive check on map literals with "//exhaustive:enforce" comment.
# Default: false
explicit-exhaustive-map: true
# Switch statement requires default case even if exhaustive.
# Default: false
default-case-required: true
exhaustruct:
# List of regular expressions to match type names that should be processed.
# Anonymous structs can be matched by '' alias.
#
# Each regular expression must match the full type name, including package path.
# For example, to match type `net/http.Cookie` regular expression should be `.*/http\.Cookie`,
# but not `http\.Cookie`.
# Default: []
include:
- '.+\.Test'
- 'example\.com/package\.ExampleStruct[\d]{1,2}'
# List of regular expressions to match type names that should be excluded from processing.
# Anonymous structs can be matched by '' alias.
# Has precedence over `include`.
# Each regular expression must match the full type name, including package path.
# For example, to match type `net/http.Cookie` regular expression should be `.*/http\.Cookie`,
# but not `http\.Cookie`.
# Default: []
exclude:
- '.+/cobra\.Command$'
# Allows empty structures, effectively excluding them from the check.
# Default: false
allow-empty: true
# List of regular expressions to match type names that should be allowed to be empty.
# Anonymous structs can be matched by '' alias.
# Each regular expression must match the full type name, including package path.
# For example, to match type `net/http.Cookie` regular expression should be `.*/http\.Cookie`,
# but not `http\.Cookie`.
# Default: []
allow-empty-rx:
- '.*/http\.Cookie'
# Allows empty structures in return statements.
# Default: false
allow-empty-returns: true
# Allows empty structures in variable declarations.
# Default: false
allow-empty-declarations: true
fatcontext:
# Check for potential fat contexts in struct pointers.
# May generate false positives.
# Default: false
check-struct-pointers: true
forbidigo:
# Forbid the following identifiers (list of regexp).
# Default: ["^(fmt\\.Print(|f|ln)|print|println)$"]
forbid:
# Built-in bootstrapping functions.
- pattern: ^print(ln)?$
# Optional message that gets included in error reports.
- pattern: ^fmt\.Print.*$
msg: Do not commit print statements.
# Alternatively, put messages at the end of the regex, surrounded by `(# )?`.
# Escape any special characters. Those messages get included in error reports.
- pattern: 'fmt\.Print.*(# Do not commit print statements\.)?'
# Forbid spew Dump, whether it is called as function or method.
# Depends on analyze-types below.
- pattern: ^spew\.(ConfigState\.)?Dump$
# The package name might be ambiguous.
# The full import path can be used as additional criteria.
# Depends on analyze-types below.
- pattern: ^v1.Dump$
pkg: ^example.com/pkg/api/v1$
# Exclude godoc examples from forbidigo checks.
# Default: true
exclude-godoc-examples: false
# Instead of matching the literal source code,
# use type information to replace expressions with strings that contain the package name
# and (for methods and fields) the type name.
# This makes it possible to handle import renaming and forbid struct fields and methods.
# Default: false
analyze-types: true
funcorder:
# Checks that constructors are placed after the structure declaration.
# Default: true
constructor: false
# Checks if the exported methods of a structure are placed before the non-exported ones.
# Default: true
struct-method: false
# Checks if the constructors and/or structure methods are sorted alphabetically.
# Default: false
alphabetical: true
funlen:
# Checks the number of lines in a function.
# If lower than 0, disable the check.
# Default: 60
lines: -1
# Checks the number of statements in a function.
# If lower than 0, disable the check.
# Default: 40
statements: -1
# Ignore comments when counting lines.
# Default: true
ignore-comments: false
ginkgolinter:
# Suppress the wrong length assertion warning.
# Default: false
suppress-len-assertion: true
# Suppress the wrong nil assertion warning.
# Default: false
suppress-nil-assertion: true
# Suppress the wrong error assertion warning.
# Default: false
suppress-err-assertion: true
# Suppress the wrong comparison assertion warning.
# Default: false
suppress-compare-assertion: true
# Suppress the function all in async assertion warning.
# Default: false
suppress-async-assertion: true
# Suppress warning for comparing values from different types, like `int32` and `uint32`.
# Default: false
suppress-type-compare-assertion: true
# Trigger warning for ginkgo focus containers like `FDescribe`, `FContext`, `FWhen` or `FIt`.
# Default: false
forbid-focus-container: true
# Don't trigger warnings for HaveLen(0)
# Default: false
allow-havelen-zero: true
# Force using `Expect` with `To`, `ToNot` or `NotTo`.
# Reject using `Expect` with `Should` or `ShouldNot`.
# Default: false
force-expect-to: true
# Best effort validation of async intervals (timeout and polling).
# Ignored the `suppress-async-assertion` is true.
# Default: false
validate-async-intervals: true
# Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.
# Default: false
forbid-spec-pollution: true
# Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.
# Default: false
force-succeed: true
# Force adding assertion descriptions to gomega matchers.
# Default: false
force-assertion-description: true
# Force using `ToNot`, `ShouldNot` instead of `To(Not())`.
# Default: false
force-tonot: true
gochecksumtype:
# Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.
# Default: true
default-signifies-exhaustive: false
# Include shared interfaces in the exhaustiveness check.
# Default: false
include-shared-interfaces: true
gocognit:
# Minimal code complexity to report.
# Default: 30 (but we recommend 10-20)
min-complexity: 10
goconst:
# Minimal length of string constant.
# Default: 3
min-len: 2
# Minimum occurrences of constant string count to trigger issue.
# Default: 3
min-occurrences: 2
# Look for existing constants matching the values.
# Default: true
match-constant: false
# Search also for duplicated numbers.
# Default: false
numbers: true
# Minimum value, only works with `goconst.numbers`.
# Default: 3
min: 2
# Maximum value, only works with `goconst.numbers`.
# Default: 3
max: 2
# Ignore when constant is not used as function argument.
# Default: true
ignore-calls: false
# Exclude strings matching the given regular expression.
# Default: ""
ignore-string-values:
- 'foo.+'
# Detects constants with identical values.
# Default: false
find-duplicates: true
# Evaluates of constant expressions like Prefix + "suffix".
# Default: false
eval-const-expressions: true
gocritic:
# Disable all checks.
# Default: false
disable-all: true
# Which checks should be enabled in addition to default checks; can't be combined with 'disabled-checks'.
# By default, list of stable checks is used (https://go-critic.com/overview#checks-overview):
# appendAssign, argOrder, assignOp, badCall, badCond, captLocal, caseOrder, codegenComment, commentFormatting,
# defaultCaseOrder, deprecatedComment, dupArg, dupBranchBody, dupCase, dupSubExpr, elseif, exitAfterDefer,
# flagDeref, flagName, ifElseChain, mapKey, newDeref, offBy1, regexpMust, singleCaseSwitch, sloppyLen,
# sloppyTypeAssert, switchTrue, typeSwitchVar, underef, unlambda, unslice, valSwap, wrapperFunc
# To see which checks are enabled run `GL_DEBUG=gocritic golangci-lint run --enable=gocritic`.
enabled-checks:
# Detects suspicious append result assignments.
# https://go-critic.com/overview.html#appendassign
- appendAssign
# Detects `append` chains to the same slice that can be done in a single `append` call.
# https://go-critic.com/overview.html#appendcombine
- appendCombine
# Detects suspicious arguments order.
# https://go-critic.com/overview.html#argorder
- argOrder
# Detects assignments that can be simplified by using assignment operators.
# https://go-critic.com/overview.html#assignop
- assignOp
# Detects suspicious function calls.
# https://go-critic.com/overview.html#badcall
- badCall
# Detects suspicious condition expressions.
# https://go-critic.com/overview.html#badcond
- badCond
# Detects suspicious mutex lock/unlock operations.
# https://go-critic.com/overview.html#badlock
- badLock
# Detects suspicious regexp patterns.
# https://go-critic.com/overview.html#badregexp
- badRegexp
# Detects bad usage of sort package.
# https://go-critic.com/overview.html#badsorting
- badSorting
# Detects bad usage of sync.OnceFunc.
# https://go-critic.com/overview.html#badsynconcefunc
- badSyncOnceFunc
# Detects bool expressions that can be simplified.
# https://go-critic.com/overview.html#boolexprsimplify
- boolExprSimplify
# Detects when predeclared identifiers are shadowed in assignments.
# https://go-critic.com/overview.html#builtinshadow
- builtinShadow
# Detects top-level declarations that shadow the predeclared identifiers.
# https://go-critic.com/overview.html#builtinshadowdecl
- builtinShadowDecl
# Detects capitalized names for local variables.
# https://go-critic.com/overview.html#captlocal
- captLocal
# Detects erroneous case order inside switch statements.
# https://go-critic.com/overview.html#caseorder
- caseOrder
# Detects malformed 'code generated' file comments.
# https://go-critic.com/overview.html#codegencomment
- codegenComment
# Detects comments with non-idiomatic formatting.
# https://go-critic.com/overview.html#commentformatting
- commentFormatting
# Detects commented-out code inside function bodies.
# https://go-critic.com/overview.html#commentedoutcode
- commentedOutCode
# Detects commented-out imports.
# https://go-critic.com/overview.html#commentedoutimport
- commentedOutImport
# Detects when default case in switch isn't on 1st or last position.
# https://go-critic.com/overview.html#defaultcaseorder
- defaultCaseOrder
# Detects loops inside functions that use defer.
# https://go-critic.com/overview.html#deferinloop
- deferInLoop
# Detects deferred function literals that can be simplified.
# https://go-critic.com/overview.html#deferunlambda
- deferUnlambda
# Detects malformed 'deprecated' doc-comments.
# https://go-critic.com/overview.html#deprecatedcomment
- deprecatedComment
# Detects comments that silence go lint complaints about doc-comment.
# https://go-critic.com/overview.html#docstub
- docStub
# Detects suspicious duplicated arguments.
# https://go-critic.com/overview.html#duparg
- dupArg
# Detects duplicated branch bodies inside conditional statements.
# https://go-critic.com/overview.html#dupbranchbody
- dupBranchBody
# Detects duplicated case clauses inside switch or select statements.
# https://go-critic.com/overview.html#dupcase
- dupCase
# Detects multiple imports of the same package under different aliases.
# https://go-critic.com/overview.html#dupimport
- dupImport
# Detects duplicated option function arguments in variadic function calls.
# https://go-critic.com/overview.html#dupoption
- dupOption
# Detects suspicious duplicated sub-expressions.
# https://go-critic.com/overview.html#dupsubexpr
- dupSubExpr
# Detects suspicious formatting strings usage.
# https://go-critic.com/overview.html#dynamicfmtstring
- dynamicFmtString
# Detects else with nested if statement that can be replaced with else-if.
# https://go-critic.com/overview.html#elseif
- elseif
# Detects suspicious empty declarations blocks.
# https://go-critic.com/overview.html#emptydecl
- emptyDecl
# Detects fallthrough that can be avoided by using multi case values.
# https://go-critic.com/overview.html#emptyfallthrough
- emptyFallthrough
# Detects empty string checks that can be written more idiomatically.
# https://go-critic.com/overview.html#emptystringtest
- emptyStringTest
# Detects unoptimal strings/bytes case-insensitive comparison.
# https://go-critic.com/overview.html#equalfold
- equalFold
# Detects unwanted dependencies on the evaluation order.
# https://go-critic.com/overview.html#evalorder
- evalOrder
# Detects calls to exit/fatal inside functions that use defer.
# https://go-critic.com/overview.html#exitafterdefer
- exitAfterDefer
# Detects exposed methods from sync.Mutex and sync.RWMutex.
# https://go-critic.com/overview.html#exposedsyncmutex
- exposedSyncMutex
# Detects suspicious reassignment of error from another package.
# https://go-critic.com/overview.html#externalerrorreassign
- externalErrorReassign
# Detects problems in filepath.Join() function calls.
# https://go-critic.com/overview.html#filepathjoin
- filepathJoin
# Detects immediate dereferencing of `flag` package pointers.
# https://go-critic.com/overview.html#flagderef
- flagDeref
# Detects suspicious flag names.
# https://go-critic.com/overview.html#flagname
- flagName
# Detects hex literals that have mixed case letter digits.
# https://go-critic.com/overview.html#hexliteral
- hexLiteral
# Detects nil usages in http.NewRequest calls, suggesting http.NoBody as an alternative.
# https://go-critic.com/overview.html#httpnobody
- httpNoBody
# Detects params that incur excessive amount of copying.
# https://go-critic.com/overview.html#hugeparam
- hugeParam
# Detects repeated if-else statements and suggests to replace them with switch statement.
# https://go-critic.com/overview.html#ifelsechain
- ifElseChain
# Detects when imported package names shadowed in the assignments.
# https://go-critic.com/overview.html#importshadow
- importShadow
# Detects strings.Index calls that may cause unwanted allocs.
# https://go-critic.com/overview.html#indexalloc
- indexAlloc
# Detects non-assignment statements inside if/switch init clause.
# https://go-critic.com/overview.html#initclause
- initClause
# Detects suspicious map literal keys.
# https://go-critic.com/overview.html#mapkey
- mapKey
# Detects method expression call that can be replaced with a method call.
# https://go-critic.com/overview.html#methodexprcall
- methodExprCall
# Finds where nesting level could be reduced.
# https://go-critic.com/overview.html#nestingreduce
- nestingReduce
# Detects immediate dereferencing of `new` expressions.
# https://go-critic.com/overview.html#newderef
- newDeref
# Detects return statements those results evaluate to nil.
# https://go-critic.com/overview.html#nilvalreturn
- nilValReturn
# Detects old-style octal literals.
# https://go-critic.com/overview.html#octalliteral
- octalLiteral
# Detects various off-by-one kind of errors.
# https://go-critic.com/overview.html#offby1
- offBy1
# Detects if function parameters could be combined by type and suggest the way to do it.
# https://go-critic.com/overview.html#paramtypecombine
- paramTypeCombine
# Detects expressions like []rune(s)[0] that may cause unwanted rune slice allocation.
# https://go-critic.com/overview.html#preferdecoderune
- preferDecodeRune
# Detects concatenation with os.PathSeparator which can be replaced with filepath.Join.
# https://go-critic.com/overview.html#preferfilepathjoin
- preferFilepathJoin
# Detects fmt.Sprint(f/ln) calls which can be replaced with fmt.Fprint(f/ln).
# https://go-critic.com/overview.html#preferfprint
- preferFprint
# Detects w.Write or io.WriteString calls which can be replaced with w.WriteString.
# https://go-critic.com/overview.html#preferstringwriter
- preferStringWriter
# Detects WriteRune calls with rune literal argument that is single byte and reports to use WriteByte instead.
# https://go-critic.com/overview.html#preferwritebyte
- preferWriteByte
# Detects input and output parameters that have a type of pointer to referential type.
# https://go-critic.com/overview.html#ptrtorefparam
- ptrToRefParam
# Detects append all its data while range it.
# https://go-critic.com/overview.html#rangeappendall
- rangeAppendAll
# Detects expensive copies of `for` loop range expressions.
# https://go-critic.com/overview.html#rangeexprcopy
- rangeExprCopy
# Detects loops that copy big objects during each iteration.
# https://go-critic.com/overview.html#rangevalcopy
- rangeValCopy
# Detects redundant fmt.Sprint calls.
# https://go-critic.com/overview.html#redundantsprint
- redundantSprint
# Detects `regexp.Compile*` that can be replaced with `regexp.MustCompile*`.
# https://go-critic.com/overview.html#regexpmust
- regexpMust
# Detects suspicious regexp patterns.
# https://go-critic.com/overview.html#regexppattern
- regexpPattern
# Detects regexp patterns that can be simplified.
# https://go-critic.com/overview.html#regexpsimplify
- regexpSimplify
# Detects suspicious http.Error call without following return.
# https://go-critic.com/overview.html#returnafterhttperror
- returnAfterHttpError
# Runs user-defined rules using ruleguard linter.
# https://go-critic.com/overview.html#ruleguard
- ruleguard
# Detects switch statements that could be better written as if statement.
# https://go-critic.com/overview.html#singlecaseswitch
- singleCaseSwitch
# Detects slice clear loops, suggests an idiom that is recognized by the Go compiler.
# https://go-critic.com/overview.html#sliceclear
- sliceClear
# Detects usage of `len` when result is obvious or doesn't make sense.
# https://go-critic.com/overview.html#sloppylen
- sloppyLen
# Detects suspicious/confusing re-assignments.
# https://go-critic.com/overview.html#sloppyreassign
- sloppyReassign
# Detects redundant type assertions.
# https://go-critic.com/overview.html#sloppytypeassert
- sloppyTypeAssert
# Detects suspicious sort.Slice calls.
# https://go-critic.com/overview.html#sortslice
- sortSlice
# Detects "%s" formatting directives that can be replaced with %q.
# https://go-critic.com/overview.html#sprintfquotedstring
- sprintfQuotedString
# Detects issue in Query() and Exec() calls.
# https://go-critic.com/overview.html#sqlquery
- sqlQuery
# Detects string concat operations that can be simplified.
# https://go-critic.com/overview.html#stringconcatsimplify
- stringConcatSimplify
# Detects redundant conversions between string and []byte.
# https://go-critic.com/overview.html#stringxbytes
- stringXbytes
# Detects strings.Compare usage.
# https://go-critic.com/overview.html#stringscompare
- stringsCompare
# Detects switch-over-bool statements that use explicit `true` tag value.
# https://go-critic.com/overview.html#switchtrue
- switchTrue
# Detects sync.Map load+delete operations that can be replaced with LoadAndDelete.
# https://go-critic.com/overview.html#syncmaploadanddelete
- syncMapLoadAndDelete
# Detects manual conversion to milli- or microseconds.
# https://go-critic.com/overview.html#timeexprsimplify
- timeExprSimplify
# Detects TODO comments without detail/assignee.
# https://go-critic.com/overview.html#todocommentwithoutdetail
- todoCommentWithoutDetail
# Detects function with too many results.
# https://go-critic.com/overview.html#toomanyresultschecker
- tooManyResultsChecker
# Detects potential truncation issues when comparing ints of different sizes.
# https://go-critic.com/overview.html#truncatecmp
- truncateCmp
# Detects repeated type assertions and suggests to replace them with type switch statement.
# https://go-critic.com/overview.html#typeassertchain
- typeAssertChain
# Detects method declarations preceding the type definition itself.
# https://go-critic.com/overview.html#typedeffirst
- typeDefFirst
# Detects type switches that can benefit from type guard clause with variable.
# https://go-critic.com/overview.html#typeswitchvar
- typeSwitchVar
# Detects unneeded parenthesis inside type expressions and suggests to remove them.
# https://go-critic.com/overview.html#typeunparen
- typeUnparen
# Detects unchecked errors in if statements.
# https://go-critic.com/overview.html#uncheckedinlineerr
- uncheckedInlineErr
# Detects dereference expressions that can be omitted.
# https://go-critic.com/overview.html#underef
- underef
# Detects redundant statement labels.
# https://go-critic.com/overview.html#unlabelstmt
- unlabelStmt
# Detects function literals that can be simplified.
# https://go-critic.com/overview.html#unlambda
- unlambda
# Detects unnamed results that may benefit from names.
# https://go-critic.com/overview.html#unnamedresult
- unnamedResult
# Detects unnecessary braced statement blocks.
# https://go-critic.com/overview.html#unnecessaryblock
- unnecessaryBlock
# Detects redundantly deferred calls.
# https://go-critic.com/overview.html#unnecessarydefer
- unnecessaryDefer
# Detects slice expressions that can be simplified to sliced expression itself.
# https://go-critic.com/overview.html#unslice
- unslice
# Detects value swapping code that are not using parallel assignment.
# https://go-critic.com/overview.html#valswap
- valSwap
# Detects conditions that are unsafe due to not being exhaustive.
# https://go-critic.com/overview.html#weakcond
- weakCond
# Ensures that `//nolint` comments include an explanation.
# https://go-critic.com/overview.html#whynolint
- whyNoLint
# Detects function calls that can be replaced with convenience wrappers.
# https://go-critic.com/overview.html#wrapperfunc
- wrapperFunc
# Detects Yoda style expressions and suggests to replace them.
# https://go-critic.com/overview.html#yodastyleexpr
- yodaStyleExpr
# Detects bytes.Repeat with 0 value.
# https://go-critic.com/overview.html#zerobyterepeat
- zeroByteRepeat
# Enable all checks.
# Default: false
enable-all: true
# Which checks should be disabled; can't be combined with 'enabled-checks'.
# Default: []
disabled-checks:
- appendAssign
- appendCombine
- argOrder
- assignOp
- badCall
- badCond
- badLock
- badRegexp
- badSorting
- badSyncOnceFunc
- boolExprSimplify
- builtinShadow
- builtinShadowDecl
- captLocal
- caseOrder
- codegenComment
- commentFormatting
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deferInLoop
- deferUnlambda
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupImport
- dupSubExpr
- dynamicFmtString
- elseif
- emptyDecl
- emptyFallthrough
- emptyStringTest
- equalFold
- evalOrder
- exitAfterDefer
- exposedSyncMutex
- externalErrorReassign
- filepathJoin
- flagDeref
- flagName
- hexLiteral
- httpNoBody
- hugeParam
- ifElseChain
- importShadow
- indexAlloc
- initClause
- mapKey
- methodExprCall
- nestingReduce
- newDeref
- nilValReturn
- octalLiteral
- offBy1
- paramTypeCombine
- preferDecodeRune
- preferFilepathJoin
- preferFprint
- preferStringWriter
- preferWriteByte
- ptrToRefParam
- rangeAppendAll
- rangeExprCopy
- rangeValCopy
- redundantSprint
- regexpMust
- regexpPattern
- regexpSimplify
- returnAfterHttpError
- ruleguard
- singleCaseSwitch
- sliceClear
- sloppyLen
- sloppyReassign
- sloppyTypeAssert
- sortSlice
- sprintfQuotedString
- sqlQuery
- stringConcatSimplify
- stringXbytes
- stringsCompare
- switchTrue
- syncMapLoadAndDelete
- timeExprSimplify
- todoCommentWithoutDetail
- tooManyResultsChecker
- truncateCmp
- typeAssertChain
- typeDefFirst
- typeSwitchVar
- typeUnparen
- uncheckedInlineErr
- underef
- unlabelStmt
- unlambda
- unnamedResult
- unnecessaryBlock
- unnecessaryDefer
- unslice
- valSwap
- weakCond
- whyNoLint
- wrapperFunc
- yodaStyleExpr
# Enable multiple checks by tags in addition to default checks.
# Run `GL_DEBUG=gocritic golangci-lint run --enable=gocritic` to see all tags and checks.
# See https://github.com/go-critic/go-critic#usage -> section "Tags".
# Default: []
enabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
disabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
# Settings passed to gocritic.
# The settings key is the name of a supported gocritic checker.
# The list of supported checkers can be found at https://go-critic.com/overview.
settings:
# Must be valid enabled check name.
captLocal:
# Whether to restrict checker to params only.
# Default: true
paramsOnly: false
commentedOutCode:
# Min length of the comment that triggers a warning.
# Default: 15
minLength: 50
elseif:
# Whether to skip balanced if-else pairs.
# Default: true
skipBalanced: false
hugeParam:
# Size in bytes that makes the warning trigger.
# Default: 80
sizeThreshold: 70
ifElseChain:
# Min number of if-else blocks that makes the warning trigger.
# Default: 2
minThreshold: 4
nestingReduce:
# Min number of statements inside a branch to trigger a warning.
# Default: 5
bodyWidth: 4
rangeExprCopy:
# Size in bytes that makes the warning trigger.
# Default: 512
sizeThreshold: 516
# Whether to check test functions
# Default: true
skipTestFuncs: false
rangeValCopy:
# Size in bytes that makes the warning trigger.
# Default: 128
sizeThreshold: 32
# Whether to check test functions.
# Default: true
skipTestFuncs: false
ruleguard:
# Enable debug to identify which 'Where' condition was rejected.
# The value of the parameter is the name of a function in a ruleguard file.
#
# When a rule is evaluated:
# If:
# The Match() clause is accepted; and
# One of the conditions in the Where() clause is rejected,
# Then:
# ruleguard prints the specific Where() condition that was rejected.
#
# The option is passed to the ruleguard 'debug-group' argument.
# Default: ""
debug: 'emptyDecl'
# Determines the behavior when an error occurs while parsing ruleguard files.
# If flag is not set, log error and skip rule files that contain an error.
# If flag is set, the value must be a comma-separated list of error conditions.
# - 'all': fail on all errors.
# - 'import': ruleguard rule imports a package that cannot be found.
# - 'dsl': gorule file does not comply with the ruleguard DSL.
# Default: ""
failOn: dsl,import
# Comma-separated list of file paths containing ruleguard rules.
# By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed.
# The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`.
# The placeholder '${config-path}' is substituted with a path relative to the configuration file.
# Glob patterns such as 'rules-*.go' may be specified.
# Default: ""
rules: '${base-path}/ruleguard/rules-*.go,${base-path}/myrule1.go'
# Comma-separated list of enabled groups or skip empty to enable everything.
# Tags can be defined with # character prefix.
# Default: ""
enable: "myGroupName,#myTagName"
# Comma-separated list of disabled groups or skip empty to enable everything.
# Tags can be defined with # character prefix.
# Default: ""
disable: "myGroupName,#myTagName"
tooManyResultsChecker:
# Maximum number of results.
# Default: 5
maxResults: 10
truncateCmp:
# Whether to skip int/uint/uintptr types.
# Default: true
skipArchDependent: false
underef:
# Whether to skip (*x).method() calls where x is a pointer receiver.
# Default: true
skipRecvDeref: false
unnamedResult:
# Whether to check exported functions.
# Default: false
checkExported: true
gocyclo:
# Minimal code complexity to report.
# Default: 30 (but we recommend 10-20)
min-complexity: 10
godoclint:
# Default set of rules to enable.
# Possible values are: `basic`, `all` or `none`.
# Default: `basic` (enables `pkg-doc`, `single-pkg-doc`, `start-with-name`, and `deprecated`)
default: all
# List of rules to enable in addition to the default set.
# Default: empty
enable:
# Check proper package-level godoc, if any.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#pkg-doc
- pkg-doc
# Assert at most one godoc per package.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#single-pkg-doc
- single-pkg-doc
# Require all packages to have a godoc.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#require-pkg-doc
- require-pkg-doc
# Assert symbol godocs start with the symbol name.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#start-with-name
- start-with-name
# Require godoc for all public symbols.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#require-doc
- require-doc
# Assert correct formatting of deprecation notes.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#deprecated
- deprecated
# Assert maximum line length for godocs.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#max-len
- max-len
# Assert no unused link in godocs.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#no-unused-link
- no-unused-link
# Require proper doc links to standard library declarations where applicable.
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#require-stdlib-doclink
- require-stdlib-doclink
# List of rules to disable.
# Default: empty
disable:
- pkg-doc
- single-pkg-doc
- require-pkg-doc
- start-with-name
- require-doc
- deprecated
- max-len
- no-unused-link
- require-stdlib-doclink
# A map for fine-tuning individual rules.
# All subkeys are optional.
options:
max-len:
# Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.
# Default: 77
length: 127
require-doc:
# Ignore exported (public) symbols when applying the `require-doc` rule.
# Default: false
ignore-exported: true
# Ignore unexported (private) symbols when applying the `require-doc` rule.
# Default: true
ignore-unexported: false
start-with-name:
# Include unexported symbols when applying the `start-with-name` rule.
# Default: false
include-unexported: true
godot:
# Comments to be checked: `declarations`, `toplevel`, `noinline` or `all`.
# Default: declarations
scope: toplevel
# List of regexps for excluding particular comment lines from check.
# Default: []
exclude:
# Exclude todo and fixme comments.
- "^fixme:"
- "^todo:"
# Check that each sentence ends with a period.
# Default: true
period: false
# Check that each sentence starts with a capital letter.
# Default: false
capital: true
godox:
# Report any comments starting with keywords, this is useful for TODO or FIXME comments that
# might be left in the code accidentally and should be resolved before merging.
# Default: ["TODO", "BUG", "FIXME"]
keywords:
- NOTE
- OPTIMIZE # marks code that should be optimized before merging
- HACK # marks hack-around that should be removed before merging
goheader:
# Supports two types 'const` and `regexp`.
# Values can be used recursively.
# Default: {}
values:
const:
# Define here const type values in format k:v.
# For example:
COMPANY: MY COMPANY
regexp:
# Define here regexp type values.
# for example:
AUTHOR: .*@mycompany\.com
# The template used for checking.
# Put here copyright header template for source code files.
# Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
# Default: ""
template: |-
{{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
# As alternative of directive 'template', you may put the path to file with the template source.
# Useful if you need to load the template from a specific file.
# By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed.
# The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`.
# The placeholder '${config-path}' is substituted with a path relative to the configuration file.
# Default: ""
template-path: /path/to/my/template.tmpl
gomoddirectives:
# Allow local `replace` directives.
# Default: false
replace-local: true
# List of allowed `replace` directives.
# Default: []
replace-allow-list:
- launchpad.net/gocheck
# Allow to not explain why the version has been retracted in the `retract` directives.
# Default: false
retract-allow-no-explanation: true
# Forbid the use of the `exclude` directives.
# Default: false
exclude-forbidden: true
# Forbid the use of the `ignore` directives (>= go1.25).
# Default: false
ignore-forbidden: true
# Forbid the use of the `toolchain` directive.
# Default: false
toolchain-forbidden: true
# Defines a pattern to validate `toolchain` directive.
# Default: '' (no match)
toolchain-pattern: 'go1\.23\.\d+$'
# Forbid the use of the `tool` directives.
# Default: false
tool-forbidden: true
# Forbid the use of the `godebug` directive.
# Default: false
go-debug-forbidden: true
# Defines a pattern to validate `go` minimum version directive.
# Default: '' (no match)
go-version-pattern: '\d\.\d+(\.0)?'
# Check the validity of the module path.
# Default: false
check-module-path: true
gomodguard:
allowed:
# List of allowed modules.
# Default: []
modules:
- gopkg.in/yaml.v2
# List of allowed module domains.
# Default: []
domains:
- golang.org
blocked:
# List of blocked modules.
# Default: []
modules:
# Blocked module.
- github.com/uudashr/go-module:
# Recommended modules that should be used instead. (Optional)
recommendations:
- golang.org/x/mod
# Reason why the recommended module should be used. (Optional)
reason: "`mod` is the official go.mod parser library."
# List of blocked module version constraints.
# Default: []
versions:
# Blocked module with version constraint.
- github.com/mitchellh/go-homedir:
# Version constraint, see https://github.com/Masterminds/semver#basic-comparisons.
version: "< 1.1.0"
# Reason why the version constraint exists. (Optional)
reason: "testing if blocked version constraint works."
# Set to true to raise lint issues for packages that are loaded from a local path via replace directive.
# Default: false
local-replace-directives: false
gosec:
# To select a subset of rules to run.
# Available rules: https://github.com/securego/gosec#available-rules
# Default: [] - means include all rules
includes:
- G101 # Look for hardcoded credentials
- G102 # Bind to all interfaces
- G103 # Audit the use of unsafe block
- G104 # Audit errors not checked
- G106 # Audit the use of ssh.InsecureIgnoreHostKey function
- G107 # Url provided to HTTP request as taint input
- G108 # Profiling endpoint is automatically exposed
- G109 # Converting strconv.Atoi result to int32/int16
- G110 # Detect io.Copy instead of io.CopyN when decompression
- G111 # Detect http.Dir('/') as a potential risk
- G112 # Detect ReadHeaderTimeout not configured as a potential risk
- G113 # HTTP request smuggling via conflicting headers or bare LF in body parsing
- G114 # Use of net/http serve function that has no support for setting timeouts
- G115 # Type conversion which leads to integer overflow
- G116 # Detect Trojan Source attacks using bidirectional Unicode characters
- G117 # Potential exposure of secrets via JSON/YAML/XML/TOML marshaling
- G118 # Context propagation failure leading to goroutine/resource leaks
- G119 # Unsafe redirect policy may propagate sensitive headers
- G120 # Unbounded form parsing in HTTP handlers can cause memory exhaustion
- G121 # Unsafe CrossOriginProtection bypass patterns
- G122 # Filesystem TOCTOU race risk in filepath.Walk/WalkDir callbacks
- G123 # TLS resumption may bypass VerifyPeerCertificate when VerifyConnection is unset
- G201 # SQL query construction using format string
- G202 # SQL query construction using string concatenation
- G203 # Use of unescaped data in HTML templates
- G204 # Audit use of command execution
- G301 # Poor file permissions used when creating a directory
- G302 # Poor file permissions used when creation file or using chmod
- G303 # Creating tempfile using a predictable path
- G304 # File path provided as taint input
- G305 # File path traversal when extracting zip archive
- G306 # Poor file permissions used when writing to a file
- G307 # Poor file permissions used when creating a file with os.Create
- G401 # Detect the usage of MD5 or SHA1
- G402 # Look for bad TLS connection settings
- G403 # Ensure minimum RSA key length of 2048 bits
- G404 # Insecure random number source (rand)
- G405 # Detect the usage of DES or RC4
- G406 # Detect the usage of deprecated MD4 or RIPEMD160
- G408 # Stateful misuse of ssh.PublicKeyCallback leading to auth bypass
- G501 # Import blocklist: crypto/md5
- G502 # Import blocklist: crypto/des
- G503 # Import blocklist: crypto/rc4
- G504 # Import blocklist: net/http/cgi
- G505 # Import blocklist: crypto/sha1
- G506 # Import blocklist: golang.org/x/crypto/md4
- G507 # Import blocklist: golang.org/x/crypto/ripemd160
- G601 # Implicit memory aliasing in RangeStmt
- G602 # Possible slice bounds out of range
- G701 # SQL injection via taint analysis
- G702 # Command injection via taint analysis
- G703 # Path traversal via taint analysis
- G704 # SSRF via taint analysis
- G705 # XSS via taint analysis
- G706 # Log injection via taint analysis
- G707 # SMTP command/header injection via taint analysis
# To specify a set of rules to explicitly exclude.
# Available rules: https://github.com/securego/gosec#available-rules
# Default: []
excludes:
- G101 # Look for hardcoded credentials
- G102 # Bind to all interfaces
- G103 # Audit the use of unsafe block
- G104 # Audit errors not checked
- G106 # Audit the use of ssh.InsecureIgnoreHostKey function
- G107 # Url provided to HTTP request as taint input
- G108 # Profiling endpoint is automatically exposed
- G109 # Converting strconv.Atoi result to int32/int16
- G110 # Detect io.Copy instead of io.CopyN when decompression
- G111 # Detect http.Dir('/') as a potential risk
- G112 # Detect ReadHeaderTimeout not configured as a potential risk
- G114 # Use of net/http serve function that has no support for setting timeouts
- G115 # Type conversion which leads to integer overflow
- G116 # Detect Trojan Source attacks using bidirectional Unicode characters
- G201 # SQL query construction using format string
- G202 # SQL query construction using string concatenation
- G203 # Use of unescaped data in HTML templates
- G204 # Audit use of command execution
- G301 # Poor file permissions used when creating a directory
- G302 # Poor file permissions used when creation file or using chmod
- G303 # Creating tempfile using a predictable path
- G304 # File path provided as taint input
- G305 # File path traversal when extracting zip archive
- G306 # Poor file permissions used when writing to a file
- G307 # Poor file permissions used when creating a file with os.Create
- G401 # Detect the usage of MD5 or SHA1
- G402 # Look for bad TLS connection settings
- G403 # Ensure minimum RSA key length of 2048 bits
- G404 # Insecure random number source (rand)
- G405 # Detect the usage of DES or RC4
- G406 # Detect the usage of deprecated MD4 or RIPEMD160
- G501 # Import blocklist: crypto/md5
- G502 # Import blocklist: crypto/des
- G503 # Import blocklist: crypto/rc4
- G504 # Import blocklist: net/http/cgi
- G505 # Import blocklist: crypto/sha1
- G506 # Import blocklist: golang.org/x/crypto/md4
- G507 # Import blocklist: golang.org/x/crypto/ripemd160
- G601 # Implicit memory aliasing in RangeStmt
- G602 # Possible slice bounds out of range
# Filter out the issues with a lower severity than the given value.
# Valid options are: low, medium, high.
# Default: low
severity: medium
# Filter out the issues with a lower confidence than the given value.
# Valid options are: low, medium, high.
# Default: low
confidence: medium
# Concurrency value.
# Default: the number of logical CPUs usable by the current process.
concurrency: 12
# To specify the configuration of rules.
config:
# Globals are applicable to all rules.
global:
# If true, ignore #nosec in comments (and an alternative as well).
# Default: false
nosec: true
# Add an alternative comment prefix to #nosec (both will work at the same time).
# Default: ""
"#nosec": "#my-custom-nosec"
# Define whether nosec issues are counted as finding or not.
# Default: false
show-ignored: true
# Audit mode enables addition checks that for normal code analysis might be too nosy.
# Default: false
audit: true
G101:
# Regexp pattern for variables and constants to find.
# Default: "(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred"
pattern: "(?i)example"
# If true, complain about all cases (even with low entropy).
# Default: false
ignore_entropy: false
# Maximum allowed entropy of the string.
# Default: "80.0"
entropy_threshold: "80.0"
# Maximum allowed value of entropy/string length.
# Is taken into account if entropy >= entropy_threshold/2.
# Default: "3.0"
per_char_threshold: "3.0"
# Calculate entropy for first N chars of the string.
# Default: "16"
truncate: "32"
# Additional functions to ignore while checking unhandled errors.
# Following functions always ignored:
# bytes.Buffer:
# - Write
# - WriteByte
# - WriteRune
# - WriteString
# fmt:
# - Print
# - Printf
# - Println
# - Fprint
# - Fprintf
# - Fprintln
# strings.Builder:
# - Write
# - WriteByte
# - WriteRune
# - WriteString
# io.PipeWriter:
# - CloseWithError
# hash.Hash:
# - Write
# os:
# - Unsetenv
# Default: {}
G104:
fmt:
- Fscanf
G111:
# Regexp pattern to find potential directory traversal.
# Default: "http\\.Dir\\(\"\\/\"\\)|http\\.Dir\\('\\/'\\)"
pattern: "custom\\.Dir\\(\\)"
# Maximum allowed permissions mode for os.Mkdir and os.MkdirAll.
# Default: "0750"
G301: "0750"
# Maximum allowed permissions mode for os.OpenFile and os.Chmod.
# Default: "0600"
G302: "0600"
# Maximum allowed permissions mode for os.WriteFile and ioutil.WriteFile.
# Default: "0600"
G306: "0600"
gosmopolitan:
# Allow and ignore `time.Local` usages.
#
# Default: false
allow-time-local: true
# List of fully qualified names in the `full/pkg/path.name` form, to act as "i18n escape hatches".
# String literals inside call-like expressions to, or struct literals of those names,
# are exempt from the writing system check.
#
# Default: []
escape-hatches:
- 'github.com/nicksnyder/go-i18n/v2/i18n.Message'
- 'example.com/your/project/i18n/markers.Raw'
- 'example.com/your/project/i18n/markers.OK'
- 'example.com/your/project/i18n/markers.TODO'
- 'command-line-arguments.Simple'
# List of Unicode scripts to watch for any usage in string literals.
# https://pkg.go.dev/unicode#pkg-variables
#
# Default: ["Han"]
watch-for-scripts:
- Devanagari
- Han
- Hangul
- Hiragana
- Katakana
govet:
# Disable all analyzers.
# Default: false
disable-all: true
# Enable analyzers by name.
# (In addition to default:
# appends, asmdecl, assign, atomic, bools, buildtag, cgocall, composites, copylocks, defers, directive, errorsas,
# framepointer, httpresponse, ifaceassert, loopclosure, lostcancel, nilfunc, printf, shift, sigchanyzer, slog,
# stdmethods, stringintconv, structtag, testinggoroutine, tests, timeformat, unmarshal, unreachable, unsafeptr,
# unusedresult
# ).
# Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers.
# Default: []
enable:
# Check for missing values after append.
- appends
# Report mismatches between assembly files and Go declarations.
- asmdecl
# Check for useless assignments.
- assign
# Check for common mistakes using the sync/atomic package.
- atomic
# Check for non-64-bits-aligned arguments to sync/atomic functions.
- atomicalign
# Check for common mistakes involving boolean operators.
- bools
# Check //go:build and // +build directives.
- buildtag
# Detect some violations of the cgo pointer passing rules.
- cgocall
# Check for unkeyed composite literals.
- composites
# Check for locks erroneously passed by value.
- copylocks
# Check for calls of reflect.DeepEqual on error values.
- deepequalerrors
# Report common mistakes in defer statements.
- defers
# Check Go toolchain directives such as //go:debug.
- directive
# Report passing non-pointer or non-error values to errors.As.
- errorsas
# Find structs that would use less memory if their fields were sorted.
- fieldalignment
# Find calls to a particular function.
- findcall
# Report assembly that clobbers the frame pointer before saving it.
- framepointer
# Check format of addresses passed to net.Dial.
- hostport
# Report using Go 1.22 enhanced ServeMux patterns in older Go versions.
- httpmux
# Check for mistakes using HTTP responses.
- httpresponse
# Detect impossible interface-to-interface type assertions.
- ifaceassert
# Check references to loop variables from within nested functions.
- loopclosure
# Check cancel func returned by context.WithCancel is called.
- lostcancel
# Check for useless comparisons between functions and nil.
- nilfunc
# Check for redundant or impossible nil comparisons.
- nilness
# Check consistency of Printf format strings and arguments.
- printf
# Check for comparing reflect.Value values with == or reflect.DeepEqual.
- reflectvaluecompare
# Check for possible unintended shadowing of variables.
- shadow
# Check for shifts that equal or exceed the width of the integer.
- shift
# Check for unbuffered channel of os.Signal.
- sigchanyzer
# Check for invalid structured logging calls.
- slog
# Check the argument type of sort.Slice.
- sortslice
# Check signature of methods of well-known interfaces.
- stdmethods
# Report uses of too-new standard library symbols.
- stdversion
# Check for string(int) conversions.
- stringintconv
# Check that struct field tags conform to reflect.StructTag.Get.
- structtag
# Report calls to (*testing.T).Fatal from goroutines started by a test.
- testinggoroutine
# Check for common mistaken usages of tests and examples.
- tests
# Check for calls of (time.Time).Format or time.Parse with 2006-02-01.
- timeformat
# Report passing non-pointer or non-interface values to unmarshal.
- unmarshal
# Check for unreachable code.
- unreachable
# Check for invalid conversions of uintptr to unsafe.Pointer.
- unsafeptr
# Check for unused results of calls to some functions.
- unusedresult
# Checks for unused writes.
- unusedwrite
# Check for misuses of sync.WaitGroup.
- waitgroup
# Enable all analyzers.
# Default: false
enable-all: true
# Disable analyzers by name.
# (In addition to default
# atomicalign, deepequalerrors, fieldalignment, findcall, nilness, reflectvaluecompare, shadow, sortslice,
# timeformat, unusedwrite
# ).
# Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers.
# Default: []
disable:
- appends
- asmdecl
- assign
- atomic
- atomicalign
- bools
- buildtag
- cgocall
- composites
- copylocks
- deepequalerrors
- defers
- directive
- errorsas
- fieldalignment
- findcall
- framepointer
- hostport
- httpmux
- httpresponse
- ifaceassert
- loopclosure
- lostcancel
- nilfunc
- nilness
- printf
- reflectvaluecompare
- shadow
- shift
- sigchanyzer
- slog
- sortslice
- stdmethods
- stdversion
- stringintconv
- structtag
- testinggoroutine
- tests
- timeformat
- unmarshal
- unreachable
- unsafeptr
- unusedresult
- unusedwrite
- waitgroup
# Settings per analyzer.
settings:
# Analyzer name, run `go tool vet help` to see all analyzers.
printf:
# Comma-separated list of print function names to check (in addition to default, see `go tool vet help printf`).
# Default: []
funcs:
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Fatalf
shadow:
# Whether to be strict about shadowing; can be noisy.
# Default: false
strict: true
unusedresult:
# Comma-separated list of functions whose results must be used.
# (In addition to default:
# context.WithCancel, context.WithDeadline, context.WithTimeout, context.WithValue, errors.New, fmt.Errorf,
# fmt.Sprint, fmt.Sprintf, sort.Reverse
# ).
# Default: []
funcs:
- pkg.MyFunc
# Comma-separated list of names of methods of type func() string whose results must be used.
# (In addition to default Error,String).
# Default: []
stringmethods:
- MyMethod
grouper:
# Require the use of a single global 'const' declaration only.
# Default: false
const-require-single-const: true
# Require the use of grouped global 'const' declarations.
# Default: false
const-require-grouping: true
# Require the use of a single 'import' declaration only.
# Default: false
import-require-single-import: true
# Require the use of grouped 'import' declarations.
# Default: false
import-require-grouping: true
# Require the use of a single global 'type' declaration only.
# Default: false
type-require-single-type: true
# Require the use of grouped global 'type' declarations.
# Default: false
type-require-grouping: true
# Require the use of a single global 'var' declaration only.
# Default: false
var-require-single-var: true
# Require the use of grouped global 'var' declarations.
# Default: false
var-require-grouping: true
iface:
# List of analyzers.
# Default: ["identical"]
enable:
- identical # Identifies interfaces in the same package that have identical method sets.
- unused # Identifies interfaces that are not used anywhere in the same package where the interface is defined.
- opaque # Identifies functions that return interfaces, but the actual returned value is always a single concrete implementation.
- unexported # Identifies interfaces that are not exported but are used in exported functions or methods.
settings:
unused:
# List of packages path to exclude from the check.
# Default: []
exclude:
- github.com/example/log
importas:
# Do not allow unaliased imports of aliased packages.
# Default: false
no-unaliased: true
# Do not allow non-required aliases.
# Default: false
no-extra-aliases: true
# List of aliases
# Default: []
alias:
# Using `servingv1` alias for `knative.dev/serving/pkg/apis/serving/v1` package.
- pkg: knative.dev/serving/pkg/apis/serving/v1
alias: servingv1
# Using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package.
- pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
alias: autoscalingv1alpha1
# You can specify the package path by regular expression,
# and alias by regular expression expansion syntax like below.
# See https://github.com/julz/importas#use-regular-expression for details.
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
alias: $1$2
# An explicit empty alias can be used to ensure no aliases are used for a package.
# This can be useful if `no-extra-aliases: true` doesn't fit your need.
# Multiple packages can use an empty alias.
- pkg: errors
alias: ""
inamedparam:
# Skips check for interface methods with only a single parameter.
# Default: false
skip-single-param: true
ineffassign:
# Check escaping variables of type error, may cause false positives.
# Default: false
check-escaping-errors: true
interfacebloat:
# The maximum number of methods allowed for an interface.
# Default: 10
max: 5
iotamixing:
# Whether to report individual consts rather than just the const block.
# Default: false
report-individual: true
ireturn:
# List of interfaces to allow.
# Lists of the keywords and regular expressions matched to interface or package names can be used.
# `allow` and `reject` settings cannot be used at the same time.
#
# Keywords:
# - `empty` for `interface{}`
# - `error` for errors
# - `stdlib` for standard library
# - `anon` for anonymous interfaces
# - `generic` for generic interfaces added in go 1.18
#
# Default: [anon, error, empty, stdlib]
allow:
- anon
# You can specify idiomatic endings for interface
- (or|er)$
# List of interfaces to reject.
# Lists of the keywords and regular expressions matched to interface or package names can be used.
# `allow` and `reject` settings cannot be used at the same time.
#
# Keywords:
# - `empty` for `interface{}`
# - `error` for errors
# - `stdlib` for standard library
# - `anon` for anonymous interfaces
# - `generic` for generic interfaces added in go 1.18
#
# Default: []
reject:
- github.com\/user\/package\/v4\.Type
lll:
# Max line length, lines longer will be reported.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option.
# Default: 120.
line-length: 120
# Tab width in spaces.
# Default: 1
tab-width: 1
loggercheck:
# Allow check for the github.com/go-kit/log library.
# Default: true
kitlog: false
# Allow check for the k8s.io/klog/v2 library.
# Default: true
klog: false
# Allow check for the github.com/go-logr/logr library.
# Default: true
logr: false
# Allow check for the log/slog library.
# Default: true
slog: false
# Allow check for the "sugar logger" from go.uber.org/zap library.
# Default: true
zap: false
# Require all logging keys to be inlined constant strings.
# Default: false
require-string-key: true
# Require printf-like format specifier (%s, %d for example) not present.
# Default: false
no-printf-like: true
# List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.
# For example: https://github.com/timonwong/loggercheck/blob/7395ab86595781e33f7afba27ad7b55e6956ebcd/testdata/custom-rules.txt
# Default: empty
rules:
- k8s.io/klog/v2.InfoS # package level exported functions
- (github.com/go-logr/logr.Logger).Error # "Methods"
- (*go.uber.org/zap.SugaredLogger).With # Also "Methods", but with a pointer receiver
maintidx:
# Show functions with maintainability index lower than N.
# A high index indicates better maintainability (it's kind of the opposite of complexity).
# Default: 20
under: 100
makezero:
# Allow only slices initialized with a length of zero.
# Default: false
always: true
misspell:
# Correct spellings using locale preferences for US or UK.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
# Default is to use a neutral variety of English.
locale: US
# Typos to ignore.
# Should be in lower case.
# Default: []
ignore-rules:
- someword
# Extra word corrections.
# `typo` and `correction` should only contain letters.
# The words are case-insensitive.
# Default: []
extra-words:
- typo: "iff"
correction: "if"
- typo: "cancelation"
correction: "cancellation"
# Mode of the analysis:
# - default: checks all the file content.
# - restricted: checks only comments.
# Default: ""
mode: restricted
mnd:
# List of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
# Default: ["argument", "case", "condition", "operation", "return", "assign"]
checks:
- argument
- case
- condition
- operation
- return
- assign
# List of numbers to exclude from analysis.
# The numbers should be written as string.
# Values always ignored: "1", "1.0", "0" and "0.0".
# Default: []
ignored-numbers:
- '0666'
- '0755'
- '42'
# List of file patterns to exclude from analysis.
# Values always ignored: `.+_test.go`.
# Default: []
ignored-files:
- 'magic1_.+\.go$'
# List of function patterns to exclude from analysis.
# Following functions are always ignored: `time.Date`,
# `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`,
# `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`.
# Default: []
ignored-functions:
- '^math\.'
- '^http\.StatusText$'
modernize:
# List of analyzers to disable.
# By default, all analyzers are enabled.
disable:
# Replace interface{} with any.
- any
# Replace []byte(fmt.Sprintf) with fmt.Appendf.
- fmtappendf
# Remove redundant re-declaration of loop variables.
- forvar
# Replace explicit loops over maps with calls to maps package.
- mapsloop
# Replace if/else statements with calls to min or max.
- minmax
# Simplify code by using go1.26's new(expr).
- newexpr
# Suggest replacing omitempty with omitzero for struct fields.
- omitzero
# Remove obsolete //+build comments.
- plusbuild
# Replace 3-clause for loops with for-range over integers.
- rangeint
# Replace reflect.TypeOf(x) with TypeFor[T]().
- reflecttypefor
# Replace loops with slices.Contains or slices.ContainsFunc.
- slicescontains
# Replace sort.Slice with slices.Sort for basic types.
- slicessort
# Use iterators instead of Len/At-style APIs.
- stditerators
# Replace strings.Index etc. with strings.Cut.
- stringscut
# Replace HasPrefix/TrimPrefix with CutPrefix.
- stringscutprefix
# Replace ranging over Split/Fields with SplitSeq/FieldsSeq.
- stringsseq
# Replace += with strings.Builder.
- stringsbuilder
# Replace context.WithCancel with t.Context in tests.
- testingcontext
# Replace unsafe pointer arithmetic with function calls.
- unsafefuncs
# Replace wg.Add(1)/go/wg.Done() with wg.Go.
- waitgroup
musttag:
# A set of custom functions to check in addition to the builtin ones.
# Default: json, xml, gopkg.in/yaml.v3, BurntSushi/toml, mitchellh/mapstructure, jmoiron/sqlx
functions:
# The full name of the function, including the package.
- name: github.com/hashicorp/hcl/v2/hclsimple.DecodeFile
# The struct tag whose presence should be ensured.
tag: hcl
# The position of the argument to check.
arg-pos: 2
nakedret:
# Make an issue if func has more lines of code than this setting, and it has naked returns.
# Default: 30
max-func-lines: 31
nestif:
# Minimal complexity of if statements to report.
# Default: 5
min-complexity: 4
nilnil:
# To check functions with only two return values (`return nil, nil`).
# If disabled then returns like `return nil, nil, ..., nil` are supported.
# Default: true
only-two: false
# In addition, detect opposite situation (simultaneous return of non-nil error and valid value).
# E.g, `return clone, fh.indexer.Update(clone)` will be considered as invalid.
# Default: false
detect-opposite: true
# List of return types to check.
# Default: ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
checked-types:
- chan
- func
- iface
- map
- ptr
- uintptr
- unsafeptr
nlreturn:
# Size of the block (including return statement that is still "OK"),
# so no return split required.
# Default: 1
block-size: 2
nolintlint:
# Disable to ensure that all nolint directives actually have an effect.
# Default: false
allow-unused: true
# Exclude following linters from requiring an explanation.
# Default: []
allow-no-explanation: [ ]
# Enable to require an explanation of nonzero length after each nolint directive.
# Default: false
require-explanation: true
# Enable to require nolint directives to mention the specific linter being suppressed.
# Default: false
require-specific: true
nonamedreturns:
# Report named error if it is assigned inside defer.
# Default: false
report-error-in-defer: true
paralleltest:
# Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.
# Default: false
ignore-missing: true
# Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are
# still required to have `t.Parallel`, but subtests are allowed to skip it.
# Default: false
ignore-missing-subtests: true
perfsprint:
# Enable/disable optimization of integer formatting.
# Default: true
integer-format: false
# Optimizes even if it requires an int or uint type cast.
# Default: true
int-conversion: false
# Enable/disable optimization of error formatting.
# Default: true
error-format: false
# Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.
# Default: false
err-error: true
# Optimizes `fmt.Errorf`.
# Default: true
errorf: false
# Enable/disable optimization of string formatting.
# Default: true
string-format: false
# Optimizes `fmt.Sprintf` with only one argument.
# Default: true
sprintf1: false
# Optimizes into strings concatenation.
# Default: true
strconcat: false
# Enable/disable optimization of bool formatting.
# Default: true
bool-format: false
# Enable/disable optimization of hex formatting.
# Default: true
hex-format: false
# Enable/disable optimization of concat loop.
# Default: true
concat-loop: false
# Optimization of `concat-loop` even with other operations.
# Default: false
loop-other-ops: true
prealloc:
# IMPORTANT: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization.
# Report pre-allocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# Default: true
simple: false
# Report pre-allocation suggestions on range loops.
# Default: true
range-loops: false
# Report pre-allocation suggestions on for loops.
# Default: false
for-loops: true
predeclared:
# List of predeclared identifiers to not report on.
# Default: []
ignore:
- new
- int
# Include method names and field names in checks.
# Default: false
qualified-name: true
promlinter:
# Promlinter cannot infer all metrics name in static analysis.
# Enable strict mode will also include the errors caused by failing to parse the args.
# Default: false
strict: true
# Please refer to https://github.com/yeya24/promlinter#usage for detailed usage.
# Default: []
disabled-linters:
# Help detects issues related to the help text for a metric.
- Help
# MetricUnits detects issues with metric unit names.
- MetricUnits
# Counter detects issues specific to counters, as well as patterns that should only be used with counters.
- Counter
# HistogramSummaryReserved detects when other types of metrics use names or labels reserved for use by histograms and/or summaries.
- HistogramSummaryReserved
# MetricTypeInName detects when metric types are included in the metric name.
- MetricTypeInName
# ReservedChars detects colons in metric names.
- ReservedChars
# CamelCase detects metric names and label names written in camelCase.
- CamelCase
# UnitAbbreviations detects abbreviated units in the metric name.
- UnitAbbreviations
protogetter:
# Skip files generated by specified generators from the checking.
# Checks only the file's initial comment, which must follow the format: "// Code generated by ".
# Files generated by protoc-gen-go, protoc-gen-go-grpc, and protoc-gen-grpc-gateway are always excluded automatically.
# Default: []
skip-generated-by: ["protoc-gen-go-my-own-generator"]
# Skip files matching the specified glob pattern from the checking.
# Default: []
skip-files:
- "*.pb.go"
- "*/vendor/*"
- "/full/path/to/file.go"
# Skip any generated files from the checking.
# Default: false
skip-any-generated: true
# Skip first argument of append function.
# Default: false
replace-first-arg-in-append: true
reassign:
# Patterns for global variable names that are checked for reassignment.
# See https://github.com/curioswitch/go-reassign#usage
# Default: ["EOF", "Err.*"]
patterns:
- ".*"
recvcheck:
# Disables the built-in method exclusions:
# - `MarshalText`
# - `MarshalJSON`
# - `MarshalYAML`
# - `MarshalXML`
# - `MarshalBinary`
# - `GobEncode`
# Default: false
disable-builtin: true
# User-defined method exclusions.
# The format is `struct_name.method_name` (ex: `Foo.MethodName`).
# A wildcard `*` can use as a struct name (ex: `*.MethodName`).
# Default: []
exclusions:
- "*.Value"
revive:
# Maximum number of open files at the same time.
# See https://github.com/mgechev/revive#command-line-flags
# Defaults to unlimited.
max-open-files: 2048
# Sets the default severity.
# See https://github.com/mgechev/revive#configuration
# Default: warning
severity: error
# Enable all available rules.
# Default: false
enable-all-rules: true
# By default, the default rules are enabled,
# but if you explicitly define or configure a rule, the default rules will be disabled.
# This option, when set to `true`, allows you to avoid explicitly redefining default rules when adding a rule.
# Default: false
enable-default-rules: true
# Enable validation of comment directives.
# See https://github.com/mgechev/revive#comment-directives
directives:
- name: specify-disable-reason
severity: error
# Sets the default failure confidence.
# This means that linting errors with less than 0.8 confidence will be ignored.
# Default: 0.8
confidence: 0.1
# Revive handles the default rules in a way that can be unexpected:
# - If there are no explicit rules, the default rules are used.
# - If there is at least one explicit rule, the default rules are not used, unless `enable-default-rules` is `true`.
# Run `GL_DEBUG=revive golangci-lint run --enable-only=revive` to see default, all available rules, and enabled rules.
rules:
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#add-constant
- name: add-constant
severity: warning
disabled: false
exclude: [""]
arguments:
- max-lit-count: "3"
allow-strs: '""'
allow-ints: "0,1,2"
allow-floats: "0.0,0.,1.0,1.,2.0,2."
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#argument-limit
- name: argument-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 4 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#atomic
- name: atomic
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#banned-characters
- name: banned-characters
severity: warning
disabled: false
exclude: [""]
arguments: [ "Ω","Σ","σ", "7" ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#bare-return
- name: bare-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#blank-imports
- name: blank-imports
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#bool-literal-in-expr
- name: bool-literal-in-expr
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#call-to-gc
- name: call-to-gc
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#cognitive-complexity
- name: cognitive-complexity
severity: warning
disabled: false
exclude: [""]
arguments: [ 7 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#comment-spacings
- name: comment-spacings
severity: warning
disabled: false
exclude: [""]
arguments:
- mypragma
- otherpragma
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#comments-density
- name: comments-density
severity: warning
disabled: false
exclude: [""]
arguments: [ 15 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#confusing-naming
- name: confusing-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#confusing-results
- name: confusing-results
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#constant-logical-expr
- name: constant-logical-expr
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#context-as-argument
- name: context-as-argument
severity: warning
disabled: false
exclude: [""]
arguments:
- allow-types-before: "*testing.T,*github.com/user/repo/testing.Harness"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#context-keys-type
- name: context-keys-type
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#cyclomatic
- name: cyclomatic
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#datarace
- name: datarace
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#deep-exit
- name: deep-exit
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#defer
- name: defer
severity: warning
disabled: false
exclude: [""]
arguments:
- "call-chain"
- "loop"
- "method-call"
- "recover"
- "immediate-recover"
- "return"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#dot-imports
- name: dot-imports
severity: warning
disabled: false
exclude: [""]
arguments:
- allowed-packages: ["github.com/onsi/ginkgo/v2", "github.com/onsi/gomega"]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#duplicated-imports
- name: duplicated-imports
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#early-return
- name: early-return
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserve-scope"
- "allow-jump"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#empty-block
- name: empty-block
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#empty-lines
- name: empty-lines
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-map-style
- name: enforce-map-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "make"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-repeated-arg-type-style
- name: enforce-repeated-arg-type-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "short"
# Or this parameter:
- func-arg-style: "full"
func-ret-val-style: "short"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-slice-style
- name: enforce-slice-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "make"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-switch-style
- name: enforce-switch-style
severity: warning
disabled: false
exclude: [""]
arguments: [ "allowNoDefault" ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#epoch-naming
- name: epoch-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-naming
- name: error-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-return
- name: error-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-strings
- name: error-strings
severity: warning
disabled: false
exclude: [""]
arguments:
- "xerrors.New"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#errorf
- name: errorf
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#exported
- name: exported
severity: warning
disabled: false
exclude: [""]
arguments:
- "check-private-receivers"
- "disable-stuttering-check"
- "say-repetitive-instead-of-stutters"
- "check-public-interface"
- "disable-checks-on-constants"
- "disable-checks-on-functions"
- "disable-checks-on-methods"
- "disable-checks-on-types"
- "disable-checks-on-variables"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#file-header
- name: file-header
severity: warning
disabled: false
exclude: [""]
arguments:
- This is the text that must appear at the top of source files.
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#file-length-limit
- name: file-length-limit
severity: warning
disabled: false
exclude: [""]
arguments:
- max: 100
skip-comments: true
skip-blank-lines: true
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#filename-format
- name: filename-format
severity: warning
disabled: false
exclude: [""]
arguments:
- "^[_a-z][_a-z0-9]*\\.go$"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#flag-parameter
- name: flag-parameter
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#forbidden-call-in-wg-go
- name: forbidden-call-in-wg-go
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#function-length
- name: function-length
severity: warning
disabled: false
exclude: [""]
arguments: [ 10, 0 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#function-result-limit
- name: function-result-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#get-return
- name: get-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-branches
- name: identical-branches
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-ifelseif-branches
- name: identical-ifelseif-branches
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-ifelseif-conditions
- name: identical-ifelseif-conditions
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-switch-branches
- name: identical-switch-branches
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-switch-conditions
- name: identical-switch-conditions
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#if-return
- name: if-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#import-alias-naming
- name: import-alias-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- "^[a-z][a-z0-9]{0,}$"
# Or this parameter:
- allow-regex: "^[a-z][a-z0-9]{0,}$"
deny-regex: '^v\d+$'
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#import-shadowing
- name: import-shadowing
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#imports-blocklist
- name: imports-blocklist
severity: warning
disabled: false
exclude: [""]
arguments:
- "crypto/md5"
- "crypto/sha1"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#increment-decrement
- name: increment-decrement
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#indent-error-flow
- name: indent-error-flow
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserve-scope"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#inefficient-map-lookup
- name: inefficient-map-lookup
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#line-length-limit
- name: line-length-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 80 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#max-control-nesting
- name: max-control-nesting
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#max-public-structs
- name: max-public-structs
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#modifies-parameter
- name: modifies-parameter
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#modifies-value-receiver
- name: modifies-value-receiver
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#nested-structs
- name: nested-structs
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#optimize-operands-order
- name: optimize-operands-order
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#package-comments
- name: package-comments
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#package-directory-mismatch
- name: package-directory-mismatch
severity: warning
disabled: false
exclude: [""]
arguments:
- ignore-directories: ["testcases", "testinfo"]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#package-naming
- name: package-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- skip-convention-name-check: true
convention-name-check-regex: "^[a-z][a-zA-Z0-9]*$"
skip-top-level-check: true
skip-default-bad-name-check: true
check-extra-bad-name: true
user-defined-bad-names:
- foo
- bar
skip-collision-with-common-std: true
check-collision-with-all-std: true
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range
- name: range
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range-val-address
- name: range-val-address
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range-val-in-closure
- name: range-val-in-closure
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#receiver-naming
- name: receiver-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- max-length: 2
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redefines-builtin-id
- name: redefines-builtin-id
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redundant-build-tag
- name: redundant-build-tag
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redundant-import-alias
- name: redundant-import-alias
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redundant-test-main-exit
- name: redundant-test-main-exit
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#string-format
- name: string-format
severity: warning
disabled: false
exclude: [""]
arguments:
- - 'core.WriteError[1].Message'
- '/^([^A-Z]|$)/'
- must not start with a capital letter
- - 'fmt.Errorf[0]'
- '/(^|[^\.!?])$/'
- must not end in punctuation
- - panic
- '/^[^\n]*$/'
- must not contain line breaks
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#string-of-int
- name: string-of-int
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#struct-tag
- name: struct-tag
severity: warning
disabled: false
exclude: [""]
arguments:
- "!validate"
- "json,inline"
- "bson,outline,gnu"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#superfluous-else
- name: superfluous-else
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserve-scope"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#time-date
- name: time-date
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#time-equal
- name: time-equal
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#time-naming
- name: time-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unchecked-type-assertion
- name: unchecked-type-assertion
severity: warning
disabled: false
exclude: [""]
arguments:
- accept-ignored-assertion-result: true
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unconditional-recursion
- name: unconditional-recursion
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unexported-naming
- name: unexported-naming
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unexported-return
- name: unexported-return
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unhandled-error
- name: unhandled-error
severity: warning
disabled: false
exclude: [""]
arguments:
- "^fmt.Printf"
- "myFunction"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unnecessary-format
- name: unnecessary-format
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unnecessary-if
- name: unnecessary-if
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unnecessary-stmt
- name: unnecessary-stmt
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unreachable-code
- name: unreachable-code
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-slices-sort
- name: use-slices-sort
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unsecure-url-scheme
- name: unsecure-url-scheme
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unused-parameter
- name: unused-parameter
severity: warning
disabled: false
exclude: [""]
arguments:
- allow-regex: "^_"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unused-receiver
- name: unused-receiver
severity: warning
disabled: false
exclude: [""]
arguments:
- allow-regex: "^_"
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-any
- name: use-any
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-errors-new
- name: use-errors-new
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-fmt-print
- name: use-fmt-print
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-slices-sort
- name: use-slices-sort
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-waitgroup-go
- name: use-waitgroup-go
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#useless-break
- name: useless-break
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#useless-fallthrough
- name: useless-fallthrough
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#var-declaration
- name: var-declaration
severity: warning
disabled: false
exclude: [""]
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#var-naming
- name: var-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- [ "ID" ] # AllowList
- [ "VM" ] # DenyList
- - skip-initialism-name-checks: true
upper-case-const: true
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#waitgroup-by-value
- name: waitgroup-by-value
severity: warning
disabled: false
exclude: [""]
rowserrcheck:
# database/sql is always checked.
# Default: []
packages:
- github.com/jmoiron/sqlx
sloglint:
# Enforce not mixing key-value pairs and attributes.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-mixed-arguments
# Default: true
no-mixed-args: false
# Enforce using key-value pairs only (overrides no-mixed-args, incompatible with attr-only).
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#key-value-pairs-only
# Default: false
kv-only: true
# Enforce using attributes only (overrides no-mixed-args, incompatible with kv-only).
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#attributes-only
# Default: false
attr-only: true
# Enforce not using global loggers.
# Values:
# - "": disabled
# - "all": report all global loggers
# - "default": report only the default slog logger
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-global
# Default: ""
no-global: "all"
# Enforce using methods that accept a context.
# Values:
# - "": disabled
# - "all": report all contextless calls
# - "scope": report only if a context exists in the scope of the outermost function
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#context-only
# Default: ""
context: "all"
# Enforce using static values for log messages.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#static-messages
# Default: false
static-msg: true
# Enforce message style.
# Values: lowercased, capitalized
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#message-style
# Default: ""
msg-style: capitalized
# Enforce using constants instead of raw keys.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-raw-keys
# Default: false
no-raw-keys: true
# Enforce key naming convention.
# Values: snake, kebab, camel, pascal
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#key-naming-convention
# Default: ""
key-naming-case: snake
# Enforce not using specific keys.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#forbidden-keys
# Default: []
forbidden-keys:
- time
- level
- msg
- source
- foo
# Enforce putting arguments on separate lines.
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#arguments-on-separate-lines
# Default: false
args-on-sep-lines: true
spancheck:
# Checks to enable.
# Options include:
# - `end`: check that `span.End()` is called
# - `record-error`: check that `span.RecordError(err)` is called when an error is returned
# - `set-status`: check that `span.SetStatus(codes.Error, msg)` is called when an error is returned
# Default: ["end"]
checks:
- end
- record-error
- set-status
# A list of regexes for function signatures that silence `record-error` and `set-status` reports
# if found in the call path to a returned error.
# https://github.com/jjti/go-spancheck#ignore-check-signatures
# Default: []
ignore-check-signatures:
- "telemetry.RecordError"
# A list of regexes for additional function signatures that create spans.
# This is useful if you have a utility method to create spans.
# Each entry should be of the form `:`, where `telemetry-type` can be `opentelemetry` or `opencensus`.
# https://github.com/jjti/go-spancheck#extra-start-span-signatures
# Default: []
extra-start-span-signatures:
- "github.com/user/repo/telemetry/trace.Start:opentelemetry"
staticcheck:
# https://staticcheck.dev/docs/configuration/options/#dot_import_whitelist
# Default: ["github.com/mmcloughlin/avo/build", "github.com/mmcloughlin/avo/operand", "github.com/mmcloughlin/avo/reg"]
dot-import-whitelist:
- fmt
# https://staticcheck.dev/docs/configuration/options/#initialisms
# Default: ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"]
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ]
# https://staticcheck.dev/docs/configuration/options/#http_status_code_whitelist
# Default: ["200", "400", "404", "500"]
http-status-code-whitelist: [ "200", "400", "404", "500" ]
# SAxxxx checks in https://staticcheck.dev/docs/configuration/options/#checks
# Example (to disable some checks): [ "all", "-SA1000", "-SA1001"]
# Run `GL_DEBUG=staticcheck golangci-lint run --enable=staticcheck` to see all available checks and enabled by config checks.
# Default: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"]
checks:
# Invalid regular expression.
# https://staticcheck.dev/docs/checks/#SA1000
- SA1000
# Invalid template.
# https://staticcheck.dev/docs/checks/#SA1001
- SA1001
# Invalid format in 'time.Parse'.
# https://staticcheck.dev/docs/checks/#SA1002
- SA1002
# Unsupported argument to functions in 'encoding/binary'.
# https://staticcheck.dev/docs/checks/#SA1003
- SA1003
# Suspiciously small untyped constant in 'time.Sleep'.
# https://staticcheck.dev/docs/checks/#SA1004
- SA1004
# Invalid first argument to 'exec.Command'.
# https://staticcheck.dev/docs/checks/#SA1005
- SA1005
# 'Printf' with dynamic first argument and no further arguments.
# https://staticcheck.dev/docs/checks/#SA1006
- SA1006
# Invalid URL in 'net/url.Parse'.
# https://staticcheck.dev/docs/checks/#SA1007
- SA1007
# Non-canonical key in 'http.Header' map.
# https://staticcheck.dev/docs/checks/#SA1008
- SA1008
# '(*regexp.Regexp).FindAll' called with 'n == 0', which will always return zero results.
# https://staticcheck.dev/docs/checks/#SA1010
- SA1010
# Various methods in the "strings" package expect valid UTF-8, but invalid input is provided.
# https://staticcheck.dev/docs/checks/#SA1011
- SA1011
# A nil 'context.Context' is being passed to a function, consider using 'context.TODO' instead.
# https://staticcheck.dev/docs/checks/#SA1012
- SA1012
# 'io.Seeker.Seek' is being called with the whence constant as the first argument, but it should be the second.
# https://staticcheck.dev/docs/checks/#SA1013
- SA1013
# Non-pointer value passed to 'Unmarshal' or 'Decode'.
# https://staticcheck.dev/docs/checks/#SA1014
- SA1014
# Using 'time.Tick' in a way that will leak. Consider using 'time.NewTicker', and only use 'time.Tick' in tests, commands and endless functions.
# https://staticcheck.dev/docs/checks/#SA1015
- SA1015
# Trapping a signal that cannot be trapped.
# https://staticcheck.dev/docs/checks/#SA1016
- SA1016
# Channels used with 'os/signal.Notify' should be buffered.
# https://staticcheck.dev/docs/checks/#SA1017
- SA1017
# 'strings.Replace' called with 'n == 0', which does nothing.
# https://staticcheck.dev/docs/checks/#SA1018
- SA1018
# Using a deprecated function, variable, constant or field.
# https://staticcheck.dev/docs/checks/#SA1019
- SA1019
# Using an invalid host:port pair with a 'net.Listen'-related function.
# https://staticcheck.dev/docs/checks/#SA1020
- SA1020
# Using 'bytes.Equal' to compare two 'net.IP'.
# https://staticcheck.dev/docs/checks/#SA1021
- SA1021
# Modifying the buffer in an 'io.Writer' implementation.
# https://staticcheck.dev/docs/checks/#SA1023
- SA1023
# A string cutset contains duplicate characters.
# https://staticcheck.dev/docs/checks/#SA1024
- SA1024
# It is not possible to use '(*time.Timer).Reset''s return value correctly.
# https://staticcheck.dev/docs/checks/#SA1025
- SA1025
# Cannot marshal channels or functions.
# https://staticcheck.dev/docs/checks/#SA1026
- SA1026
# Atomic access to 64-bit variable must be 64-bit aligned.
# https://staticcheck.dev/docs/checks/#SA1027
- SA1027
# 'sort.Slice' can only be used on slices.
# https://staticcheck.dev/docs/checks/#SA1028
- SA1028
# Inappropriate key in call to 'context.WithValue'.
# https://staticcheck.dev/docs/checks/#SA1029
- SA1029
# Invalid argument in call to a 'strconv' function.
# https://staticcheck.dev/docs/checks/#SA1030
- SA1030
# Overlapping byte slices passed to an encoder.
# https://staticcheck.dev/docs/checks/#SA1031
- SA1031
# Wrong order of arguments to 'errors.Is'.
# https://staticcheck.dev/docs/checks/#SA1032
- SA1032
# 'sync.WaitGroup.Add' called inside the goroutine, leading to a race condition.
# https://staticcheck.dev/docs/checks/#SA2000
- SA2000
# Empty critical section, did you mean to defer the unlock?.
# https://staticcheck.dev/docs/checks/#SA2001
- SA2001
# Called 'testing.T.FailNow' or 'SkipNow' in a goroutine, which isn't allowed.
# https://staticcheck.dev/docs/checks/#SA2002
- SA2002
# Deferred 'Lock' right after locking, likely meant to defer 'Unlock' instead.
# https://staticcheck.dev/docs/checks/#SA2003
- SA2003
# 'TestMain' doesn't call 'os.Exit', hiding test failures.
# https://staticcheck.dev/docs/checks/#SA3000
- SA3000
# Assigning to 'b.N' in benchmarks distorts the results.
# https://staticcheck.dev/docs/checks/#SA3001
- SA3001
# Binary operator has identical expressions on both sides.
# https://staticcheck.dev/docs/checks/#SA4000
- SA4000
# '&*x' gets simplified to 'x', it does not copy 'x'.
# https://staticcheck.dev/docs/checks/#SA4001
- SA4001
# Comparing unsigned values against negative values is pointless.
# https://staticcheck.dev/docs/checks/#SA4003
- SA4003
# The loop exits unconditionally after one iteration.
# https://staticcheck.dev/docs/checks/#SA4004
- SA4004
# Field assignment that will never be observed. Did you mean to use a pointer receiver?.
# https://staticcheck.dev/docs/checks/#SA4005
- SA4005
# A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?.
# https://staticcheck.dev/docs/checks/#SA4006
- SA4006
# The variable in the loop condition never changes, are you incrementing the wrong variable?.
# https://staticcheck.dev/docs/checks/#SA4008
- SA4008
# A function argument is overwritten before its first use.
# https://staticcheck.dev/docs/checks/#SA4009
- SA4009
# The result of 'append' will never be observed anywhere.
# https://staticcheck.dev/docs/checks/#SA4010
- SA4010
# Break statement with no effect. Did you mean to break out of an outer loop?.
# https://staticcheck.dev/docs/checks/#SA4011
- SA4011
# Comparing a value against NaN even though no value is equal to NaN.
# https://staticcheck.dev/docs/checks/#SA4012
- SA4012
# Negating a boolean twice ('!!b') is the same as writing 'b'. This is either redundant, or a typo.
# https://staticcheck.dev/docs/checks/#SA4013
- SA4013
# An if/else if chain has repeated conditions and no side-effects; if the condition didn't match the first time, it won't match the second time, either.
# https://staticcheck.dev/docs/checks/#SA4014
- SA4014
# Calling functions like 'math.Ceil' on floats converted from integers doesn't do anything useful.
# https://staticcheck.dev/docs/checks/#SA4015
- SA4015
# Certain bitwise operations, such as 'x ^ 0', do not do anything useful.
# https://staticcheck.dev/docs/checks/#SA4016
- SA4016
# Discarding the return values of a function without side effects, making the call pointless.
# https://staticcheck.dev/docs/checks/#SA4017
- SA4017
# Self-assignment of variables.
# https://staticcheck.dev/docs/checks/#SA4018
- SA4018
# Multiple, identical build constraints in the same file.
# https://staticcheck.dev/docs/checks/#SA4019
- SA4019
# Unreachable case clause in a type switch.
# https://staticcheck.dev/docs/checks/#SA4020
- SA4020
# "x = append(y)" is equivalent to "x = y".
# https://staticcheck.dev/docs/checks/#SA4021
- SA4021
# Comparing the address of a variable against nil.
# https://staticcheck.dev/docs/checks/#SA4022
- SA4022
# Impossible comparison of interface value with untyped nil.
# https://staticcheck.dev/docs/checks/#SA4023
- SA4023
# Checking for impossible return value from a builtin function.
# https://staticcheck.dev/docs/checks/#SA4024
- SA4024
# Integer division of literals that results in zero.
# https://staticcheck.dev/docs/checks/#SA4025
- SA4025
# Go constants cannot express negative zero.
# https://staticcheck.dev/docs/checks/#SA4026
- SA4026
# '(*net/url.URL).Query' returns a copy, modifying it doesn't change the URL.
# https://staticcheck.dev/docs/checks/#SA4027
- SA4027
# 'x % 1' is always zero.
# https://staticcheck.dev/docs/checks/#SA4028
- SA4028
# Ineffective attempt at sorting slice.
# https://staticcheck.dev/docs/checks/#SA4029
- SA4029
# Ineffective attempt at generating random number.
# https://staticcheck.dev/docs/checks/#SA4030
- SA4030
# Checking never-nil value against nil.
# https://staticcheck.dev/docs/checks/#SA4031
- SA4031
# Comparing 'runtime.GOOS' or 'runtime.GOARCH' against impossible value.
# https://staticcheck.dev/docs/checks/#SA4032
- SA4032
# Assignment to nil map.
# https://staticcheck.dev/docs/checks/#SA5000
- SA5000
# Deferring 'Close' before checking for a possible error.
# https://staticcheck.dev/docs/checks/#SA5001
- SA5001
# The empty for loop ("for {}") spins and can block the scheduler.
# https://staticcheck.dev/docs/checks/#SA5002
- SA5002
# Defers in infinite loops will never execute.
# https://staticcheck.dev/docs/checks/#SA5003
- SA5003
# "for { select { ..." with an empty default branch spins.
# https://staticcheck.dev/docs/checks/#SA5004
- SA5004
# The finalizer references the finalized object, preventing garbage collection.
# https://staticcheck.dev/docs/checks/#SA5005
- SA5005
# Infinite recursive call.
# https://staticcheck.dev/docs/checks/#SA5007
- SA5007
# Invalid struct tag.
# https://staticcheck.dev/docs/checks/#SA5008
- SA5008
# Invalid Printf call.
# https://staticcheck.dev/docs/checks/#SA5009
- SA5009
# Impossible type assertion.
# https://staticcheck.dev/docs/checks/#SA5010
- SA5010
# Possible nil pointer dereference.
# https://staticcheck.dev/docs/checks/#SA5011
- SA5011
# Passing odd-sized slice to function expecting even size.
# https://staticcheck.dev/docs/checks/#SA5012
- SA5012
# Using 'regexp.Match' or related in a loop, should use 'regexp.Compile'.
# https://staticcheck.dev/docs/checks/#SA6000
- SA6000
# Missing an optimization opportunity when indexing maps by byte slices.
# https://staticcheck.dev/docs/checks/#SA6001
- SA6001
# Storing non-pointer values in 'sync.Pool' allocates memory.
# https://staticcheck.dev/docs/checks/#SA6002
- SA6002
# Converting a string to a slice of runes before ranging over it.
# https://staticcheck.dev/docs/checks/#SA6003
- SA6003
# Inefficient string comparison with 'strings.ToLower' or 'strings.ToUpper'.
# https://staticcheck.dev/docs/checks/#SA6005
- SA6005
# Using io.WriteString to write '[]byte'.
# https://staticcheck.dev/docs/checks/#SA6006
- SA6006
# Defers in range loops may not run when you expect them to.
# https://staticcheck.dev/docs/checks/#SA9001
- SA9001
# Using a non-octal 'os.FileMode' that looks like it was meant to be in octal.
# https://staticcheck.dev/docs/checks/#SA9002
- SA9002
# Empty body in an if or else branch.
# https://staticcheck.dev/docs/checks/#SA9003
- SA9003
# Only the first constant has an explicit type.
# https://staticcheck.dev/docs/checks/#SA9004
- SA9004
# Trying to marshal a struct with no public fields nor custom marshaling.
# https://staticcheck.dev/docs/checks/#SA9005
- SA9005
# Dubious bit shifting of a fixed size integer value.
# https://staticcheck.dev/docs/checks/#SA9006
- SA9006
# Deleting a directory that shouldn't be deleted.
# https://staticcheck.dev/docs/checks/#SA9007
- SA9007
# 'else' branch of a type assertion is probably not reading the right value.
# https://staticcheck.dev/docs/checks/#SA9008
- SA9008
# Ineffectual Go compiler directive.
# https://staticcheck.dev/docs/checks/#SA9009
- SA9009
# Incorrect or missing package comment.
# https://staticcheck.dev/docs/checks/#ST1000
- ST1000
# Dot imports are discouraged.
# https://staticcheck.dev/docs/checks/#ST1001
- ST1001
# Poorly chosen identifier.
# https://staticcheck.dev/docs/checks/#ST1003
- ST1003
# Incorrectly formatted error string.
# https://staticcheck.dev/docs/checks/#ST1005
- ST1005
# Poorly chosen receiver name.
# https://staticcheck.dev/docs/checks/#ST1006
- ST1006
# A function's error value should be its last return value.
# https://staticcheck.dev/docs/checks/#ST1008
- ST1008
# Poorly chosen name for variable of type 'time.Duration'.
# https://staticcheck.dev/docs/checks/#ST1011
- ST1011
# Poorly chosen name for error variable.
# https://staticcheck.dev/docs/checks/#ST1012
- ST1012
# Should use constants for HTTP error codes, not magic numbers.
# https://staticcheck.dev/docs/checks/#ST1013
- ST1013
# A switch's default case should be the first or last case.
# https://staticcheck.dev/docs/checks/#ST1015
- ST1015
# Use consistent method receiver names.
# https://staticcheck.dev/docs/checks/#ST1016
- ST1016
# Don't use Yoda conditions.
# https://staticcheck.dev/docs/checks/#ST1017
- ST1017
# Avoid zero-width and control characters in string literals.
# https://staticcheck.dev/docs/checks/#ST1018
- ST1018
# Importing the same package multiple times.
# https://staticcheck.dev/docs/checks/#ST1019
- ST1019
# The documentation of an exported function should start with the function's name.
# https://staticcheck.dev/docs/checks/#ST1020
- ST1020
# The documentation of an exported type should start with type's name.
# https://staticcheck.dev/docs/checks/#ST1021
- ST1021
# The documentation of an exported variable or constant should start with variable's name.
# https://staticcheck.dev/docs/checks/#ST1022
- ST1022
# Redundant type in variable declaration.
# https://staticcheck.dev/docs/checks/#ST1023
- ST1023
# Use plain channel send or receive instead of single-case select.
# https://staticcheck.dev/docs/checks/#S1000
- S1000
# Replace for loop with call to copy.
# https://staticcheck.dev/docs/checks/#S1001
- S1001
# Omit comparison with boolean constant.
# https://staticcheck.dev/docs/checks/#S1002
- S1002
# Replace call to 'strings.Index' with 'strings.Contains'.
# https://staticcheck.dev/docs/checks/#S1003
- S1003
# Replace call to 'bytes.Compare' with 'bytes.Equal'.
# https://staticcheck.dev/docs/checks/#S1004
- S1004
# Drop unnecessary use of the blank identifier.
# https://staticcheck.dev/docs/checks/#S1005
- S1005
# Use "for { ... }" for infinite loops.
# https://staticcheck.dev/docs/checks/#S1006
- S1006
# Simplify regular expression by using raw string literal.
# https://staticcheck.dev/docs/checks/#S1007
- S1007
# Simplify returning boolean expression.
# https://staticcheck.dev/docs/checks/#S1008
- S1008
# Omit redundant nil check on slices, maps, and channels.
# https://staticcheck.dev/docs/checks/#S1009
- S1009
# Omit default slice index.
# https://staticcheck.dev/docs/checks/#S1010
- S1010
# Use a single 'append' to concatenate two slices.
# https://staticcheck.dev/docs/checks/#S1011
- S1011
# Replace 'time.Now().Sub(x)' with 'time.Since(x)'.
# https://staticcheck.dev/docs/checks/#S1012
- S1012
# Use a type conversion instead of manually copying struct fields.
# https://staticcheck.dev/docs/checks/#S1016
- S1016
# Replace manual trimming with 'strings.TrimPrefix'.
# https://staticcheck.dev/docs/checks/#S1017
- S1017
# Use "copy" for sliding elements.
# https://staticcheck.dev/docs/checks/#S1018
- S1018
# Simplify "make" call by omitting redundant arguments.
# https://staticcheck.dev/docs/checks/#S1019
- S1019
# Omit redundant nil check in type assertion.
# https://staticcheck.dev/docs/checks/#S1020
- S1020
# Merge variable declaration and assignment.
# https://staticcheck.dev/docs/checks/#S1021
- S1021
# Omit redundant control flow.
# https://staticcheck.dev/docs/checks/#S1023
- S1023
# Replace 'x.Sub(time.Now())' with 'time.Until(x)'.
# https://staticcheck.dev/docs/checks/#S1024
- S1024
# Don't use 'fmt.Sprintf("%s", x)' unnecessarily.
# https://staticcheck.dev/docs/checks/#S1025
- S1025
# Simplify error construction with 'fmt.Errorf'.
# https://staticcheck.dev/docs/checks/#S1028
- S1028
# Range over the string directly.
# https://staticcheck.dev/docs/checks/#S1029
- S1029
# Use 'bytes.Buffer.String' or 'bytes.Buffer.Bytes'.
# https://staticcheck.dev/docs/checks/#S1030
- S1030
# Omit redundant nil check around loop.
# https://staticcheck.dev/docs/checks/#S1031
- S1031
# Use 'sort.Ints(x)', 'sort.Float64s(x)', and 'sort.Strings(x)'.
# https://staticcheck.dev/docs/checks/#S1032
- S1032
# Unnecessary guard around call to "delete".
# https://staticcheck.dev/docs/checks/#S1033
- S1033
# Use result of type assertion to simplify cases.
# https://staticcheck.dev/docs/checks/#S1034
- S1034
# Redundant call to 'net/http.CanonicalHeaderKey' in method call on 'net/http.Header'.
# https://staticcheck.dev/docs/checks/#S1035
- S1035
# Unnecessary guard around map access.
# https://staticcheck.dev/docs/checks/#S1036
- S1036
# Elaborate way of sleeping.
# https://staticcheck.dev/docs/checks/#S1037
- S1037
# Unnecessarily complex way of printing formatted string.
# https://staticcheck.dev/docs/checks/#S1038
- S1038
# Unnecessary use of 'fmt.Sprint'.
# https://staticcheck.dev/docs/checks/#S1039
- S1039
# Type assertion to current type.
# https://staticcheck.dev/docs/checks/#S1040
- S1040
# Apply De Morgan's law.
# https://staticcheck.dev/docs/checks/#QF1001
- QF1001
# Convert untagged switch to tagged switch.
# https://staticcheck.dev/docs/checks/#QF1002
- QF1002
# Convert if/else-if chain to tagged switch.
# https://staticcheck.dev/docs/checks/#QF1003
- QF1003
# Use 'strings.ReplaceAll' instead of 'strings.Replace' with 'n == -1'.
# https://staticcheck.dev/docs/checks/#QF1004
- QF1004
# Expand call to 'math.Pow'.
# https://staticcheck.dev/docs/checks/#QF1005
- QF1005
# Lift 'if'+'break' into loop condition.
# https://staticcheck.dev/docs/checks/#QF1006
- QF1006
# Merge conditional assignment into variable declaration.
# https://staticcheck.dev/docs/checks/#QF1007
- QF1007
# Omit embedded fields from selector expression.
# https://staticcheck.dev/docs/checks/#QF1008
- QF1008
# Use 'time.Time.Equal' instead of '==' operator.
# https://staticcheck.dev/docs/checks/#QF1009
- QF1009
# Convert slice of bytes to string when printing it.
# https://staticcheck.dev/docs/checks/#QF1010
- QF1010
# Omit redundant type from variable declaration.
# https://staticcheck.dev/docs/checks/#QF1011
- QF1011
# Use 'fmt.Fprintf(x, ...)' instead of 'x.Write(fmt.Sprintf(...))'.
# https://staticcheck.dev/docs/checks/#QF1012
- QF1012
tagalign:
# Align and sort can be used together or separately.
#
# Whether enable align. If true, the struct tags will be aligned.
# E.g.:
# type FooBar struct {
# Bar string `json:"bar" validate:"required"`
# FooFoo int8 `json:"foo_foo" validate:"required"`
# }
# will be formatted to:
# type FooBar struct {
# Bar string `json:"bar" validate:"required"`
# FooFoo int8 `json:"foo_foo" validate:"required"`
# }
# Default: true.
align: false
# Whether enable tags sort.
# If true, the tags will be sorted by name in ascending order.
# E.g.: `xml:"bar" json:"bar" validate:"required"` -> `json:"bar" validate:"required" xml:"bar"`.
# Default: true
sort: false
# Specify the order of tags, the other tags will be sorted by name.
# This option will be ignored if `sort` is false.
# Default: []
order:
- json
- yaml
- yml
- toml
- mapstructure
- binding
- validate
# Whether enable strict style.
# In this style, the tags will be sorted and aligned in the dictionary order,
# and the tags with the same name will be aligned together.
# Note: This option will be ignored if 'align' or 'sort' is false.
# Default: false
strict: true
tagliatelle:
# Checks the struct tag name case.
case:
# Defines the association between tag name and case.
# Any struct tag name can be used.
# Supported string cases:
# - `camel`
# - `pascal`
# - `kebab`
# - `snake`
# - `upperSnake`
# - `goCamel`
# - `goPascal`
# - `goKebab`
# - `goSnake`
# - `upper`
# - `lower`
# - `header`
rules:
json: camel
yaml: camel
xml: camel
toml: camel
bson: camel
avro: snake
mapstructure: kebab
env: upperSnake
envconfig: upperSnake
whatever: snake
# Defines the association between tag name and case.
# Important: the `extended-rules` overrides `rules`.
# Default: empty
extended-rules:
json:
# Supported string cases:
# - `camel`
# - `pascal`
# - `kebab`
# - `snake`
# - `upperSnake`
# - `goCamel`
# - `goPascal`
# - `goKebab`
# - `goSnake`
# - `header`
# - `lower`
# - `header`
#
# Required
case: camel
# Adds 'AMQP', 'DB', 'GID', 'RTP', 'SIP', 'TS' to initialisms,
# and removes 'LHS', 'RHS' from initialisms.
# Default: false
extra-initialisms: true
# Defines initialism additions and overrides.
# Default: empty
initialism-overrides:
DB: true # add a new initialism
LHS: false # disable a default initialism.
# ...
# Uses the struct field name to check the name of the struct tag.
# Default: false
use-field-name: true
# The field names to ignore.
# Default: []
ignored-fields:
- Bar
- Foo
# Overrides the default/root configuration.
# Default: []
overrides:
-
# The package path (uses `/` only as a separator).
# Required
pkg: foo/bar
# Default: empty or the same as the default/root configuration.
rules:
json: snake
xml: pascal
# Default: empty or the same as the default/root configuration.
extended-rules:
# Same options as the base `extended-rules`.
# Default: false (WARNING: it doesn't follow the default/root configuration)
use-field-name: true
# The field names to ignore.
# Default: [] or the same as the default/root configuration.
ignored-fields:
- Bar
- Foo
# Ignore the package (takes precedence over all other configurations).
# Default: false
ignore: true
testifylint:
# Enable all checkers (https://github.com/Antonboom/testifylint#checkers).
# Default: false
enable-all: true
# Disable checkers by name
# (in addition to default
# suite-thelper
# ).
disable:
- blank-import
- bool-compare
- compares
- contains
- empty
- encoded-compare
- equal-values
- error-is-as
- error-nil
- expected-actual
- float-compare
- formatter
- go-require
- len
- negative-positive
- nil-compare
- regexp
- require-error
- suite-broken-parallel
- suite-dont-use-pkg
- suite-extra-assert-call
- suite-method-signature
- suite-subtest-run
- suite-thelper
- useless-assert
# Disable all checkers (https://github.com/Antonboom/testifylint#checkers).
# Default: false
disable-all: true
# Enable checkers by name
# (in addition to default
# blank-import, bool-compare, compares, contains, empty, encoded-compare, equal-values, error-is-as, error-nil,
# expected-actual, go-require, float-compare, formatter, len, negative-positive, nil-compare, regexp, require-error,
# suite-broken-parallel, suite-dont-use-pkg, suite-extra-assert-call, suite-subtest-run, suite-method-signature,
# useless-assert
# ).
enable:
- blank-import
- bool-compare
- compares
- contains
- empty
- encoded-compare
- equal-values
- error-is-as
- error-nil
- expected-actual
- float-compare
- formatter
- go-require
- len
- negative-positive
- nil-compare
- regexp
- require-error
- suite-broken-parallel
- suite-dont-use-pkg
- suite-extra-assert-call
- suite-method-signature
- suite-subtest-run
- suite-thelper
- useless-assert
bool-compare:
# To ignore user defined types (over builtin bool).
# Default: false
ignore-custom-types: true
expected-actual:
# Regexp for expected variable name.
# Default: (^(exp(ected)?|want(ed)?)([A-Z]\w*)?$)|(^(\w*[a-z])?(Exp(ected)?|Want(ed)?)$)
pattern: ^expected
formatter:
# To enable go vet's printf checks.
# Default: true
check-format-string: false
# To require f-assertions (e.g. `assert.Equalf`) if format string is used, even if there are no variable-length
# variables, i.e. it requires `require.NoErrorf` for both these cases:
# - require.NoErrorf(t, err, "unexpected error")
# - require.NoErrorf(t, err, "unexpected error for sid: %v", sid)
# To understand this behavior, please read the
# https://github.com/Antonboom/testifylint?tab=readme-ov-file#historical-reference-of-formatter.
# Default: false
require-f-funcs: true
# To require that the first element of msgAndArgs (msg) has a string type.
# For example, in such case assertion like `assert.True(t, b, tt.case)` will be considered as invalid.
# Default: true
require-string-msg: false
go-require:
# To ignore HTTP handlers (like http.HandlerFunc).
# Default: false
ignore-http-handlers: true
require-error:
# Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.
# Default: ""
fn-pattern: ^(Errorf?|NoErrorf?)$
suite-extra-assert-call:
# To require or remove extra Assert() call?
# Default: remove
mode: require
testpackage:
# Regexp pattern to skip files.
# Default: "(export|internal)_test\\.go"
skip-regexp: (export|internal)_test\.go
# List of packages that don't end with _test that tests are allowed to be in.
# Default: "main"
allow-packages:
- example
- main
thelper:
test:
# Check *testing.T is first param (or after context.Context) of helper function.
# Default: true
first: false
# Check *testing.T param has name t.
# Default: true
name: false
# Check t.Helper() begins helper function.
# Default: true
begin: false
benchmark:
# Check *testing.B is first param (or after context.Context) of helper function.
# Default: true
first: false
# Check *testing.B param has name b.
# Default: true
name: false
# Check b.Helper() begins helper function.
# Default: true
begin: false
tb:
# Check *testing.TB is first param (or after context.Context) of helper function.
# Default: true
first: false
# Check *testing.TB param has name tb.
# Default: true
name: false
# Check tb.Helper() begins helper function.
# Default: true
begin: false
fuzz:
# Check *testing.F is first param (or after context.Context) of helper function.
# Default: true
first: false
# Check *testing.F param has name f.
# Default: true
name: false
# Check f.Helper() begins helper function.
# Default: true
begin: false
usestdlibvars:
# Suggest the use of http.MethodXX.
# Default: true
http-method: false
# Suggest the use of http.StatusXX.
# Default: true
http-status-code: false
# Suggest the use of time.Month in time.Date.
# Default: false
time-date-month: true
# Suggest the use of time.Weekday.String().
# Default: true
time-weekday: true
# Suggest the use of time.Month.String().
# Default: false
time-month: true
# Suggest the use of time.Layout.
# Default: false
time-layout: true
# Suggest the use of crypto.Hash.String().
# Default: false
crypto-hash: true
# Suggest the use of rpc.DefaultXXPath.
# Default: false
default-rpc-path: true
# Suggest the use of sql.LevelXX.String().
# Default: false
sql-isolation-level: true
# Suggest the use of tls.SignatureScheme.String().
# Default: false
tls-signature-scheme: true
# Suggest the use of constant.Kind.String().
# Default: false
constant-kind: true
usetesting:
# Enable/disable `os.CreateTemp("", ...)` detections.
# Default: true
os-create-temp: false
# Enable/disable `os.MkdirTemp()` detections.
# Default: true
os-mkdir-temp: false
# Enable/disable `os.Setenv()` detections.
# Default: true
os-setenv: false
# Enable/disable `os.TempDir()` detections.
# Default: false
os-temp-dir: true
# Enable/disable `os.Chdir()` detections.
# Disabled if Go < 1.24.
# Default: true
os-chdir: false
# Enable/disable `context.Background()` detections.
# Disabled if Go < 1.24.
# Default: false
context-background: true
# Enable/disable `context.TODO()` detections.
# Disabled if Go < 1.24.
# Default: false
context-todo: true
unconvert:
# Remove conversions that force intermediate rounding.
# Default: false
fast-math: true
# Be more conservative (experimental).
# Default: false
safe: true
unparam:
# Inspect exported functions.
# Set to true if no external program/library imports your code.
#
# IMPORTANT: If you enable this setting, unparam reports many false positives in text editors:
# when run on a subdirectory it cannot find external interfaces.
# Most editor integrations invoke golangci-lint on the directory containing the changed file.
#
# Default: false
check-exported: true
unqueryvet:
# Enable SQL builder checking.
# Default: true
check-sql-builders: false
# Enable aliased wildcard detection like `SELECT t.*`.
# Default: true
check-aliased-wildcard: false
# Enable string concatenation analysis.
# Default: true
check-string-concat: false
# Enable format string analysis like `fmt.Sprintf`.
# Default: true
check-format-strings: false
# Enable strings.Builder analysis.
# Default: true
check-string-builder: false
# Enable subquery analysis.
# Default: true
check-subqueries: false
# Detects N+1 Query.
# Default: false
check-n1: true
# Detects SQL injection.
# Default: false
check-sql-injection: true
# Detects transaction leaks.
# Default: false
check-tx-leaks: true
# Regex patterns for acceptable `SELECT *` usage.
# Default:
# - "SELECT \\* FROM information_schema\\..*"
# - "SELECT \\* FROM pg_catalog\\..*"
# - "SELECT COUNT\\(\\*\\)"
# - "SELECT MAX\\(\\*\\)"
# - "SELECT MIN\\(\\*\\)"
allowed-patterns:
- "SELECT \\* FROM temp_.*"
- "SELECT \\* FROM.*-- migration"
# Allow is a list of SQL patterns to allow (whitelist).
# Default: []
allow:
- foo
# Functions to ignore (regex patterns)
# Default: []
ignored-functions:
- "debug\\..*"
- "test.*"
# SQL builder libraries to check.
# Default: all true.
sql-builders:
squirrel: false
gorm: false
sqlx: false
ent: false
pgx: false
bun: false
sqlboiler: false
jet: false
# List of user-defined DSL rules.
# https://github.com/MirrexOne/unqueryvet?tab=readme-ov-file#custom-rules-dsl
# Default: []
custom-rules:
- id: allow-temp-tables
pattern: "SELECT * FROM $TABLE"
when: "isTempTable(table)"
action: allow
- id: dangerous-delete
pattern: "DELETE FROM $TABLE"
when: "!has_where"
message: "DELETE without WHERE clause"
unused:
# Mark all struct fields that have been written to as used.
# Default: true
field-writes-are-uses: false
# Treat IncDec statement (e.g. `i++` or `i--`) as both read and write operation instead of just write.
# Default: false
post-statements-are-reads: true
# Mark all exported fields as used.
# default: true
exported-fields-are-used: false
# Mark all function parameters as used.
# default: true
parameters-are-used: false
# Mark all local variables as used.
# default: true
local-variables-are-used: false
# Mark all identifiers inside generated files as used.
# Default: true
generated-is-used: false
varnamelen:
# The longest distance, in source lines, that is being considered a "small scope".
# Variables used in at most this many lines will be ignored.
# Default: 5
max-distance: 6
# The minimum length of a variable's name that is considered "long".
# Variable names that are at least this long will be ignored.
# Default: 3
min-name-length: 2
# Check method receivers.
# Default: false
check-receiver: true
# Check named return values.
# Default: false
check-return: true
# Check type parameters.
# Default: false
check-type-param: true
# Ignore "ok" variables that hold the bool return value of a type assertion.
# Default: false
ignore-type-assert-ok: true
# Ignore "ok" variables that hold the bool return value of a map index.
# Default: false
ignore-map-index-ok: true
# Ignore "ok" variables that hold the bool return value of a channel receive.
# Default: false
ignore-chan-recv-ok: true
# Optional list of variable names that should be ignored completely.
# Default: []
ignore-names:
- err
# Optional list of variable declarations that should be ignored completely.
# Entries must be in one of the following forms (see below for examples):
# - for variables, parameters, named return values, method receivers, or type parameters:
# ( can also be a pointer/slice/map/chan/...)
# - for constants: const
#
# Default: []
ignore-decls:
- c echo.Context
- t testing.T
- f *foo.Bar
- e error
- i int
- const C
- T any
- m map[string]int
whitespace:
# Enforces newlines (or comments) after every multi-line if statement.
# Default: false
multi-if: true
# Enforces newlines (or comments) after every multi-line function signature.
# Default: false
multi-func: true
wrapcheck:
# An array of strings specifying additional substrings of signatures to ignore.
# Unlike 'ignore-sigs', this option extends the default set (or the set specified in 'ignore-sigs') without replacing it entirely.
# This allows you to add specific signatures to the ignore list
# while retaining the defaults or any items in 'ignore-sigs'.
# Default: []
extra-ignore-sigs:
- .CustomError(
- .SpecificWrap(
# An array of strings that specify substrings of signatures to ignore.
# If this set, it will override the default set of ignored signatures.
# See https://github.com/tomarrell/wrapcheck#configuration for more information.
# Default: [".Errorf(", "errors.New(", "errors.Unwrap(", "errors.Join(", ".Wrap(", ".Wrapf(", ".WithMessage(", ".WithMessagef(", ".WithStack("]
ignore-sigs:
- .Errorf(
- errors.New(
- errors.Unwrap(
- errors.Join(
- .Wrap(
- .Wrapf(
- .WithMessage(
- .WithMessagef(
- .WithStack(
# An array of strings that specify regular expressions of signatures to ignore.
# Default: []
ignore-sig-regexps:
- \.New.*Error\(
# An array of strings that specify globs of packages to ignore.
# Default: []
ignore-package-globs:
- encoding/*
- github.com/pkg/*
# An array of strings that specify regular expressions of interfaces to ignore.
# Default: []
ignore-interface-regexps:
- ^(?i)c(?-i)ach(ing|e)
# Determines whether wrapcheck should report errors returned from inside the package.
# Default: false
report-internal-errors: true
wsl:
# Do strict checking when assigning from append (x = append(x, y)).
# If this is set to true - the append call must append either a variable
# assigned, called or used on the line above.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#strict-append
# Default: true
strict-append: false
# Allows assignments to be cuddled with variables used in calls on
# line above and calls to be cuddled with assignments of variables
# used in call on line above.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-assign-and-call
# Default: true
allow-assign-and-call: false
# Allows assignments to be cuddled with anything.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-assign-and-anything
# Default: false
allow-assign-and-anything: true
# Allows cuddling to assignments even if they span over multiple lines.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-multiline-assign
# Default: true
allow-multiline-assign: false
# If the number of lines in a case block is equal to or lager than this number,
# the case *must* end white a newline.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-case-trailing-whitespace
# Default: 0
force-case-trailing-whitespace: 1
# Allow blocks to end with comments.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-trailing-comment
# Default: false
allow-trailing-comment: true
# Allow multiple comments in the beginning of a block separated with newline.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-separated-leading-comment
# Default: false
allow-separated-leading-comment: true
# Allow multiple var/declaration statements to be cuddled.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-cuddle-declarations
# Default: false
allow-cuddle-declarations: true
# A list of call idents that everything can be cuddled with.
# Defaults: [ "Lock", "RLock" ]
allow-cuddle-with-calls: [ "Foo", "Bar" ]
# AllowCuddleWithRHS is a list of right hand side variables that is allowed
# to be cuddled with anything.
# Defaults: [ "Unlock", "RUnlock" ]
allow-cuddle-with-rhs: [ "Foo", "Bar" ]
# Allow cuddling with any block as long as the variable is used somewhere in
# the block.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-cuddle-used-in-block
# Default: false
allow-cuddle-used-in-block: true
# Causes an error when an If statement that checks an error variable doesn't
# cuddle with the assignment of that variable.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-err-cuddling
# Default: false
force-err-cuddling: true
# When force-err-cuddling is enabled this is a list of names
# used for error variables to check for in the conditional.
# Default: [ "err" ]
error-variable-names: [ "foo" ]
# Causes an error if a short declaration (:=) cuddles with anything other than
# another short declaration.
# This logic overrides force-err-cuddling among others.
# https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-short-decl-cuddling
# Default: false
force-short-decl-cuddling: true
wsl_v5:
# Allow cuddling a variable if it's used first in the immediate following block,
# even if the statement with the block doesn't use the variable.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration
# Default: true
allow-first-in-block: false
# Same as above,
# but allows cuddling if the variable is used anywhere in the following (or nested) block.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration
# Default: false
allow-whole-block: true
# If a block contains more than this number of lines,
# the branch statement needs to be separated by whitespace.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration
# Default: 2
branch-max-lines: 4
# If set to a non-negative number,
# case blocks need to end with whitespace if exceeding this number
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration
# Default: 0
case-max-lines: 2
# Default checks to use.
# Can be `all`, `none`, `default` or empty.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration
# Default: ""
default: all
# Enabled checks.
# Will be additive to any presets.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration
# Default: []
enable:
- assign
- branch
- decl
- defer
- expr
- for
- go
- if
- inc-dec
- label
- range
- return
- select
- send
- switch
- type-switch
- append
- assign-exclusive
- assign-expr
- err
- leading-whitespace
- trailing-whitespace
- after-block
# Disable checks.
# Will be subtractive to any preset.
# https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration
# Default: []
disable:
- assign
- branch
- decl
- defer
- expr
- for
- go
- if
- inc-dec
- label
- range
- return
- select
- send
- switch
- type-switch
- append
- assign-exclusive
- assign-expr
- err
- leading-whitespace
- trailing-whitespace
- after-block
# The custom section can be used to define linter plugins to be loaded at runtime.
# See README documentation for more info.
custom:
# Each custom linter should have a unique name.
example:
# The plugin type.
# It can be `goplugin` or `module`.
# Default: goplugin
type: module
# The path to the plugin *.so. Can be absolute or local.
# Required for each custom linter.
path: /path/to/example.so
# The description of the linter.
# Optional.
description: This is an example usage of a plugin linter.
# Intended to point to the repo location of the linter.
# Optional.
original-url: github.com/golangci/example-linter
# Plugins settings/configuration.
# Only work with plugin based on `linterdb.PluginConstructor`.
# Optional.
settings:
foo: bar
# Defines a set of rules to ignore issues.
# It does not skip the analysis, and so does not ignore "typecheck" errors.
exclusions:
# Mode of the generated files analysis.
#
# - `strict`: sources are excluded by strictly following the Go generated file convention.
# Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\.$`
# This line must appear before the first non-comment, non-blank text in the file.
# https://go.dev/s/generatedcode
# - `lax`: sources are excluded if they contain lines like `autogenerated file`, `code generated`, `do not edit`, etc.
# - `disable`: disable the generated files exclusion.
#
# Default: strict
generated: lax
# Log a warning if an exclusion rule is unused.
# Default: false
warn-unused: true
# Predefined exclusion rules.
# Default: []
presets:
- comments
- std-error-handling
- common-false-positives
- legacy
# Excluding configuration per-path, per-linter, per-text and per-source.
rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
# Run some linter only for test files by excluding its issues for everything else.
- path-except: _test\.go
linters:
- forbidigo
# Exclude known linters from partially hard-vendored code,
# which is impossible to exclude via `nolint` comments.
# `/` will be replaced by the current OS file path separator to properly work on Windows.
- path: internal/hmac/
text: "weak cryptographic primitive"
linters:
- gosec
# Exclude some `staticcheck` messages.
- linters:
- staticcheck
text: "SA9003:"
# Exclude `lll` issues for long lines with `go:generate`.
- linters:
- lll
source: "^//go:generate "
# Which file paths to exclude: they will be analyzed, but issues from them won't be reported.
# "/" will be replaced by the current OS file path separator to properly work on Windows.
# Default: []
paths:
- ".*\\.my\\.go$"
- lib/bad.go
# Which file paths to not exclude.
# Default: []
paths-except:
- ".*\\.my\\.go$"
- lib/bad.go
formatters:
# Enable specific formatter.
# Default: [] (uses standard Go formatting)
enable:
- gci
- gofmt
- gofumpt
- goimports
- golines
- swaggo
# Formatters settings.
settings:
gci:
# Section configuration to compare against.
# Section names are case-insensitive and may contain parameters in ().
# The default order of sections is `standard > default > custom > blank > dot > alias > localmodule`.
# If `custom-order` is `true`, it follows the order of `sections` option.
# Default: ["standard", "default"]
sections:
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
- prefix(github.com/org/project) # Custom section: groups all imports with the specified Prefix.
- blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled.
- dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled.
- alias # Alias section: contains all alias imports. This section is not present unless explicitly enabled.
- localmodule # Local module section: contains all local packages. This section is not present unless explicitly enabled.
# Checks that no inline comments are present.
# Default: false
no-inline-comments: true
# Checks that no prefix comments (comment lines above an import) are present.
# Default: false
no-prefix-comments: true
# Enable custom order of sections.
# If `true`, make the section order the same as the order of `sections`.
# Default: false
custom-order: true
# Drops lexical ordering for custom sections.
# Default: false
no-lex-order: true
gofmt:
# Simplify code: gofmt with `-s` option.
# Default: true
simplify: false
# Apply the rewrite rules to the source before reformatting.
# https://pkg.go.dev/cmd/gofmt
# Default: []
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
- pattern: 'a[b:len(a)]'
replacement: 'a[b:]'
gofumpt:
# Module path which contains the source code being formatted.
# Default: ""
module-path: github.com/org/project
# Choose whether to use the extra rules.
# Default: false
extra-rules: true
goimports:
# A list of prefixes, which, if set, checks import paths
# with the given prefixes are grouped after 3rd-party packages.
# Default: []
local-prefixes:
- github.com/org/project
golines:
# Target maximum line length.
# Default: 100
max-len: 200
# Length of a tabulation.
# Default: 4
tab-len: 8
# Shorten single-line comments.
# Default: false
shorten-comments: true
# Default: true
reformat-tags: false
# Split chained methods on the dots as opposed to the arguments.
# Default: true
chain-split-dots: false
exclusions:
# Log a warning if an exclusion path is unused.
# Default: false
warn-unused: true
# Mode of the generated files analysis.
#
# - `strict`: sources are excluded by strictly following the Go generated file convention.
# Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\.$`
# This line must appear before the first non-comment, non-blank text in the file.
# https://go.dev/s/generatedcode
# - `lax`: sources are excluded if they contain lines like `autogenerated file`, `code generated`, `do not edit`, etc.
# - `disable`: disable the generated files exclusion.
#
# Default: lax
generated: strict
# Which file paths to exclude.
# This option is ignored when using `--stdin` as the path is unknown.
# Default: []
paths:
- ".*\\.my\\.go$"
- lib/bad.go
issues:
# Maximum issues count per one linter.
# Set to 0 to disable.
# Default: 50
max-issues-per-linter: 0
# Maximum count of issues with the same text.
# Set to 0 to disable.
# Default: 3
max-same-issues: 0
# Make issues output unique by line.
# Default: true
uniq-by-line: false
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing large codebase.
# It's not practical to fix all existing issues at the moment of integration:
# much better don't allow issues in new code.
#
# Default: false
new: true
# Show only new issues created after the best common ancestor (merge-base against HEAD).
# Default: ""
new-from-merge-base: main
# Show only new issues created after git revision `REV`.
# Default: ""
new-from-rev: HEAD
# Show only new issues created in git patch with set file path.
# Default: ""
new-from-patch: path/to/patch/file
# Show issues in any part of update files (requires new-from-rev or new-from-patch).
# Default: false
whole-files: true
# Apply the fixes detected by the linters and formatters (if it's supported by the linter).
# Default: false
fix: true
# Output configuration options.
output:
# The formats used to render issues.
formats:
# Prints issues in a text format with colors, line number, and linter name.
# This format is the default format.
text:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.txt
# Print linter name in the end of issue text.
# Default: true
print-linter-name: false
# Print lines of code with issue.
# Default: true
print-issued-lines: false
# Use colors.
# Default: true
colors: false
# Prints issues in a JSON representation.
json:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.json
# Prints issues in columns representation separated by tabulations.
tab:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.txt
# Print linter name in the end of issue text.
# Default: true
print-linter-name: true
# Use colors.
# Default: true
colors: false
# Prints issues in an HTML page.
# It uses the Cloudflare CDN (cdnjs) and React.
html:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.html
# Prints issues in the Checkstyle format.
checkstyle:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.xml
# Prints issues in the Code Climate format.
code-climate:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.json
# Prints issues in the JUnit XML format.
junit-xml:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.xml
# Support extra JUnit XML fields.
# Default: false
extended: true
# Prints issues in the TeamCity format.
teamcity:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.txt
# Prints issues in the SARIF format.
sarif:
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Default: stdout
path: ./path/to/output.json
# Add a prefix to the output file references.
# This option is ignored when using `output.path-mode: abs` mode.
# Default: ""
path-prefix: ""
# By default, the report are related to the path obtained by `run.relative-path-mode`.
# The mode `abs` allows to show absolute file paths instead of relative file paths.
# The option `output.path-prefix` is ignored when using `abs` mode.
# Default: ""
path-mode: "abs"
# Order to use when sorting results.
# Possible values: `file`, `linter`, and `severity`.
#
# If the severity values are inside the following list, they are ordered in this order:
# 1. error
# 2. warning
# 3. high
# 4. medium
# 5. low
# Either they are sorted alphabetically.
#
# Default: ["linter", "file"]
sort-order:
- linter
- severity
- file # filepath, line, and column.
# Show statistics per linter.
# Default: true
show-stats: false
# Options for analysis running.
run:
# Timeout for total work, e.g. 30s, 5m, 5m30s.
# If the value is lower or equal to 0, the timeout is disabled.
# Default: 0 (disabled)
timeout: 5m
# The mode used to evaluate relative paths.
# It's used by exclusions, Go plugins, and some linters.
# The value can be:
# - `gomod`: the paths will be relative to the directory of the `go.mod` file.
# - `gitroot`: the paths will be relative to the git root (the parent directory of `.git`).
# - `cfg`: the paths will be relative to the configuration file.
# - `wd` (NOT recommended): the paths will be relative to the place where golangci-lint is run.
# Default: cfg
relative-path-mode: gomod
# Exit code when at least one issue was found.
# Default: 1
issues-exit-code: 2
# Include test files or not.
# Default: true
tests: false
# List of build tags, all linters use it.
# Default: []
build-tags:
- mytag
# If set, we pass it to "go list -mod={option}". From "go help modules":
# If invoked with -mod=readonly, the go command is disallowed from the implicit
# automatic updating of go.mod described above. Instead, it fails when any changes
# to go.mod are needed. This setting is most useful to check that go.mod does
# not need updates, such as in a continuous integration and testing system.
# If invoked with -mod=vendor, the go command assumes that the vendor
# directory holds the correct copies of dependencies and ignores
# the dependency descriptions in go.mod.
#
# Allowed values: readonly|vendor|mod
# Default: ""
modules-download-mode: readonly
# Uses version control information during the loading of packages.
# Default: false (implies `-buildvcs=false`)
enable-build-vcs: true
# Allow multiple parallel golangci-lint instances running.
# If false, golangci-lint acquires file lock on start.
# Default: false
allow-parallel-runners: true
# Allow multiple golangci-lint instances running, but serialize them around a lock.
# If false, golangci-lint exits with an error if it fails to acquire file lock on start.
# Default: false
allow-serial-runners: true
# Define the Go version limit.
# Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.22.
go: '1.23'
# Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously.
# Default: 0 (automatically set to match Linux container CPU quota and
# fall back to the number of logical CPUs in the machine)
concurrency: 4
severity:
# Set the default severity for issues.
#
# If severity rules are defined and the issues do not match or no severity is provided to the rule
# this will be the default severity applied.
# Severities should match the supported severity names of the selected out format.
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#SeverityLevel
# - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
# - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance
#
# `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
#
# Default: ""
default: error
# When a list of severity rules are provided, severity information will be added to lint issues.
# Severity rules have the same filtering capability as exclude rules
# except you are allowed to specify one matcher per severity rule.
#
# `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
#
# Only affects out formats that support setting severity information.
#
# Default: []
rules:
- linters:
- dupl
severity: info
================================================
FILE: .golangci.yml
================================================
# This configuration file is not a recommendation.
#
# We intentionally use a limited set of linters.
# This configuration file is used with different version of golangci-lint to avoid regressions:
# the linters can change between version,
# their configuration may be not compatible or their reports can be different,
# and this can break some of our tests.
# Also, some linters are not relevant for the project (e.g. linters related to SQL).
#
# We have specific constraints, so we use a specific configuration.
#
# See the file `.golangci.reference.yml` to have a list of all available configuration options.
version: "2"
linters:
default: none
# This list of linters is not a recommendation (same thing for all this configuration file).
# We intentionally use a limited set of linters.
# See the comment on top of this file.
enable:
- bodyclose
- copyloopvar
- depguard
- dogsled
- dupl
- errcheck
- errorlint
- funlen
- gocheckcompilerdirectives
- gochecknoinits
- goconst
- gocritic
- gocyclo
- godox
- mnd
- goprintffuncname
- gosec
- govet
- intrange
- ineffassign
- lll
- misspell
- nakedret
- noctx
- nolintlint
- revive
- staticcheck
- testifylint
- unconvert
- unparam
- unused
- whitespace
settings:
depguard:
rules:
logger:
deny:
# logging is allowed only by logutils.Log,
- pkg: "github.com/sirupsen/logrus"
desc: logging is allowed only by logutils.Log.
- pkg: "github.com/pkg/errors"
desc: Should be replaced by standard lib errors package.
- pkg: "github.com/instana/testify"
desc: It's a fork of github.com/stretchr/testify.
files:
# logrus is allowed to use only in logutils package.
- "!**/pkg/logutils/**.go"
dupl:
threshold: 100
funlen:
lines: -1 # the number of lines (code + empty lines) is not a right metric and leads to code without empty line or one-liner.
statements: 50
goconst:
min-len: 2
min-occurrences: 3
gocritic:
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
gocyclo:
min-complexity: 15
godox:
keywords:
- FIXME
mnd:
# don't include the "operation" and "assign"
checks:
- argument
- case
- condition
- return
ignored-numbers:
- '0'
- '1'
- '2'
- '3'
ignored-functions:
- strings.SplitN
govet:
settings:
printf:
funcs:
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Fatalf
enable:
- nilness
- shadow
errorlint:
asserts: false
lll:
line-length: 140
misspell:
locale: US
ignore-rules:
- "importas" # linter name
nolintlint:
allow-unused: false # report any unused nolint directives
require-explanation: true # require an explanation for nolint directives
require-specific: true # require nolint directives to be specific about which linter is being skipped
revive:
rules:
- name: indent-error-flow
- name: unexported-return
disabled: true
- name: unused-parameter
- name: unused-receiver
exclusions:
presets:
- comments
- std-error-handling
- common-false-positives
- legacy
paths:
- test/testdata_etc # test files
- internal/go # extracted from Go code
- internal/x # extracted from x/tools code
- pkg/goformatters/gci/internal # extracted from gci code
- pkg/goanalysis/runner_checker.go # extracted from x/tools code
rules:
- path: (.+)_test\.go
linters:
- dupl
- mnd
- lll
# Based on existing code, the modifications should be limited to make maintenance easier.
- path: pkg/golinters/unused/unused.go
linters: [gocritic]
text: "rangeValCopy: each iteration copies 160 bytes \\(consider pointers or indexing\\)"
# Related to the result of computation but divided multiple times by 1024.
- path: test/bench/bench_test.go
linters: [gosec]
text: "G115: integer overflow conversion uint64 -> int"
# The files created during the tests don't need to be secured.
- path: scripts/website/expand_templates/linters_test.go
linters: [gosec]
text: "G306: Expect WriteFile permissions to be 0600 or less"
# For compatibility with previous versions.
# Also, those reports are not relevant.
- linters: [gosec]
text: "(G704: SSRF via taint analysis|G703: Path traversal via taint analysis|G702: Command injection via taint analysis|G115: integer overflow conversion uintptr)"
# Related to migration command.
- path: pkg/commands/internal/migrate/two/
linters:
- lll
# Related to migration command.
- path: pkg/commands/internal/migrate/
linters:
- gocritic
text: "hugeParam:"
# The codes are close but this is not duplication.
- path: pkg/commands/(formatters|linters).go
linters:
- dupl
# Deprecated linters
- path: pkg/lint/lintersdb/builder_linter.go
text: "SA1019: wsl.NewV4 is deprecated: use NewV5 instead."
linters:
- staticcheck
- path: pkg/golinters/wsl/wsl.go
text: "SA1019: config.WSLv4Settings is deprecated: use WSLv5Settings instead."
linters:
- staticcheck
formatters:
enable:
- gofmt
- goimports
settings:
gofmt:
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
goimports:
local-prefixes:
- github.com/golangci/golangci-lint/v2
exclusions:
paths:
- test/testdata_etc # test files
- internal/go # extracted from Go code
- internal/x # extracted from x/tools code
- pkg/goformatters/gci/internal # extracted from gci code
- pkg/goanalysis/runner_checker.go # extracted from x/tools code
================================================
FILE: .goreleaser.yml
================================================
version: 2
project_name: golangci-lint
builds:
- binary: golangci-lint
main: ./cmd/golangci-lint/
flags:
- -trimpath
ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.ShortCommit}} -X main.date={{.Date}}
env:
- CGO_ENABLED=0
goos:
- darwin
- windows
- linux
- freebsd
- netbsd
- illumos
goarch:
- amd64
- arm64
- arm
- 386
- ppc64le
- s390x
- mips64
- mips64le
- riscv64
- loong64
goarm:
- 6
- 7
gomips:
- hardfloat
ignore:
- goos: darwin
goarch: 386
# Deprecated in go1.25, Removed in go1.26
# https://go.dev/doc/go1.25#windows
- goos: windows
goarch: arm
archives:
- formats: [ 'tar.gz' ]
wrap_in_directory: true
format_overrides:
- goos: windows
formats: [ 'zip' ]
name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
files:
- LICENSE
- README.md
snapshot:
version_template: SNAPSHOT-{{ .Commit }}
checksum:
disable: false
name_template: '{{ .ProjectName }}-{{ .Version }}-checksums.txt'
changelog:
sort: asc
filters:
exclude:
- '(?i)^docs?:'
- '(?i)^docs\([^:]+\):'
- '(?i)^docs\[[^:]+\]:'
- '^tests?:'
- '(?i)^dev:'
- '(?i)^chore:'
- '^build\(deps\): bump .* in /docs \(#\d+\)'
- '^build\(deps\): bump .* in /\.github/peril \(#\d+\)'
- '^build\(deps\): bump .* in /scripts/gen_github_action_config \(#\d+\)'
- Merge pull request
- Merge branch
release:
skip_upload: false
github:
owner: golangci
name: golangci-lint
header: |
`golangci-lint` is a free and open-source project built by volunteers.
If you value it, consider supporting us, the [maintainers](https://donate.golangci.org) and [linter authors](https://golangci-lint.run/docs/product/thanks/).
We appreciate it! :heart:
For key updates, see the [changelog](https://golangci-lint.run/docs/product/changelog/#{{ .Major }}{{ .Minor }}{{ .Patch }}).
source:
enabled: true
name_template: '{{ .ProjectName }}-{{ .Version }}-source'
brews:
- description: Fast linters runner for Go.
homepage: https://golangci.com
skip_upload: false
repository:
owner: golangci
name: homebrew-tap
commit_author:
name: golangci-releaser
email: 65486276+golangci-releaser@users.noreply.github.com
directory: Formula
install: |
bin.install "golangci-lint"
output = Utils.popen_read("#{bin}/golangci-lint completion bash")
(bash_completion/"golangci-lint").write output
output = Utils.popen_read("#{bin}/golangci-lint completion zsh")
(zsh_completion/"_golangci-lint").write output
output = Utils.popen_read("#{bin}/golangci-lint completion fish")
(fish_completion/"golangci-lint.fish").write output
prefix.install_metafiles
test: |
system "#{bin}/golangci-lint --version"
## chocolatey is disabled because mono has been removed from GitHub Actions runners due to security and maintenance concerns.
## The release is done manually and locally, with goreleaser after the release of the other elements.
## Note(ldez): add documentation about how to do it.
#chocolateys:
# - summary: Fast linters Runner for Go
# description: |
# {{ .ProjectName }} installer package.
# Fast linters Runner for Go.
# project_url: https://golangci-lint.run
# skip_publish: false
# name: golangci-lint
# title: Golangci-lint
# owners: golangci
# authors: golangci
# copyright: 2024 GolangCI
# url_template: "https://github.com/golangci/golangci-lint/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# icon_url: "https://cdn.rawgit.com/golangci/golangci-lint/HEAD/assets/go.png"
# license_url: https://github.com/golangci/golangci-lint/blob/HEAD/LICENSE
# require_license_acceptance: false
# project_source_url: https://github.com/golangci/golangci-lint
# package_source_url: https://github.com/golangci/golangci-lint
# docs_url: https://golangci-lint.run
# bug_tracker_url: https://github.com/golangci/golangci-lint/issues
# tags: "go golang lint linter"
# release_notes: "https://github.com/golangci/golangci-lint/releases/tag/v{{ .Version }}"
# api_key: "{{ .Env.CHOCOLATEY_API_KEY }}"
# source_repo: "https://push.chocolatey.org/"
# goamd64: v1
aurs:
- description: Fast linters runner for Go.
skip_upload: false
homepage: https://golangci.com
provides:
- "golangci-lint-bin"
maintainers:
- "Fernandez Ludovic "
license: GPL-3.0
private_key: "{{ .Env.AUR_KEY }}"
git_url: "ssh://aur@aur.archlinux.org/golangci-lint-bin.git"
commit_author:
name: golangci-releaser
email: 65486276+golangci-releaser@users.noreply.github.com
package: |-
local x86_64=amd64 i686=386 aarch64=arm64 armv6h=armv6 armv7h=armv7
cd "golangci-lint-${pkgver}-linux-${!CARCH}"
# bin
install -Dm755 "./golangci-lint" "${pkgdir}/usr/bin/golangci-lint"
# license
install -Dm644 "./LICENSE" "${pkgdir}/usr/share/licenses/golangci-lint/LICENSE"
# completions
mkdir -p "${pkgdir}/usr/share/bash-completion/completions/"
mkdir -p "${pkgdir}/usr/share/zsh/site-functions/"
mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/"
./golangci-lint completion bash | install -Dm644 /dev/stdin "${pkgdir}/usr/share/bash-completion/completions/golangci-lint"
./golangci-lint completion zsh | install -Dm644 /dev/stdin "${pkgdir}/usr/share/zsh/site-functions/_golangci-lint"
./golangci-lint completion fish | install -Dm644 /dev/stdin "${pkgdir}/usr/share/fish/vendor_completions.d/golangci-lint.fish"
snapcrafts:
- summary: Fast linters runner for Go.
description: |
It runs linters in parallel, uses caching, supports YAML configuration, integrates with all major IDEs, and includes over a hundred linters.
disable: false
publish: true
name_template: "{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
grade: stable
confinement: classic
license: GPL-3.0
base: core22
nfpms:
- description: Fast linters Runner for Go
homepage: https://golangci-lint.run/
id: golangci-lint-nfpms
package_name: golangci-lint
file_name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
maintainer: "Golangci-lint Maintainers <65486276+golangci-releaser@users.noreply.github.com>"
license: GPLv3
vendor: golangci
section: golang
formats:
- deb
- rpm
umask: 0o022
overrides:
deb:
contents:
- src: LICENSE
dst: /usr/share/doc/golangci-lint/copyright
- src: README.md
dst: /usr/share/doc/golangci-lint/README.md
recommends:
- golang-go
rpm:
contents:
- src: LICENSE
dst: /usr/share/doc/golangci-lint/LICENSE
type: license
- src: README.md
dst: /usr/share/doc/golangci-lint/README.md
type: readme
recommends:
- /usr/bin/go
rpm:
group: Development/Tools
dockers_v2:
- id: golangci-lint
images:
- 'golangci/golangci-lint'
dockerfile: build/buildx.Dockerfile
platforms:
- linux/amd64
- linux/arm64
tags:
- 'latest'
- '{{ .Tag }}'
- 'v{{ .Major }}.{{ .Minor }}'
labels:
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
'org.opencontainers.image.title': '{{.ProjectName}}'
'org.opencontainers.image.description': 'Fast linters Runner for Go'
'org.opencontainers.image.source': '{{.GitURL}}'
'org.opencontainers.image.url': '{{.GitURL}}'
'org.opencontainers.image.documentation': 'https://golangci-lint.run'
'org.opencontainers.image.created': '{{.Date}}'
'org.opencontainers.image.revision': '{{.FullCommit}}'
'org.opencontainers.image.version': '{{.Version}}'
- id: golangci-lint-alpine
images:
- 'golangci/golangci-lint'
dockerfile: build/buildx-alpine.Dockerfile
platforms:
- linux/amd64
- linux/arm64
tags:
- 'latest-alpine'
- '{{ .Tag }}-alpine'
- 'v{{ .Major }}.{{ .Minor }}-alpine'
labels:
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
'org.opencontainers.image.title': '{{.ProjectName}}'
'org.opencontainers.image.description': 'Fast linters Runner for Go'
'org.opencontainers.image.source': '{{.GitURL}}'
'org.opencontainers.image.url': '{{.GitURL}}'
'org.opencontainers.image.documentation': 'https://golangci-lint.run'
'org.opencontainers.image.created': '{{.Date}}'
'org.opencontainers.image.revision': '{{.FullCommit}}'
'org.opencontainers.image.version': '{{.Version}}'
================================================
FILE: .pre-commit-hooks.yaml
================================================
- id: golangci-lint
name: golangci-lint
description: Fast linters runner for Go. Note that only modified files are linted, so linters like 'unused' that need to scan all files won't work as expected.
entry: golangci-lint run --new-from-rev HEAD --fix
types: [go]
language: golang
require_serial: true
pass_filenames: false
- id: golangci-lint-full
name: golangci-lint-full
description: Fast linters runner for Go. Runs on all files in the module. Use this hook if you use pre-commit in CI.
entry: golangci-lint run --fix
types: [go]
language: golang
require_serial: true
pass_filenames: false
- id: golangci-lint-fmt
name: golangci-lint-fmt
description: Fast linters runner for Go. Formats all files in the repo.
entry: golangci-lint fmt
types: [go]
language: golang
require_serial: true
pass_filenames: false
- id: golangci-lint-config-verify
name: golangci-lint-config-verify
description: Verifies the configuration file
entry: golangci-lint config verify
files: '\.golangci\.(?:yml|yaml|toml|json)'
language: golang
pass_filenames: false
================================================
FILE: CHANGELOG-v1.md
================================================
Follow the news and releases on [Mastodon](https://fosstodon.org/@golangcilint) and on [Bluesky](https://bsky.app/profile/golangci-lint.run).
`golangci-lint` is a free and open-source project built by volunteers.
If you value it, consider supporting us, we appreciate it!
[](https://donate.golangci.org)
### v1.64.8
_Released on 2025-03-17_
* Detects use of configuration files from golangci-lint v2
### v1.64.7
_Released on 2025-03-11_
1. Linters bug fixes
* `depguard`: from 2.2.0 to 2.2.1
* `dupl`: from 3e9179ac440a to f665c8d69b32
* `gosec`: from 2.22.1 to 2.22.2
* `staticcheck`: from 0.6.0 to 0.6.1
2. Documentation
* Add GitLab documentation
### v1.64.6
_Released on 2025-03-02_
1. Linters bug fixes
* `asciicheck`: from 0.4.0 to 0.4.1
* `contextcheck`: from 1.1.5 to 1.1.6
* `errcheck`: from 1.8.0 to 1.9.0
* `exptostd`: from 0.4.1 to 0.4.2
* `ginkgolinter`: from 0.19.0 to 0.19.1
* `go-exhaustruct`: from 3.3.0 to 3.3.1
* `gocheckcompilerdirectives`: from 1.2.1 to 1.3.0
* `godot`: from 1.4.20 to 1.5.0
* `perfsprint`: from 0.8.1 to 0.8.2
* `revive`: from 1.6.1 to 1.7.0
* `tagalign`: from 1.4.1 to 1.4.2
### v1.64.5
_Released on 2025-02-13_
1. Bug fixes
* Add missing flag `new-from-merge-base-flag`
2. Linters bug fixes
* `asciicheck`: from 0.3.0 to 0.4.0
* `forcetypeassert`: from 0.1.0 to 0.2.0
* `gosec`: from 2.22.0 to 2.22.1
### v1.64.4
_Released on 2025-02-12_
1. Linters bug fixes
* `gci`: fix standard packages list for go1.24
### v1.64.3
_Released on 2025-02-12_
1. Linters bug fixes
* `ginkgolinter`: from 0.18.4 to 0.19.0
* `go-critic`: from 0.11.5 to 0.12.0
* `revive`: from 1.6.0 to 1.6.1
* `gci`: fix standard packages list for go1.24
2. Misc.
* Build Docker images with go1.24
### v1.64.2
_Released on 2025-02-11_
This is the last minor release of golangci-lint v1.
The next release will be golangci-lint [v2](https://github.com/golangci/golangci-lint/issues/5300).
1. Enhancements
* 🎉 go1.24 support
* New `issues.new-from-merge-base` option
* New `run.relative-path-mode` option
2. Linters new features
* `copyloopvar`: from 1.1.0 to 1.2.1 (support suggested fixes)
* `exptostd`: from 0.3.1 to 0.4.1 (handles `golang.org/x/exp/constraints.Ordered`)
* `fatcontext`: from 0.5.3 to 0.7.1 (new option: `check-struct-pointers`)
* `perfsprint`: from 0.7.1 to 0.8.1 (new options: `integer-format`, `error-format`, `string-format`, `bool-format`, and `hex-format`)
* `revive`: from 1.5.1 to 1.6.0 (new rules: `redundant-build-tag`, `use-errors-new`. New option `early-return.early-return`)
3. Linters bug fixes
* `go-errorlint`: from 1.7.0 to 1.7.1
* `gochecknoglobals`: from 0.2.1 to 0.2.2
* `godox`: from 006bad1f9d26 to 1.1.0
* `gosec`: from 2.21.4 to 2.22.0
* `iface`: from 1.3.0 to 1.3.1
* `nilnesserr`: from 0.1.1 to 0.1.2
* `protogetter`: from 0.3.8 to 0.3.9
* `sloglint`: from 0.7.2 to 0.9.0
* `spancheck`: fix default `StartSpanMatchersSlice` values
* `staticcheck`: from 0.5.1 to 0.6.0
4. Deprecations
* ⚠️ `tenv` is deprecated and replaced by `usetesting.os-setenv: true`.
* ⚠️ `exportloopref` deprecation step 2
5. Misc.
* Sanitize severities by output format
* Avoid panic with plugin without description
6. Documentation
* Clarify `depguard` configuration
### v1.64.1
_Released on 2025-02-11_
Cancelled due to CI failure.
### v1.64.0
_Released on 2025-02-11_
Cancelled due to CI failure.
### v1.63.4
_Released on 2025-01-03_
1. Linters bug fixes
* `dupl`, `gomodguard`, `revive`: keep only Go-files.
### v1.63.3
_Released on 2025-01-02_
1. Linters bug fixes
* `gofmt`, `gofumpt`, `goimports`, `gci`: panic with several trailing EOL
* `goheader`: skip issues with invalid positions
### v1.63.2
_Released on 2025-01-02_
1. Linters bug fixes
* `gofmt`, `gofumpt`, `goimports`, `gci`: panic with missing trailing EOL
### v1.63.1
_Released on 2025-01-01_
1. Linters bug fixes
* `cgi`: invalid reports with cgo
* `gofumpt`: panic with autofix and cgo
### v1.63.0
_Released on 2025-01-01_
1. Enhancements
* Add support for SuggestedFixes 🎉 (35 linters can "autofix" reports).
* Formatters (`gofmt`, `goimports`, `gofumpt`, `gci`) are applied after the suggested fixes.
2. New linters
* Add `exptostd` linter https://github.com/ldez/exptostd
* Add `nilnesserr` linter https://github.com/alingse/nilnesserr
* Add `usetesting` linter https://github.com/ldez/usetesting
3. Linters new features
* `gci`: new options: `no-inline-comments`, `no-prefix-comments`
* `gomoddirectives`: from 0.2.4 to 0.6.0 (new options: `go-version-pattern`, `toolchain-pattern`,`toolchain-forbidden`, `tool-forbidden`, `go-debug-forbidden`)
* `govet`: new `stdversion`, `waitgroup` analyzers
* `importas`: allow multiple empty aliases
* `loggercheck`: new `slog` option
* `recvcheck`: from 0.1.2 to 0.2.0 (new options: `disable-builtin`, `exclusions`)
* `tagliatelle`: from 0.5.0 to 0.7.1 (new options: `ignored-fields`, `extended-rules`,`overrides`, `pkg`, `ignore`)
* `usestdlibvars`: from 1.27.0 to 1.28.0 (autofix)
* `wrapcheck`: from 2.9.0 to 2.10.0 (new option: `extra-ignore-sigs`)
4. Linters bug fixes
* `asciicheck`: from 0.2.0 to 0.3.0
* `bodyclose`: from 574207250966 to ed6a65f985e
* `funlen`: from 0.1.0 to 0.2.0
* `ginkgolinter`: from 0.18.3 to 0.18.4
* `gochecksumtype`: from 0.2.0 to 0.3.1
* `gocognit`: from 1.1.3 to 1.2.0
* `godot`: from 1.4.18 to 1.4.20
* `goheader`: report position improvement
* `gosec`: handling of global nosec option when it is false
* `iface`: from 1.2.1 to 1.3.0
* `importas`: from 0.1.0 to 0.2.0
* `intrange`: from 0.2.1 to 0.3.0
* `makezero`: from 1.1.1 to 1.2.0
* `mirror`: from 1.2.0 to 1.3.0
* `nilnil`: from 1.0.0 to 1.0.1
* `nosprintfhostport`: from 0.1.1 to 0.2.0
* `reassign`: from 0.2.0 to 0.3.0
* `spancheck`: from 0.6.2 to 0.6.4
* `tagalign`: from 1.3.4 to 1.4.1
* `wastedassign`: from 2.0.7 to 2.1.0
* `whitespace`: from 0.1.1 to 0.2.0
* `wsl`: from 4.4.1 to 4.5.0
5. Deprecations
* ⚠️ `output.uniq-by-line` is deprecated and replaced by `issues.uniq-by-line`.
6. Misc.
* Improvements of the help command (color and JSON support).
* Removes `decoder`, `sloglint`, `tagalign` from `format` preset.
* Enables paths with junction inside Windows.
* The timeout is disabled if `run.timeout` <= 0.
### v1.62.2
_Released on 2024-11-25_
1. Linters bug fixes
* `fatcontext`: from 0.5.2 to 0.5.3
* `ginkgolinter`: from 0.18.0 to 0.18.3
* `errorlint`: from 1.6.0 to 1.7.0
* `iface`: from 1.2.0 to 1.2.1
* `revive`: from 1.5.0 to 1.5.1
* `testifylint`: from 1.5.0 to 1.5.2
2. Misc.
* fix: ignore cache error when file not found
### v1.62.1
_Released on 2024-11-25_
Cancelled due to CI failure.
### v1.62.0
_Released on 2024-11-10_
1. New linters
* Add `recvcheck` linter https://github.com/raeperd/recvcheck
* Add `iface` linter https://github.com/uudashr/iface
2. Linters new features
* `ginkgolinter`: from 0.17.0 to 0.18.0 (new option: `force-succeed`)
* `gochecksumtype`: from 0.1.4 to 0.2.0 (new option: `default-signifies-exhaustive`)
* `loggercheck`: from 0.9.4 to 0.10.1 (`log/slog` support)
* `nilnil`: from 0.1.9 to 1.0.0 (new option: `detect-opposite`)
* `revive`: from 1.3.9 to 1.5.0 (new rules: `filename-format`, and `file-length-limit`)
* `tenv`: from 1.10.0 to 1.12.1 (handle dot import)
* `testifylint`: from 1.4.3 to 1.5.0 (new checkers: `contains`, `encoded-compare`, `regexp`)
3. Linters bug fixes
* `bidichk`: from 0.2.7 to 0.3.2 (important performance improvement)
* `canonicalheader`: from 1.1.1 to 1.1.2
* `cyclop`: from 1.2.1 to 1.2.3
* `dupword`: from 0.1.1 to 0.1.3
* `errcheck`: from 1.7.0 to 1.8.0
* `errchkjson`: from 0.3.6 to 0.4.0
* `errname`: from 0.1.13 to 1.0.0
* `gocritic`: from 0.11.4 to 0.11.5
* `goprintffuncname`: from 7558a9eaa5af to v0.1.0
* `godot`: from 1.4.17 to 1.4.18
* `gosec`: from 2.21.2 to 2.21.4
* `intrange`: from 0.2.0 to 0.2.1
* `musttag`: from 0.12.2 to 0.13.0
* `nakedret`: from 2.0.4 to 2.0.5
* `noctx`: from 0.0.2 to 0.1.0
* `protogetter`: from 0.3.6 to 0.3.8
4. Deprecations
* ⚠️ `execinquery`: deprecation step 2
* ⚠️ `gomnd`: deprecation step 2 (replaced by `mnd`)
5. Misc.
* Type sizing when cross-compiling (32-bit).
* code-climate: add check_name field
* Improve Go version detection
* Fix Go version propagation
6. Documentation
* Adds a section about `exclude-dirs-use-default`
* Improve 'install from sources' section
* Improve FAQ about Go versions
* Improve linter/rule/check docs
* Improve new linter section
* Improve `forbidigo` pattern examples for built-in functions
### v1.61.0
_Released on 2024-09-09_
1. Enhancements
* Add `junit-xml-extended` format
* Exclude Swagger Codegen files by default
2. Linters new features
* `gci`: from 0.13.4 to 0.13.5 (new option `no-lex-order`)
* `nolintlint`: remove the empty line in the directive replacement
3. Linters bug fixes
* `dupword`: from 0.0.14 to 0.1.1
* `fatcontext`: from 0.4.0 to 0.5.2
* `go-ruleguard`: from 0.4.2 to 0fe6f58b47b1 (fix panic with custom linters)
* `godot`: from 1.4.16 to 1.4.17
* `gomodguard`: from 1.3.3 to 1.3.5
* `gosec`: disable temporarily `G407`
* `gosec`: from ab3f6c1c83a0 to 2.21.2 (partially fix `G115`)
* `intrange`: from 0.1.2 to 0.2.0
4. Misc.
* Improve runtime version parsing
5. Documentation
* Add additional info about `typecheck`
### v1.60.3
_Released on 2024-08-22_
1. Updated linters
* `gosec`: from 81cda2f91fbe to ab3f6c1c83a0 (fix `G115` false positives)
2. Misc.
* Check that the Go version use to build is greater or equals to the Go version of the project
### v1.60.2
_Released on 2024-08-20_
1. Linters new features
* `gosec`: from 5f0084eb01a9 to 81cda2f91fbe (adds `G115`, `G405`, `G406`, `G506`, `G507`)
2. Linters bug fixes
* `gofmt`: update to HEAD (go1.22)
* `gofumpt`: from 0.6.0 to 0.7.0
* `gosec`: fix G602 analyzer
* `staticcheck`: from 0.5.0 to 0.5.1
* `staticcheck`: propagate Go version
* `wrapcheck`: from 2.8.3 to 2.9.0
3. Deprecations
* ⚠️ `exportloopref`: deprecation
### v1.60.1
_Released on 2024-08-14_
1. Misc.
* 🎉 go1.23 support
2. Linters new features
* `exhaustruct`: from 3.2.0 to 3.3.0 (recognize custom error values in return)
* `govet` (`printf`): report non-constant format, no args
* `lll`: advertise max line length instead of just reporting failure
* `revive`: from 1.3.7 to 1.3.9 (new rule: `comments-density`)
* `staticcheck`: from 0.4.7 to 0.5.0
* `testifylint`: from 1.3.1 to 1.4.3 (new options: `formatter`, `suite-broken-parallel`, `suite-subtest-run`)
3. Linters bug fixes
* `errorlint`: from 1.5.2 to 1.6.0
* `fatcontext`: from 0.2.2 to 0.4.0 (fix false positives for context stored in structs)
* `gocognit`: from 1.1.2 to 1.1.3
* `gomodguard`: from 1.3.2 to 1.3.3
* `sloglint`: from 0.7.1 to 0.7.2
* `spancheck`: from 0.6.1 to 0.6.2
* `tenv`: from 1.7.1 to 1.10.0 (remove reports on fuzzing)
* `tparallel`: from 0.3.1 to 0.3.2
* `usestdlibvars`: from 1.26.0 to 1.27.0 (fix false-positive with number used inside a mathematical operations)
* `wsl`: from 4.2.1 to 4.4.1
4. Deprecations
* ️⚠️ `unused`: remove `exported-is-used` option
5. Fixes
* SARIF: sanitize level property
* ️⚠️ `typecheck` issues should never be ignored
6. Documentation
* Add link on linter without configuration
* Remove 'trusted by' page
* `wsl` update documentation of the configuration
### v1.60.0
_Released on 2024-08-13_
Cancelled due to a CI problem.
### v1.59.1
_Released on 2024-06-09_
1. Updated linters
* `errorlint`: from 1.5.1 to 1.5.2
* `gomnd`: deprecated configuration compatibility
* `intrange`: add `style` preset
* `misspell`: from 0.5.1 to 0.6.0
* `sloglint`: from 0.7.0 to 0.7.1
* `testifylint`: from 1.3.0 to 1.3.1
* `unparam`: bump to HEAD
* `usestdlibvars`: from 1.25.0 to 1.26.0
2. Fixes
* SARIF: init empty result slice
* SARIF: issue column >= 1
3. Documentation
* `revive`: update documentation of the configuration
### v1.59.0
_Released on 2024-05-26_
1. Enhancements
* Add SARIF output format
* Allow the analysis of generated files (`issues.exclude-generated: disable`)
2. Updated linters
* `errcheck`: fix deprecation warning
* `gocritic`: from 0.11.3 to 0.11.4
* `gosec`: from 2.20.0 to 5f0084eb01a9 (fix G601 and G113 performance issues)
* `sloglint`: from 0.6.0 to 0.7.0 (new option `forbidden-keys`)
* `testifylint`: from 1.2.0 to 1.3.0 (new checker `negative-positive` and new option `go-require.ignore-http-handlers`)
3. Misc.
* ️️⚠️ Deprecate `github-action` output format
* ️️⚠️ Deprecate `issues.exclude-generated-strict` option (replaced by `issues.exclude-generated: strict`)
* ️️⚠️ Add warning about disabled and deprecated linters (level 2)
### v1.58.2
_Released on 2024-05-19_
1. Updated linters
* `canonicalheader`: from 1.0.6 to 1.1.1
* `gosec`: from 2.19.0 to 2.20.0
* `musttag`: from 0.12.1 to 0.12.2
* `nilnil`: from 0.1.8 to 0.1.9
2. Documentation
* Improve integrations and install pages
### v1.58.1
_Released on 2024-05-08_
1. Updated linters
* `tagalign`: from 1.3.3 to 1.3.4
* `protogetter`: from 0.3.5 to 0.3.6
* `gochecknoinits`: fix analyzer name
2. Fixes
* Restores previous `github-actions` output format (removes GitHub Action problem matchers)
### v1.58.0
_Released on 2024-05-03_
1. New linters
* `fatcontext`: https://github.com/Crocmagnon/fatcontext
* `canonicalheader`: https://github.com/lasiar/canonicalheader
2. Updated linters
* `copyloopvar`: from 1.0.10 to 1.1.0 (`ignore-alias` is replaced by `check-alias` with the opposite behavior)
* `decorder`: from 0.4.1 to 0.4.2
* `errname`: from 0.1.12 to 0.1.13
* `errorlint`: from 1.4.8 to 1.5.1 (new options `allowed-errors` and `allowed-errors-wildcard`)
* `execinquery`: deprecate linter ⚠️
* `gci`: from 0.12.3 to 0.13.4 (new section `localModule`)
* `gocritic`: from 0.11.2 to 0.11.3
* `spancheck`: from 0.5.3 to 0.6.1
* `goerr113` is replaced by `err113` ⚠️
* `gomnd` is replaced by `mnd` ⚠️
* `gomodguard`: from 1.3.1 to 1.3.2
* `grouper`: from 1.1.1 to 1.1.2
* `intrange`: from 0.1.1 to 0.1.2
* `mirror`: from 1.1.0 to 1.2.0
* `misspell`: from 0.4.1 to 0.5.1
* `musttag`: from 0.9.0 to 0.12.1
* `nilnil`: from 0.1.7 to 0.1.8
* `nonamedreturns`: from 1.0.4 to 1.0.5
* `promlinter`: from 0.2.0 to 0.3.0
* `sloglint`: from 0.5.0 to 0.6.0
* `unparam`: bump to HEAD (063aff900ca150b80930c8de76f11d7e6488222f)
* `whitespace`: from 0.1.0 to 0.1.1
3. Enhancements
* Speed up "fast" linters when only "fast" linters are run: between 40% and 80% faster at first run (i.e. without cache)
4. Fixes
* Use version with module plugins
* Skip `go.mod` report inside autogenerated processor
* Keep only `typecheck` issues when needed
* Don't hide `typecheck` errors inside diff processor
5. Misc.
* ⚠️ log an error when using previously deprecated linters ([Linter Deprecation Cycle](https://golangci-lint.run/docs/product/roadmap/#linter-deprecation-cycle))
* [`deadcode`](https://github.com/remyoudompheng/go-misc/tree/HEAD/deadcode): deprecated since v1.49.0 (2022-08-23).
* [`exhaustivestruct`](https://github.com/mbilski/exhaustivestruct): deprecated since v1.46.0 (2022-05-08).
* [`golint`](https://github.com/golang/lint): deprecated since v1.41.0 (2021-06-15).
* [`ifshort`](https://github.com/esimonov/ifshort): deprecated since v1.48.0 (2022-08-04).
* [`interfacer`](https://github.com/mvdan/interfacer): deprecated since v1.38.0 (2021-03-03).
* [`maligned`](https://github.com/mdempsky/maligned): deprecated since v1.38.0 (2021-03-03).
* [`nosnakecase`](https://github.com/sivchari/nosnakecase): deprecated since v1.48.0 (2022-08-04).
* [`scopelint`](https://github.com/kyoh86/scopelint): deprecated since v1.39.0 (2021-03-25).
* [`structcheck`](https://github.com/opennota/check): deprecated since v1.49.0 (2022-08-23).
* [`varcheck`](https://github.com/opennota/check): deprecated since v1.49.0 (2022-08-23).
* ⚠️ Deprecate usage of linter alternative names
* Remove help display on errors with `config verify` command
* Add `pre-commit` hook to run `config verify`
* Improve `github-action` output
6. Documentation
* Remove deprecated Atom from Editor Integrations
GitHub Action (v5.1.0) for golangci-lint:
- supports for `pull`, `pull_request_target`, and `merge_group` events with the option `only-new-issues`.
- ️️⚠️ `skip-pkg-cache` and `skip-build-cache` have been removed because the cache related to Go itself is already handled by `actions/setup-go`.
- with golangci-lint v1.58, the file information (path and position) will be displayed on the log.
### v1.57.2
_Released on 2024-03-28_
1. Updated linters
* `contextcheck`: from 1.1.4 to 1.1.5
* `copyloopvar`: from 1.0.8 to 1.0.10
* `ginkgolinter`: from 0.16.1 to 0.16.2
* `goconst`: from 1.7.0 to 1.7.1
* `gomoddirectives`: from 0.2.3 to 0.2.4
* `intrange`: from 0.1.0 to 0.1.1
2. Misc.
* Display warnings on deprecated linter options
* Fix missing `colored-tab` output format
* Fix TeamCity `inspectionType` service message
3. Documentation
* Remove invalid example about mixing files and directory
* Improve linters page
### v1.57.1
_Released on 2024-03-20_
1. Fixes
* Ignore issues with invalid position (e.g. `contextcheck`).
### v1.57.0
_Released on 2024-03-19_
1. New linters
* `copyloopvar`: https://github.com/karamaru-alpha/copyloopvar
* `intrange`: https://github.com/ckaznocha/intrange
2. Updated linters
* `dupword`: from 0.0.13 to 0.0.14
* `gci`: from 0.12.1 to 0.12.3
* `ginkgolinter`: from 0.15.2 to 0.16.1 (new option `force-expect-to`, `validate-async-intervals`, and `forbid-spec-pollution`)
* `go-critic`: from 0.11.1 to 0.11.2
* `go-critic`: support of `enable-all` and `disable-all` options
* `go-spancheck`: from 0.5.2 to 0.5.3
* `gomodguard`: from 1.3.0 to 1.3.1
* `govet`: deprecation of `check-shadowing` ⚠️
* `govet`: disable temporarily `httpresponse` because of a bug https://github.com/golang/go/issues/66259
* `misspell`: add `extra-words`
* `musttag`: from 0.8.0 to 0.9.0
* `nakedret`: from 2.0.2 to 2.0.4
* `paralleltest`: from 1.0.9 to 1.0.10
* `perfsprint`: from 0.6.0 to 0.7.1 (new option `strconcat`)
* `protogetter`: from 0.3.4 to 0.3.5
* `revive`: add `exclude` option
* `sloglint`: from 0.4.0 to 0.5.0 (new option `no-global`)
* `staticcheck`: from 0.4.6 to 0.4.7
* `testifylint`: from 1.1.2 to 1.2.0 (new option `bool-compare`)
* `unconvert`: to HEAD (new options `fast-math` and `safe`)
* `wrapcheck`: from 2.8.1 to 2.8.3
* Disable `copyloopvar` and `intrange` on Go < 1.22
3. Enhancements
* 🧩New custom linters system https://golangci-lint.run/docs/plugins/module-plugins/
* Allow running only a specific linter without modifying the file configuration (`--enable-only`)
* Allow custom sort order for the reports (`output.sort-order`)
* Automatically adjust the maximum concurrency to the container CPU quota if `run.concurrency=0`
* Add `config verify` command to check the configuration against the JSON Schema
* Option to strictly follow Go generated file convention (`issues.exclude-generated-strict`)
* Syntax to not override `severity` from linters (`@linter`)
* Use severities from `gosec`
* Create automatically directory related to `output.formats.path`
* Use the first issue without inline on `mergeLineIssues` on multiple issues
4. Misc.
* ⚠️ Inactivate deprecated linters (`deadcode`, `exhaustivestruct`, `golint`, `ifshort`, `interfacer`, `maligned`, `nosnakecase`, `scopelint`, `structcheck`, `varcheck`)
* ⚠️ Deprecated CLI flags have been removed (deprecated since 2018)
* ⚠️ Move `show-stats` option from `run` to `output` configuration section
* ⚠️ Replace `run.skip-xxx` options by `issues.exclude-xxx` options
* ⚠️ Replace `output.format` by `output.formats` with a new file configuration syntax
* Internal rewrite of the CLI
* Improve 'no go files to analyze' message
* Use `GOTOOLCHAIN=auto` inside the Docker images
5. Documentation
* ⚠️ Define the linter deprecation cycle https://golangci-lint.run/docs/product/roadmap/#linter-deprecation-cycle
* 🎉Use information from the previous release to create linter pages
* Publish JSON schema on https://golangci-lint.run/jsonschema/golangci.jsonschema.json
* Reorganize documentation pages
* Add an explanation about the configuration file inside golangci-lint repository
**⚠️ Important ⚠️**
1. Deprecated linters are inactivated, you still need to disable them if you are using `enable-all`.
2. Deprecated CLI flags (about linter settings and `deadline`) have been removed.
### v1.56.2
_Released on 2024-02-15_
1. updated linters
* `go-critic`: from 0.11.0 to 0.11.1
* `gosec`: from 2.18.2 to 2.19.0
* `testifylint`: from 1.1.1 to 1.1.2
* `usestdlibvars`: from 1.24.0 to 1.25.0
* `wsl`: from 4.2.0 to 4.2.1
2. misc.
* Fix missing version in Docker image
3. Documentation
* Explain the limitation of `new-from-rev` and `new-from-patch`
### v1.56.1
_Released on 2024-02-08_
1. updated linters
* `errcheck`: from 1.6.3 to 1.7.0
* `govet`: disable `loopclosure` with go1.22
* `revive`: from 1.3.6 to 1.3.7
* `testifylint`: from 1.1.0 to 1.1.1
### v1.56.0
_Released on 2024-02-07_
1. new linters
* `spancheck`: https://github.com/jjti/go-spancheck
2. updated linters
* `depguard`: from 2.1.0 to 2.2.0
* `exhaustive`: from 0.11.0 to 0.12.0
* `exhaustruct`: from 3.1.0 to 3.2.0
* `gci`: from 0.11.2 to 0.12.1
* `ginkgolinter`: from 0.14.1 to 0.15.2
* `go-check-sumtype`: from 0.1.3 to 0.1.4
* `go-critic`: from 0.9.0 to 0.11.0
* `go-errorlint`: from 1.4.5 to 1.4.8
* `go-spancheck`: from 0.4.2 to 0.5.2
* `goconst`: from 1.6.0 to 1.7.0
* `godot`: from 1.4.15 to 1.4.16
* `gofumpt`: from 0.5.0 to 0.6.0
* `inamedparam`: from 0.1.2 to 0.1.3
* `ineffassign`: from 0.0.0-20230610083614-0e73809eb601 to 0.1.0
* `ireturn`: from 0.2.2 to 0.3.0
* `misspell`: add mode option
* `musttag`: from v0.7.2 to v0.8.0
* `paralleltest`: from 1.0.8 to 1.0.9
* `perfsprint`: from 0.2.0 to 0.6.0
* `protogetter`: from 0.2.3 to 0.3.4
* `revive`: from 1.3.4 to 1.3.6
* `sloglint`: add static-msg option
* `sloglint`: from 0.1.2 to 0.4.0
* `testifylint`: from 0.2.3 to 1.1.0
* `unparam`: from 20221223090309-7455f1af531d to 20240104100049-c549a3470d14
* `whitespace`: update after moving to the `analysis` package
* `wsl`: from 3.4.0 to 4.2.0
* `zerologlint`: from 0.1.3 to 0.1.5
3. misc.
* 🎉 go1.22 support
* Implement stats per linter with a flag
* Make versioning inside Docker image consistent with binaries
* Parse Go RC version
4. Documentation
* Fix `noctx` description
* Add missing fields to `.golangci.reference.yml`
* Improve `.golangci.reference.yml` defaults
* `typecheck`: improve FAQ
* `exhaustruct`: note that struct regular expressions are expected to match the entire `package/name/structname`
* `wrapcheck`: adjust `ignoreSigs` to new defaults
**Important**
`testifylint` has [breaking changes](https://github.com/Antonboom/testifylint/releases/tag/v1.0.0) about enabling/disabling checks:
- If you were using the option `enable` with a filtered list of checks, you should either add `disable-all: true` (1) or use `disable` field (2).
```yml
# Example (1)
testifylint:
disable-all: true
enable:
- bool-compare
- compares
- empty
- error-is-as
- error-nil
- expected-actual
- go-require
- float-compare
- len
- nil-compare
- require-error
# - suite-dont-use-pkg
- suite-extra-assert-call
- suite-thelper
```
```yml
# Example (2)
testifylint:
disable:
- suite-dont-use-pkg
```
### v1.55.2
_Released on 2023-11-03_
1. updated linters
* `ireturn`: from 0.2.1 to 0.2.2
* `ginkgolinter`: from 0.14.0 to 0.14.1
### v1.55.1
_Released on 2023-10-25_
1. updated linters
* `gosec`: from 2.18.1 to 2.18.2
2. misc.
* `revgrep`: from v0.5.0 to v0.5.2 (support git < 2.41.0)
* output: convert backslashes to forward slashes for GitHub Action annotations printer
### v1.55.0
_Released on 2023-10-20_
1. new linters
* `gochecksumtype`: https://github.com/alecthomas/go-check-sumtype
* `inamedparam`: https://github.com/macabu/inamedparam
* `perfsprint`: https://github.com/catenacyber/perfsprint
* `protogetter`: https://github.com/ghostiam/protogetter
* `sloglint`: https://github.com/go-simpler/sloglint
* `testifylint`: https://github.com/Antonboom/testifylint
2. updated linters
* `bidichk`: from 0.2.4 to 0.2.7
* `decorder`: from 0.4.0 to 0.4.1
* `dupword`: from 0.0.12 to 0.0.13
* `errchkjson`: from 0.3.1 to 0.3.6
* `gci`: from 0.11.0 to 0.11.2
* `ginkgolinter`: from 0.13.5 to 0.14.0
* `go-errorlint`: from 1.4.4 to 1.4.5
* `gocognit`: from 1.0.7 to 1.1.0
* `goconst`: from 1.5.1 to 1.6.0
* `godot`: from 1.4.14 to 1.4.15
* `gofmt`: update to HEAD
* `goimports`: update to HEAD
* `gosec`: from 2.17.0 to 2.18.1
* `gosmopolitan`: from 1.2.1 to 1.2.2
* `govet`: add `appends` analyzer
* `ireturn`: from 0.2.0 to 0.2.1
* `protogetter`: from 0.2.2 to 0.2.3
* `revgrep`: from 745bb2f7c2e6 to v0.5.0
* `revive`: from 1.3.2 to 1.3.4
* `sqlclosecheck`: from 0.4.0 to 0.5.1
* `staticcheck`: from 0.4.5 to 0.4.6
* `tagalign`: from 1.3.2 to 1.3.3
* `unused`: support passing in options
3. misc.
* Add a pre-commit hook to check all files
4. Documentation
* add source options to exclude-rules docs
* `gosec`: add G602 to includes/excludes inside .golangci.reference.yml
### v1.54.2
_Released on 2023-08-21_
1. updated linters:
* `errname`: from 0.1.10 to 0.1.12
* `ginkgolinter`: from 0.13.3 to 0.13.5
* `go-errorlint`: from 1.4.3 to 1.4.4
* `godot`: from 1.4.11 to 1.4.14
* `gosec`: from 2.16.0 to 2.17.0
* `musttag`: from 0.7.1 to 0.7.2
* `nilnil`: from 0.1.5 to 0.1.7
* `staticcheck`: from 0.4.3 to 0.4.5
* `usestdlibvars`: from 1.23.0 to 1.24.0
* `govet`: add missing `directive` and `slog` passes
### v1.54.1
_Released on 2023-08-11_
1. updated linters:
* `go-critic`: from 0.8.2 to 0.9.0
2. misc.
* plugin: temporarily hide warning about using plugins using the old API
### v1.54.0
_Released on 2023-08-09_
1. updated linters:
* `decorder`: from 0.2.3 to 0.4.0
* `dupword`: from 0.0.11 to 0.0.12
* `errorlint`: from 1.4.2 to 1.4.3
* `exhaustruct`: from 2.3.0 to 3.1.0
* `forbidigo`: from 1.5.3 to 1.6.0
* `funlen`: from 0.0.3 to 0.1.0
* `gci`: from 0.10.1 to 0.11.0
* `ginkgolinter`: from 0.12.1 to 0.13.3
* `go-critic`: from 0.8.1 to 0.8.2
* `go-errorlint`: from 1.4.2 to 1.4.3
* `go-exhaustruct`: from 2.3.0 to 3.1.0
* `gocognit`: from 1.0.6 to 1.0.7
* `gocritic`: from 0.8.1 to 0.8.2
* `gofmt`: autofix missing newline at EOF
* `misspell`: 0.4.0 to 0.4.1
* `musttag`: from 0.7.0 to 0.7.1
* `paralleltest`: from 1.0.7 to 1.0.8
* `tagalign`: from 1.2.2 to 1.3.2
* `typecheck`: explain it and remove it from the linter list
* `zerologlint`: from 0.1.2 to 0.1.3
2. misc.
* 🎉 go1.21 support
* plugin: include custom linters in `enable-all`
* plugin: allow to use settings for plugins
3. Documentation
* Add linter descriptions.
**Important**
`ruleguard` (a "rule" inside `gocritic`) was disabled in this release (v1.54.0) and was enabled again in the next release (v1.54.1).
`exhaustruct` has breaking changes with regular expressions, more details [here](https://github.com/GaijinEntertainment/go-exhaustruct/releases/tag/v3.0.0).
### v1.53.3
_Released on 2023-06-15_
1. updated linters:
* `cyclop`: from 1.2.0 to 1.2.1
* `exhaustive`: from 0.10.0 to 0.11.0
* `forbidigo`: from 1.5.1 to 1.5.3
* `ginkgolinter`: from 0.12.2 to 0.12.1
* `ineffassign`: bump to HEAD
* `nakedret`: from 2.0.1 to 2.0.2
* `zerologlint`: from 0.1.1 to 0.1.2
2. misc.
* codeclimate: reduce memory allocation
* support illumos/amd64
### v1.53.2
_Released on 2023-06-03_
1. updated linters
* `depguard`: from v2.0.1 to 2.1.0
2. misc.
* `depguard`: throw error only when the linter is called
### v1.53.1
_Released on 2023-06-02_
1. misc.
* `depguard`: fix GOROOT detection
* `importas`: fix duplication detection when aliases use regular expression replacement pattern
### v1.53.0
_Released on 2023-06-01_
1. new linters
* `gosmopolitan`: https://github.com/xen0n/gosmopolitan
* `mirror`: https://github.com/butuzov/mirror
* `tagalign`: https://github.com/4meepo/tagalign
* `zerologlint`: https://github.com/ykadowak/zerologlint
2. updated linters
* `bodyclose`: bump to HEAD
* `containedctx`: from 1.0.2 to 1.0.3
* `depguard`: migrate to v2
* `errname`: from 0.1.9 to 0.1.10
* `exhaustive`: from 0.9.5 to 0.10.0
* `forbidigo`: better support for configuring complex rules
* `gci`: improve error message
* `ginkgolinter`: add suppress-async-assertion option
* `ginkgolinter`: from 0.9.0 to 0.12.0
* `go-critic`: from 0.7.0 to 0.8.1
* `go-errorlint`: from 1.4.0 to 1.4.2
* `gofumpt`: from 0.4.0 to 0.5.0
* `gosec`: convert global settings as map with proper key type
* `gosec`: from 2.15.0 to 2.16.0
* `importas`: detect duplicate alias or package in the configuration
* `importas`: fix typo in logs
* `ireturn`: from 0.1.1 to 0.2.0
* `musttag`: from 0.5.0 to 0.7.0
* `nakedret`: to 2.0.1
* `nilnil`: from 0.1.3 to 0.1.5
* `paralleltest`: from 1.0.6 to 1.0.7
* `revive`: from 1.3.1 to 1.3.2
* `tagliatelle`: from 0.4.0 to 0.5.0
* `usestdlibvars`: fix configuration
3. misc.
* `golang.org/x/tools`: from 0.7.0 to 0.9.2
* add loongarch64 to the install script
* output: add colored-tab
* remove warning when the config file is explicitly stdin
* rules: support inverted path match
4. Documentation
* `mnd`: clarify ignore usage examples to be regexps
* `tagliatelle`: update documentation
* improve features section
* update supported Go versions FAQ
### v1.52.2
_Released on 2023-03-25_
1. updated linters
* `tparallel`: from 0.3.0 to 0.3.1
2. misc.
* fix: pre-commit `require_serial` and `pass_filenames`
### v1.52.1
_Released on 2023-03-21_
1. misc.
* fix: improve panic management
* fix: the combination of --fix and --path-prefix
### v1.52.0
_Released on 2023-03-18_
1. updated linters
* `asciicheck`: from 0.1.1 to 0.2.0
* `bidichk`: from 0.2.3 to 0.2.4
* `contextcheck`: from 1.1.3 to 1.1.4
* `dupword`: from 0.0.9 to 0.0.11
* `durationcheck`: from 0.0.9 to 0.0.10
* `errchkjson`: from 0.3.0 to 0.3.1
* `errname`: from 0.1.7 to 0.1.9
* `forbidigo`: from 1.4.0 to 1.5.1
* `gci`: from 0.9.1 to 0.10.1
* `ginkgolinter`: from 0.8.1 to 0.9.0
* `go-critic`: from 0.6.7 to 0.7.0
* `go-errorlint`: from 1.1.0 to 1.4.0
* `godox`: bump to HEAD
* `lll`: skip go command
* `loggercheck`: from 0.9.3 to 0.9.4
* `musttag`: from 0.4.5 to 0.5.0
* `nilnil`: from 0.1.1 to 0.1.3
* `noctx`: from 0.0.1 to 0.0.2
* `revive`: from 1.2.5 to 1.3.1
* `rowserrcheck`: remove limitation related to generics support
* `staticcheck`: from 0.4.2 to 0.4.3
* `testpackage`: from 1.1.0 to 1.1.1
* `tparallel`: from 0.2.1 to 0.3.0
* `wastedassign`: remove limitation related to generics support
* `wrapcheck`: from 2.8.0 to 2.8.1
2. misc.
* Add TeamCity output format
* Consider path prefix when matching path patterns
* Add Go version to version information
3. Documentation
* Add Tekton in Trusted By page
* Clarify that custom linters are not enabled by default
* Remove description for deprecated "go" option
### v1.51.2
_Released on 2023-02-19_
1. updated linters
* `forbidigo`: from 1.3.0 to 1.4.0
* `gci`: from 0.9.0 to 0.9.1
* `go-critic`: from 0.6.5 to 0.6.7
* `go-errorlint`: from 1.0.6 to 1.1.0
* `gosec`: from 2.14.0 to 2.15.0
* `musttag`: from 0.4.4 to 0.4.5
* `staticcheck`: from 0.4.0 to 0.4.2
* `tools`: from 0.5.0 to 0.6.0
* `usestdlibvars`: from 1.21.1 to 1.23.0
* `wsl`: from 3.3.0 to 3.4.0
* `govet`: enable `timeformat` by default
2. misc.
* fix: cache status size calculation
* add new source archive
3. Documentation
* Improve installation section
* Replace links to godoc.org with pkg.go.dev
### v1.51.1
_Released on 2023-02-05_
1. updated linters
* `ginkgolinter`: from 0.7.1 to 0.8.1
* `ineffassign`: bump to HEAD
* `musttag`: from 0.4.3 to 0.4.4
* `sqlclosecheck`: from 0.3.0 to 0.4.0
* `staticcheck`: bump to v0.4.0
* `wastedassign`: from 2.0.6 to 2.0.7
* `wrapcheck`: from 2.7.0 to 2.8.0
### v1.51.0
_Released on 2023-02-02_
1. new linters
* `ginkgolinter`: https://github.com/nunnatsa/ginkgolinter
* `musttag`: https://github.com/tmzane/musttag
* `gocheckcompilerdirectives`: https://github.com/leighmcculloch/gocheckcompilerdirectives
2. updated linters
* `bodyclose`: to HEAD
* `dupword`: from 0.0.7 to 0.0.9
* `errcheck`: from 1.6.2 to 1.6.3
* `exhaustive`: from 0.8.3 to 0.9.5
* `exportloopref`: from 0.1.8 to 0.1.11
* `gci`: from 0.8.1 to 0.9.0
* `ginkgolinter`: from 0.6.0 to 0.7.1
* `go-errorlint`: from 1.0.5 to 1.0.6
* `go-ruleguard`: from 0.3.21 to 0.3.22
* `gocheckcompilerdirectives`: from 1.1.0 to 1.2.1
* `gochecknoglobals`: from 0.1.0 to 0.2.1
* `gomodguard`: from 1.2.4 to 1.3.0
* `gosec`: from 2.13.1 to 2.14.0
* `govet`: Add `timeformat` to analysers
* `grouper`: from 1.1.0 to 1.1.1
* `musttag`: from 0.4.1 to 0.4.3
* `revive`: from 1.2.4 to 1.2.5
* `tagliatelle`: from 0.3.1 to 0.4.0
* `tenv`: from 1.7.0 to 1.7.1
* `unparam`: bump to HEAD
* `usestdlibvars`: from 1.20.0 to 1.21.1
* `wsl`: fix `force-err-cuddling` flag
3. misc.
* go1.20 support
* remove deprecated linters from presets
* Build NetBSD binaries
* Build loong64 binaries
4. Documentation
* `goimport`: improve documentation for local-prefixes
* `gomnd`: add missing always ignored functions
* `nolint`: fix typo
* `tagliatelle` usage typo
* add note about binary requirement for plugin
* cache preserving and colored output on docker runs
* improve documentation about debugging.
* improve Editor Integration section
* More specific default cache directory
* update output example to use valid checkstyle example; add json example
### v1.50.1
_Released on 2022-10-22_
1. updated linters
* `contextcheck`: from 1.1.2 to 1.1.3
* `go-mnd`: from 2.5.0 to 2.5.1
* `wrapcheck`: from 2.6.2 to 2.7.0
* `revive`: fix configuration parsing
* `lll`: skip imports
2. misc.
* windows: remove redundant character escape '\/'
* code-climate: add default severity
### v1.50.0
_Released on 2022-10-04_
1. new linters
* `dupword`: https://github.com/Abirdcfly/dupword
* `testableexamples`: https://github.com/maratori/testableexamples
2. updated linters
* `contextcheck`: change owner
* `contextcheck`: from 1.0.6 to 1.1.2
* `depguard`: from 1.1.0 to 1.1.1
* `exhaustive`: add missing config
* `exhaustive`: from 0.8.1 to 0.8.3
* `gci`: from 0.6.3 to 0.8.0
* `go-critic`: from 0.6.4 to 0.6.5
* `go-errorlint`: from 1.0.2 to 1.0.5
* `go-reassign`: v0.1.2 to v0.2.0
* `gofmt`: add option `rewrite-rules`
* `gofumpt` from 0.3.1 to 0.4.0
* `goimports`: update to HEAD
* `interfacebloat`: fix configuration loading
* `logrlint`: rename `logrlint` to `loggercheck`
* `paralleltest`: add tests of the ignore-missing option
* `revive`: from 1.2.3 to 1.2.4
* `usestdlibvars`: from 1.13.0 to 1.20.0
* `wsl`: support all configs and update docs
3. misc.
* Normalize `exclude-rules` paths for Windows
* add riscv64 to the install script
4. Documentation
* cli: remove reference to old service
### v1.49.0
_Released on 2022-08-24_
IMPORTANT: `varcheck` and `deadcode` has been removed of default linters.
1. new linters
* `interfacebloat`: https://github.com/sashamelentyev/interfacebloat
* `logrlint`: https://github.com/timonwong/logrlint
* `reassign`: https://github.com/curioswitch/go-reassign
2. updated linters
* `go-colorable`: from 0.1.12 to 0.1.13
* `go-critic`: from 0.6.3 to 0.6.4
* `go-errorlint`: from 1.0.0 to 1.0.2
* `go-exhaustruct`: from 2.2.2 to 2.3.0
* `gopsutil`: from 3.22.6 to 3.22.7
* `gosec`: from 2.12.0 to 2.13.1
* `revive`: from 1.2.1 to 1.2.3
* `usestdlibvars`: from 1.8.0 to 1.13.0
* `contextcheck`: from v1.0.4 to v1.0.6 && re-enable
* `nosnakecase`: This linter is deprecated.
* `varcheck`: This linter is deprecated use `unused` instead.
* `deadcode`: This linter is deprecated use `unused` instead.
* `structcheck`: This linter is deprecated use `unused` instead.
3. documentation
* `revive`: fix wrong URL
* Add a section about default exclusions
* `usestdlibvars`: fix typo in documentation
* `nolintlint`: remove allow-leading-space option
* Update documentation and assets
4. misc.
* dev: rewrite the internal tests framework
* fix: exit early on run --version
* fix: set an explicit `GOROOT` in the Docker image for `go-critic`
### v1.48.0
_Released on 2022-08-04_
1. new linters
* `usestdlibvars`:https://github.com/sashamelentyev/usestdlibvars
2. updated linters
* `contextcheck`: disable linter
* `errcheck`: from 1.6.1 to 1.6.2
* `gci`: add missing `custom-order` setting
* `gci`: from 0.5.0 to 0.6.0
* `ifshort`: deprecate linter
* `nolint`: drop allow-leading-space option and add "nolint:all"
* `revgrep`: bump to HEAD
3. documentation
* remove outdated info on source install
4. misc
* go1.19 support
### v1.47.3
_Released on 2022-08-01_
1. updated linters:
* remove some go1.18 limitations
* `asasalint`: from 0.0.10 to 0.0.11
* `decorder`: from 0.2.2 to v0.2.3
* `gci`: fix panic with invalid configuration option
* `gci`: from 0.4.3 to v0.5.0
* `go-exhaustruct`: from 2.2.0 to 2.2.2
* `gomodguard`: from 1.2.3 to 1.2.4
* `nosnakecase`: from 1.5.0 to 1.7.0
* `honnef.co/go/tools`: from 0.3.2 to v0.3.3
2. misc
* cgo: fix linters ignoring CGo files
### v1.47.2
_Released on 2022-07-21_
1. updated linters:
* `revive`: ignore slow rules
### v1.47.1
_Released on 2022-07-19_
1. updated linters:
* `gci`: from 0.4.2 to 0.4.3
* `gci`: remove the use of stdin
* `gci`: fix options display
* `tenv`: from 1.6.0 to 1.7.0
* `unparam`: bump to HEAD
### v1.47.0
_Released on 2022-07-18_
1. new linters:
* `asasalint`: https://github.com/alingse/asasalint
* `nosnakecase`: https://github.com/sivchari/nosnakecase
2. updated linters:
* `decorder`: from 0.2.1 to 0.2.2
* `errcheck`: from 1.6.0 to 1.6.1
* `errname`: from 0.1.6 to 0.1.7
* `exhaustive`: from 0.7.11 to 0.8.1
* `gci`: fix issues and re-enable autofix
* `gci`: from 0.3.4 to 0.4.2
* `go-exhaustruct`: from 2.1.0 to 2.2.0
* `go-ruleguard`: from 0.3.19 to 0.3.21
* `gocognit`: from 1.0.5 to 1.0.6
* `gocyclo`: from 0.5.1 to 0.6.0
* `golang.org/x/tools`: bump to HEAD
* `gosec`: allow `global` config
* `gosec`: from 2.11.0 to 2.12.0
* `nonamedreturns`: from 1.0.1 to 1.0.4
* `paralleltest`: from 1.0.3 to 1.0.6
* `staticcheck`: fix generics
* `staticcheck`: from 0.3.1 to 0.3.2
* `tenv`: from 1.5.0 to 1.6.0
* `testpackage`: from 1.0.1 to 1.1.0
* `thelper`: from 0.6.2 to 0.6.3
* `wrapcheck`: from 2.6.1 to 2.6.2
3. documentation:
* add thanks page
* add a clear explanation about the `staticcheck` integration.
* `depguard`: add `ignore-file-rules`
* `depguard`: adjust phrasing
* `gocritic`: add `enable` and `disable` ruleguard settings
* `gomnd`: fix typo
* `gosec`: add configs for all existing rules
* `govet`: add settings for `shadow` and `unusedresult`
* `thelper`: add `fuzz` config and description
* linters: add defaults
### v1.46.2
_Released on 2022-05-17_
1. updated linters:
* `execinquery`: bump from v1.2.0 to v1.2.1
* `errorlint`: bump to v1.0.0
* `thelper`: allow to disable one option
2. documentation:
* rename `.golangci.example.yml` to `.golangci.reference.yml`
* add `containedctx` linter to the list of available linters
### v1.46.1
_Released on 2022-05-12_
1. updated linters:
* `execinquery`: bump from v0.6.0 to v0.6.1
2. documentation:
* add missing linters
### v1.46.0
_Released on 2022-05-09_
1. new linters:
* `execinquery`: https://github.com/lufeee/execinquery
* `nonamedreturns`: https://github.com/firefart/nonamedreturns
* `nosprintfhostport`: https://github.com/stbenjam/no-sprintf-host-port
* `exhaustruct`: https://github.com/GaijinEntertainment/go-exhaustruct
2. updated linters:
* `bidichk`: from 0.2.2 to 0.2.3
* `deadcode`: bump to HEAD
* `errchkjson`: from 0.2.3 to 0.3.0
* `errname`: from 0.1.5 to 0.1.6
* `go-critic`: from 0.6.2 to 0.6.3
* `gocyclo`: from 0.4.0 to 0.5.1
* `gofumpt` from 0.3.0 to 0.3.1
* `gomoddirectives`: from 0.2.2 to 0.2.3
* `gosec`: from 2.10.0 to 2.11.0
* `honnef.co/go/tools`: from 0.2.2to 0.3.1 (go1.18 support)
* `nilnil`: from 0.1.0 to 0.1.1
* `nonamedreturns`: bump from 1.0.0 to 1.0.1
* `predeclared`: from 0.2.1 to 0.2.2
* `promlinter`: bump to v0.2.0
* `revive`: from 1.1.4 to 1.2.1
* `tenv`: from 1.4.7 to 1.5.0
* `thelper`: from 0.5.1 to 0.6.2
* `unused`: fix false-positive
* `varnamelen`: bump to v0.8.0
* `wrapcheck`: from 2.5.0 to 2.6.1
* `exhaustivestruct`: This linter is deprecated use `exhaustruct` instead.
3. documentation:
* Update "Shell Completion" instruction on Linux
* Update FAQ page
4. misc:
* log: enable override coloring based on `CLICOLOR` and `CLICOLOR_FORCE`
### v1.45.2
_Released on 2022-03-24_
1. misc:
* fix: help command
### v1.45.1
_Released on 2022-03-24_
1. updated linters:
* `interfacer`: inactivate with go1.18
* `govet`: inactivate unsupported analyzers (go1.18)
* `depguard`: reduce requirements
* `structcheck`: inactivate with go1.18
* `varnamelen`: bump from v0.6.0 to v0.6.1
2. misc:
* Automatic Go version detection 🎉 (go1.18)
* docker: update base images (go1.18)
### v1.45.0
_Released on 2022-03-29_
1. updated linters:
* `cobra`: from 1.3.0 to 1.4.0
* `containedctx`: from 1.0.1 to 1.0.2
* `errcheck`: add an option to remove default exclusions
* `gci`: from 0.3.1 to 0.3.2
* `go-header`: from 0.4.2 to 0.4.3
* `gofumpt`: add module-path setting
* `gofumpt`: from 0.2.1 to 0.3.0
* `gopsutil`: from 3.22.1 to 3.22.2
* `gosec`: from 2.9.6 to 2.10.0
* `makezero`: from 1.1.0 to 1.1.1
* `revive`: fix default values
* `wrapcheck`: from 2.4.0 to 2.5.0
2. documentation:
* docs: add "back to the top" button
* docs: add `forbidigo` example that uses comments
* docs: improve linters page
3. misc:
* go1.18 support 🎉
* Add an option to manage the targeted version of Go
* Default to YAML when config file has no extension
### v1.44.2
_Released on 2022-02-17_
1. updated linters:
* `gci`: bump to HEAD
* `gci`: restore defaults for sections
* `whitespace`: from 0.0.4 to 0.0.5
2. documentation:
* add link to configuration in the linters list
### v1.44.1
_Released on 2022-02-17_
1. updated linters:
* `bidichk`: from 0.2.1 to 0.2.2
* `errchkjson`: from 0.2.1 to 0.2.3
* `thelper`: from 0.5.0 to 0.5.1
* `tagliatelle`: from 0.3.0 to 0.3.1
* `gopsutil`: from 3.21.12 to 3.22.1
* `gci`: from 0.2.9 to 0.3.0
* `revive`: from v1.1.3 to v1.1.4
* `varnamelen`: from v0.5.0 to v0.6.0
2. documentation:
* linters: improve configuration pages
* `decorder`: fix `disable-init-func-first-check: false` elaboration
3. misc:
* fix debug output
### v1.44.0
_Released on 2022-01-25_
1. new linters:
* `containedctx`: https://github.com/sivchari/containedctx
* `decorder`: https://gitlab.com/bosi/decorder
* `errchkjson`: https://github.com/breml/errchkjson
* `maintidx`: https://github.com/yagipy/maintidx
* `grouper`: https://github.com/leonklingele/grouper
2. updated linters:
* `asciicheck`: bump to v0.1.1
* `bidichk`: from 0.1.1 to 0.2.1
* `bodyclose`: bump to HEAD
* `decorder`: from 0.2.0 to 0.2.1
* `depguard`: from 1.0.1 to 1.1.0
* `errchkjson`: from 0.2.0 to 0.2.1
* `errorlint`: bump to HEAD
* `exhaustive`: drop deprecated/unused settings
* `exhaustive`: from v0.2.3 to 0.7.11
* `forbidigo`: from 1.2.0 to 1.3.0
* `forcetypeassert`: bump to v0.1.0
* `gocritic`: from 0.6.1 to 0.6.2
* `gocritic`: support autofix
* `gocyclo`: from 0.3.1 to 0.4.0
* `godot`: add period option
* `gofumpt`: from 0.1.1 to 0.2.1
* `gomnd`: from 2.4.0 to 2.5.0
* `gomnd`: new configuration
* `gosec`: from 2.9.1 to 2.9.6
* `ifshort`: from 1.0.3 to 1.0.4
* `ineffassign`: bump to HEAD
* `makezero`: to v1.1.0
* `promlinter`: from v0.1.0 to HEAD
* `revive`: fix `enableAllRules`
* `revive`: from 1.1.2 to 1.1.3
* `staticcheck`: from 0.2.1 to 0.2.2
* `tagliatelle`: from 0.2.0 to 0.3.0
* `thelper`: from 0.4.0 to 0.5.0
* `unparam`: bump to HEAD
* `varnamelen`: bump to v0.5.0
* `wrapcheck`: update configuration to include `ignoreSignRegexps`
3. documentation:
* linters: improve pages about configuration
* improve page about false-positive
* `nolintlint`: fix wrong default value in comment
* `revive`: add a more detailed configuration
4. misc:
* outputs: Add support for multiple outputs
* outputs: Print error text in `` tag content for more readable JUnit output
* outputs: ensure that the Issues key in JSON format is a list
* Return error if any linter fails to run
* cli: Show deprecated mark in the CLI linters help
### November 2021
1. new linters:
* `bidichk`: https://github.com/breml/bidichk
2. update linters:
* `nestif`: from 0.3.0 to 0.3.1
* `rowserrcheck`: from 1.1.0 to 1.1.1
* `gopsutil`: from 3.21.9 to 3.21.10
* `wrapcheck`: from 2.3.1 to 2.4.0
* `gocritic`: add support for variable substitution in `ruleguard` path settings
3. documentation:
* improve `go-critic` documentation
* improve `nolintlint` documentation
4. Misc:
* cli: don't hide `enable-all` option
### october 2021
1. new linters:
* `contextcheck`: https://github.com/kkHAIKE/contextcheck
* `varnamelen`: https://github.com/blizzy78/varnamelen
2. update linters:
* `gochecknoglobals`: to v0.1.0
* `gosec`: filter issues according to the severity and confidence
* `errcheck`: empty selector name.
* `ifshort`: from 1.0.2 to 1.0.3
* `go-critic`: from 0.5.6 to 0.6.0
* `gosec`: from 2.8.1 to 2.9.1
* `durationcheck`: from 0.0.8 to 0.0.9
* `wrapcheck`: from 2.3.0 to 2.3.1
* `revive`: from 1.1.1 to 1.1.2
### September 2021
1. new linters:
* `ireturn`: https://github.com/butuzov/ireturn
* `nilnil`: https://github.com/Antonboom/nilnil
* `tenv`: https://github.com/sivchari/tenv
2. update linters:
* `errcheck`: update to HEAD
* `errname`: from 0.1.4 to 0.1.5
* `gci`: Parse the settings more similarly to the CLI
* `godot`: from 1.4.9 to 1.4.11
* `ireturn`: from 0.1.0 to 0.1.1
* `nlreturn`: add block-size option
* `paralleltest`: from 1.0.2 to 1.0.3
3. Misc:
* new-from-rev: add support for finding issues in entire files in a diff
### August 2021
1. new linters:
* `errname`: https://github.com/Antonboom/errname
2. update linters:
* `errname`: from 0.1.3 to 0.1.4
* `go-critic`: fix invalid type conversions.
* `godot`: from 1.4.8 to 1.4.9
* `gomodguard`: from 1.2.2 to 1.2.3
* `revive`: from 1.0.9 to 1.1.1
* `staticcheck`: bump to 2021.1.1 (v0.2.1)
* `wrapcheck`: bump to v2.3.0
3. Misc:
* build binaries and Docker images with go1.17
### July 2021
1. update linters:
* `errcheck`: allow exclude config without extra file
* `exhaustive`: from 0.1.0 to 0.2.3
* `gocognit`: from 1.0.1 to 1.0.5
* `godot`: from 1.4.7 to 1.4.8
* `gomoddirectives`: from 0.2.1 to 0.2.2
* `revive`: from 1.0.8 to 1.0.9
2. documentation:
* improve `goconst` documentation
* improve `goimports` description
### June 2021
1. update linters:
* `durationcheck`: from 0.0.7 to 0.0.8
* `gci`: from 0.2.8 to 0.2.9
* `goconst`: from 0.5.6 to 0.5.7
* `gofumpt`: Add lang-version option
* `gomodguard`: from 1.2.1 to 1.2.2
* `gosec`: from 2.8.0 to 2.8.1
* `revive`: add enable-all-rules.
* `revive`: allow to disable rule
* `revive`: fix exclude comment rule for const block
* `revive`: from 1.0.7 to 1.0.8
* `wrapcheck`: from 2.1.0 to 2.2.0
2. documentation:
* add all integrations to docs introduction page
3. Misc:
* 🎉 Un-deprecate enable-all option
* output: generate HTML report
* Support RISV64
### May 2021
1. new linters:
* `tagliatelle`: https://github.com/ldez/tagliatelle
* `promlinter`: https://github.com/yeya24/promlinter
2. update linters:
* `durationcheck`: from 0.0.6 to 0.0.7
* `errorlint`: bump to HEAD
* `forbidigo`: from 1.1.0 to 1.2.0
* `go-critic`: from 0.5.5 to 0.5.6
* `godot`: from 1.4.6 to 1.4.7
* ⚠ `golint`: deprecated
* `gomnd`: from 2.3.2 to 2.4.0
* `gomodguard`: fix problem where duplicate issues were reported
* `gosec`: from 2.7.0 to 2.8.0
* `govet`: fix `sigchanyzer`
* `govet`: Update vet passes
* `importas`: allow repeated aliases
* `importas`: bump to HEAD
* `makezero`: bump to HEAD
* `nolintlint`: fix false positive
* `revive`: convert hard coded excludes into default exclude patterns
* `revive`: fix add-constant rule support
* `revive`: fix excludes
* `revive`: from 1.0.6 to 1.0.7
* `revive`: improve 'exported' rule output
* `rowserrcheck`: bump to v1.1.0
* `staticcheck`: configuration for `staticcheck`, `gosimple`, `stylecheck`
* `staticcheck`: from 0.1.3 to 0.1.4
* `staticcheck`: from v0.1.4 to v0.2.0
* `wastedassign`: from 0.2.0 to 1.0.0
* `wastedassign`: from 1.0.0 to v2.0.6
* `wrapcheck`: from 1.2.0 to 2.1.0
3. documentation:
* improve linters page
* `exhaustivestruct` example explanation
* fix pattern of `forbidigo` in example config yaml
* bump documentation dependencies
* fix typos
4. Misc:
* set the minimum Go version to go1.15
* non-zero exit code when a linter produces a panic
### April 2021
1. new linters:
* `tagliatelle`: https://github.com/ldez/tagliatelle
* `promlinter`: https://github.com/yeya24/promlinter
2. update linters:
* `godot`: from 1.4.4 to 1.4.6
* `wrapcheck`: from 1.0.0 to 1.2.0
* `go-mnd`: from 2.3.1 to 2.3.2
* `wsl`: from 3.2.0 to 3.3.0
* `revive`: from 1.0.5 to 1.0.6
* `importas`: bump to HEAD
* `staticcheck`: configurable Go version
* `gosec`: add configuration
* `typecheck`: improve error stack parsing
3. documentation:
* bump documentation dependencies
* fix typos
4. Misc:
* fix: comma in exclude pattern leads to unexpected results
### March 2021
1. new linters:
* `gomoddirectives`: https://github.com/ldez/gomoddirectives
2. update linters:
* `go-critic`: from 0.5.4 to 0.5.5
* `gofumpt`: from v0.1.0 to v0.1.1
* `gosec`: from 2.6.1 to 2.7.0
* `ifshort`: bump to v1.0.2
* `importas`: bump to HEAD
* `makezero`: bump to HEAD
* `nolintlint`: allow to fix //nolint lines
* `revive`: from 1.0.3 to 1.0.5
* `revive`: the default configuration is only applied when no dedicated configuration
* `rowserrcheck`: bump to HEAD
* ⚠ `scopelint`: deprecated
* `staticcheck`: from v0.1.2 (2020.2.2) to v0.1.3 (2020.2.3)
* 🎉 `typecheck`: display compilation errors as report instead of error
* `wastedassign`: bump to v0.2.0
* `wrapcheck`: bump to v1.0.0
3. documentation:
* improve [linters page](https://golangci-lint.run/docs/linters/) (versions, deprecation, and presets)
* add [cache directory](https://golangci-lint.run/docs/configuration/cli/#cache) information
* adding missing format options
* fix typos
4. Misc:
* Set `version` command output to Stdout
* fix linters load mode
* Restore fast linters meaning
### February 2021
1. new linters:
* `durationcheck`: https://github.com/charithe/durationcheck
* `revive`: https://github.com/mgechev/revive
* `cyclop`: https://github.com/bkielbasa/cyclop
* `wastedassign`: https://github.com/sanposhiho/wastedassign
* `importas`: https://github.com/julz/importas
* `nilerr`: https://github.com/gostaticanalysis/nilerr
* `forcetypeassert`: https://github.com/gostaticanalysis/forcetypeassert
* `govet`: add `stringintconv` and `ifaceassert`
2. update linters:
* `prealloc`: Use upstream version
* `errcheck`: Use upstream version
* `ineffassign`: Use upstream version
* `gocyclo`: Use upstream version
* `godot` from 1.3.2 to 1.4.3
* `exhaustivestruct` from 1.1.0 to 1.2.0
* `forbidigo` from 1.0.0 to 1.1.0
* `thelper` from 0.2.1 to 0.3.1
* `ruleguard`: print error message and exit with non-zero status when parsing error occurs
* fix wrong load mode for `asciicheck`, `exhaustivestruct`, `exportloopref`, and `makezero`
* `wsl`: bump to v3.2.0
* `durationcheck`: from 0.0.4 to 0.0.6
* `staticcheck`: from 2020.1.6 to v0.1.2 (2020.2.2)
* `thelper` from 0.3.1 to 0.4.0
* `bodyclose`: bump to HEAD
* `go-err113`: bump to HEAD
* ⚠ `interfacer`: deprecated
* ⚠ `maligned`: deprecated (govet `fieldalignment` as replacement)
* `govet`: use same default linter as go vet
* `go-printf-func-name`: to `v0.0.0-20200119135958-7558a9eaa5af`
* `godox`: to `v0.0.0-20210227103229-6504466cf951`
* `asciicheck`: to `v0.0.0-20200416200610-e657995f937b`
* `wrapcheck`: to `v0.0.0-20201130113247-1683564d9756`
* `unparam`: to `v0.0.0-20210104141923-aac4ce9116a7`
3. CLI: truncate multiline descriptions
4. fix: new-from-rev for a large repository
5. Support RelatedInformation for analysis Diagnostic
6. use go1.16 to create binaries
7. fix: MIPS release
8. documentation:
* bump documentation dependencies
* fix `go-header` usage
* improve `gocritic` description
* update deprecated hyperlink for Sublime Text plugin
* add docs on using homebrew tap
### January 2021
1. new linters:
* `predeclared`: https://github.com/nishanths/predeclared
* `ifshort`: https://github.com/esimonov/ifshort
2. update linters:
* `go-critic` from 0.5.2 to 0.5.3
* `thelper` from 0.1.0 to 0.2.1
* Validate `go-critic` settings
* `gofumpt` to v0.1.0
* `gci` to v0.2.8
* `go-mnd` to v2.3.1
* `gosec` from 2.5.0 to 2.6.1
* `godot` from 1.3.2 to 1.4.3
* `ifshort` to v1.0.1
* `rowserrcheck`: fix reports false positive
3. fix: modules-download-mode support
4. documentation:
* bump documentation dependencies
### December 2020
1. new linters:
* `forbidigo`: https://github.com/ashanbrown/forbidigo
* `makezero`: https://github.com/ashanbrown/makezero
* `thelper`: https://github.com/kulti/thelper
2. update linters:
* `go-header` from v0.3.1 to v0.4.2
* `go-mnd` from v2.0.0 to v2.2.0
* `godot` from v1.3.0 to v1.3.2
* `gci` from v0.2.4 to v0.2.7
* `gomodguard` from v1.1.0 to v1.2.0
* `go-errorlint` from v0.0.0-20201006195004-351e25ade6e3 to v0.0.0-20201127212506-19bd8db6546f
* `gofumpt` from v0.0.0-20200802201014-ab5a8192947d to v0.0.0-20201129102820-5c11c50e9475
* `nolintlint` fix comment analysis. (#1571)
3. result/processors: treat all non-Go source as special autogenerated files
4. throw an error on panic. (#1540)
5. resolve custom linters' path relative to config file directory (#1572)
6. treat all non-Go source as special autogenerated files
7. documentation:
* add settings examples for `gocritic` (#1562)
* removing reference to no-longer-existing linter-in-the-cloud (#1553)
8. others:
* bump `gopkg.in/yaml.v2` from 2.3.0 to 2.4.0 (#1528)
* bump `gatsby-remark-responsive-iframe` in /docs (#1533)
* bump `gatsby-remark-images` from 3.3.29 to 3.6.0 in /docs (#1531)
* bump `ini` from 1.3.5 to 1.3.8 in /tools (#1560)
* bump `react-headroom` from 3.0.0 to 3.0.1 in /docs (#1532)
* bump `react-live` from 2.2.2 to 2.2.3 in /docs (#1534)
* bump `react` from 16.13.1 to 16.14.0 in /docs (#1481)
* Fix `forbidigo` linter name in reports (#1590)
### November 2020
1. new linters:
* `paralleltest`: https://github.com/kunwardeep/paralleltest
2. update linters:
* `godot` from v0.4.9 to v1.3.0
* `exportloopref` from v0.1.7 to v0.1.8
* `gosec` from 2.4.0 to 2.5.0
* `goconst` using upstream https://github.com/jgautheron/goconst
3. `DefaultExcludePatterns` should only be used for specified linter (#1494)
4. unknown linter breaks //nolint (#1497)
5. report all unknown linters at once (#1477)
6. CI:
* fix Docker tag for Alpine build
7. documentation:
* missing sort-results in the docs (#1514)
* add description of Homebrew's official formula (#1421)
8. others:
* bump `golang.org/x/text` to v0.3.4 (#1293)
* bump `github.com/fatih/color` to from 1.9.0 to 1.10.0 (#1485)
* bump `lodash` from 4.17.15 to 4.17.19 in /.github/peril (#1252)
* bump `polished` from 3.6.6 to 4.0.3 in /docs (#1482)
* bump `gatsby-alias-imports` from 1.0.4 to 1.0.6 in /docs (#1479)
* bump `puppeteer` from 5.3.1 to 5.4.1 in /docs (#1480)
* bump `gatsby-remark-embedder` from 3.0.0 to 4.0.0 in /docs (#1478)
### October 2020
1. new linters:
* `exhaustivestruct`: https://github.com/mbilski/exhaustivestruct
* `go-errorlint`: https://github.com/polyfloyd/go-errorlint
* `tparallel`: https://github.com/moricho/tparallel
* `wrapcheck`: https://github.com/tomarrell/wrapcheck
2. update linters:
* `honnef.co/go/tools` from 2020.1.5 to 2020.1.6
* `exhaustivestruct` from v1.0.1 to v1.1.0
* `exhaustive` to v0.1.0
* `gochecknoglobals`: use https://github.com/leighmcculloch/gochecknoglobals
3. add support for powershell completion (#1408)
4. add `.golangci.yaml` to list of configuration files searched on startup (#1364)
5. support for only specifying default severity (#1396)
6. documentation:
* mention macports installation procedure on macOS (#1352)
* sort linters (#1451)
7. CI:
* add codeQL scanning (#1405)
* fix version details in Docker image (#1471)
* releasing docker image for arm64 (#1383)
* change interval for npm to monthly (#1424)
8. others:
* use tag version for cobra (#1458)
* bump `nancy` to 1.0.1 (#1410)
* bump `gatsby-plugin-catch-links` in /docs (#1415)
* bump `gatsby-plugin-mdx` from 1.2.40 to 1.2.43 in /docs (#1419)
* bump `gatsby-plugin-sharp` from 2.6.31 to 2.6.40 in /docs (#1423)
* bump `gatsby-plugin-sitemap` from 2.4.12 to 2.4.14 in /docs (#1417)
* bump `github.com/mattn/go-colorable` from 0.1.7 to 0.1.8 (#1413)
* bump `github.com/sirupsen/logrus` from 1.6.0 to 1.7.0 (#1412)
* bump `github.com/sourcegraph/go-diff` from 0.6.0 to 0.6.1 (#1414)
* bump `golangci/golangci-lint-action` from v2 to v2.3.0 (#1447) (#1469)
* bump `puppeteer` from 3.3.0 to 5.3.1 in /docs (#1418)
### September 2020
1. update linters:
* `godot` from 0.4.8 to 0.4.9
* `exhaustive` from v0.0.0-20200708172631-8866003e3856 to v0.0.0-20200811152831-6cf413ae40e0
* `gofumpt` from v0.0.0-20200709182408-4fd085cb6d5f to v0.0.0-20200802201014-ab5a8192947d
2. add support for fish completion (#1201)
3. documentation:
* fix typo in performance docs (#1350)
4. CI:
* prevent macos to be marked as passing upon failure (#1381)
* check only for go.mod file (#1397)
* check if go.mod and go.sum are up to dated (#1377)
* trigger Netlify (#1358)
5. others:
* bump `github.com/sourcegraph/go-diff` from 0.5.3 to 0.6.0 (#1353)
* bump `github.com/valyala/quicktemplate` from 1.6.2 to 1.6.3 (#1385)
* ignore known dependency failure in nancy (#1378)
* bump `@mdx-js/mdx` from 1.6.16 to 1.6.18 in /docs (#1401)
* bump `gatsby` from 2.24.52 to 2.24.65 in /docs (#1400)
* bump `gatsby-plugin-canonical-urls` in /docs (#1390)
* bump `gatsby-plugin-google-analytics` in /docs (#1388)
* bump `gatsby-plugin-manifest` from 2.4.23 to 2.4.27 in /docs (#1355)
* bump `gatsby-plugin-mdx` from 1.2.35 to 1.2.40 in /docs (#1386)
* bump `gatsby-plugin-offline` from 3.2.23 to 3.2.27 in /docs (#1368)
* bump `gatsby-plugin-sharp` from 2.6.25 to 2.6.31 in /docs (#1354)
* bump `gatsby-plugin-sitemap` from 2.4.11 to 2.4.12 in /docs (#1344)
* bump `gatsby-remark-autolink-headers` in /docs (#1387)
* bump `gatsby-remark-images` from 3.3.25 to 3.3.28 in /docs (#1345)
* bump `gatsby-remark-images` from 3.3.28 to 3.3.29 in /docs (#1365)
* bump `gatsby-remark-mermaid` from 2.0.0 to 2.1.0 in /docs (#1369)
* bump `gatsby-source-filesystem` in /docs (#1366)
* bump `gatsby-source-filesystem` in /docs (#1389)
* bump `gatsby-transformer-sharp` in /docs (#1402)
* bump `gatsby-transformer-yaml` from 2.4.10 to 2.4.11 in /docs (#1367)
* bump `node-fetch` in /.github/contributors (#1363)
* bump `polished` from 3.6.5 to 3.6.6 in /docs (#1347)
### August 2020
1. new `nlreturn` linter: https://github.com/ssgreg/nlreturn
2. new `gci` linter: https://github.com/daixiang0/gci
3. support `latest` version of golangci-lint in golangci-lint-action
4. update `gosec` linter from 2.3.0 to 2.4.0
5. update `godot` linter from 0.4.2 to 0.4.8
6. update `go-critic` from 0.5.0 to 0.5.2 (#1307)
7. update `nlreturn` from 2.0.1 to 2.0.2 (#1287), 2.0.2 to 2.1.0 (#1327)
8. update `gci` to v0.2.1 (#1292), to v0.2.2 (#1305), to v0.2.4 (#1337),
9. update `funlen` from 0.0.2 to 0.0.3 (#1341)
10. upgrade to golang 1.15 for smaller binary (#1303)
11. support short and json formats for version cmd (#1315)
12. add home directory to config file search paths (#1325)
13. allow for serializing multiple golangci-lint invocations (#1302)
### July 2020
1. `gofumpt` linter:
* update linter
* add `extra-rules` option
* support auto-fixing
2. upgrade `exhaustive` linter
3. upgrade `exportloopref` linter
4. improve 'no such linter' error message
5. sorting result.Issues implementation
6. enhancements in CI:
* Run `nancy` validation for all dependencies
* Move dependabot config to `.github` folder
7. other
* bump `lodash` from 4.17.15 to 4.17.19 in /tools
* bump `golangci/golangci-lint-action` from v1.2.2 to v2
* bump `github.com/valyala/quicktemplate` from 1.5.0 to 1.5.1
### June 2020
1. Add new linters: `gofumpt`
### May 2020
1. Add new linters: `nolintlint`, `goerr113`
2. Updated linters: `godot`, `staticcheck`
3. Launch a [website](https://golangci-lint.run)
### April 2020
1. Add new linters: `testpackage`, `nestif`, `godot`, `gomodguard`, `asciicheck`
2. Add GitHub Actions output format
3. Update linters: `wsl`, `gomodguard`, `gosec`
4. Support `disabled-tags` setting for `gocritic`
5. Mitigate OOM and "failed prerequisites"
6. Self-isolate due to unexpected pandemics
7. Support case-sensitive excludes
8. Allow granular re-enabling excludes by ID, e.g. `EXC0002`
### September 2019
1. Support go1.13
2. Add new linters: `funlen`, `whitespace` (with auto-fix) and `godox`
3. Update linters: `gochecknoglobals`, `scopelint`, `gosec`
4. Provide pre-built binary for ARM and FreeBSD
5. Fix false-positives in `unused`
6. Support `--skip-dirs-use-default`
7. Add support for bash completions
### July 2019
1. Fix parallel writes race condition
2. Update bodyclose with fixed panic
### June 2019
1. Treat Go source files as a plain text by `misspell`: it allows detecting issues in strings, variable names, etc.
2. Implement richer and more stable auto-fix of `misspell` issues.
### May 2019
1. Add [bodyclose](https://github.com/timakin/bodyclose) linter.
2. Support junit-xml output.
### April 2019
1. Update go-critic, new checkers were added: badCall, dupImports, evalOrder, newDeref
2. Fix staticcheck panic on packages that do not compile
3. Make install script work on Windows
4. Fix compatibility with the latest x/tools version and update golang.org/x/tools
5. Correct import path of module sourcegraph/go-diff
6. Fix `max-issues-per-linter` name
7. Fix linting of preprocessed files (e.g. `*.qtpl.go`, goyacc)
8. Enable auto-fixing when running via pre-commit
### March 2019
1. Support the newest `go vet` (with `go/analysis`)
2. Support configuration of `go vet`: e.g. you can set print functions by `linters-settings.govet.settings.printf.funcs`
3. Update megacheck (staticcheck) to 2019.1.1
4. Add [information](https://github.com/golangci/golangci-lint#memory-usage-of-golangci-lint) about controlling space-time trade-off into README
5. Exclude issues by source code line regexp by `issues.exclude-rules[i].source`
6. Build and test on go 1.12
7. Support `--color` option
8. Update x/tools to fix c++ issues
9. Include support for log level
10. Sort linters list in help commands
================================================
FILE: CHANGELOG.md
================================================
Follow the news and releases on [Mastodon](https://fosstodon.org/@golangcilint) and on [Bluesky](https://bsky.app/profile/golangci-lint.run).
`golangci-lint` is a free and open-source project built by volunteers.
If you value it, consider supporting us, we appreciate it!
[](https://donate.golangci.org)
### v2.11.3
_Released on 2026-03-10_
1. Linters bug fixes
* `gosec`: from v2.24.7 to 619ce2117e08
### v2.11.2
_Released on 2026-03-07_
1. Fixes
* `fmt`: fix error when using the `fmt` command with explicit paths.
### v2.11.1
_Released on 2026-03-06_
Due to an error related to AUR, some artifacts of the v2.11.0 release have not been published.
This release contains the same things as v2.11.0.
### v2.11.0
_Released on 2026-03-06_
1. Linters new features or changes
* `errcheck`: from 1.9.0 to 1.10.0 (exclude `crypto/rand.Read` by default)
* `gosec`: from 2.23.0 to 2.24.6 (new rules: `G113`, `G118`, `G119`, `G120`, `G121`, `G122`, `G123`, `G408`, `G707`)
* `noctx`: from 0.4.0 to 0.5.0 (new detection: `httptest.NewRequestWithContext`)
* `prealloc`: from 1.0.2 to 1.1.0
* `revive`: from 1.14.0 to 1.15.0 (⚠️ Breaking change: package-related checks moved from `var-naming` to a new rule `package-naming`)
2. Linters bug fixes
* `gocognit`: from 1.2.0 to 1.2.1
* `gosec`: from 2.24.6 to 2.24.7
* `unqueryvet`: from 1.5.3 to 1.5.4
### v2.10.1
_Released on 2026-02-17_
1. Fixes
* buildssa panic
### v2.10.0
_Released on 2026-02-17_
1. Linters new features or changes
* `ginkgolinter`: from 0.22.0 to 0.23.0
* `gosec`: from 2.22.11 to 2.23.0 (new rules: `G117`, `G602`, `G701`, `G702`, `G703`, `G704`, `G705`, `G706`)
* `staticcheck`: from 0.6.1 to 0.7.0
2. Linters bug fixes
* `godoclint`: from 0.11.1 to 0.11.2
### v2.9.0
_Released on 2026-02-10_
1. Enhancements
* 🎉 go1.26 support
2. Linters new features or changes
* `arangolint`: from 0.3.1 to 0.4.0 (new rule: detect potential query injections)
* `ginkgolinter`: from 0.21.2 to 0.22.0 (support for wrappers)
* `golines`: from 0.14.0 to 0.15.0
* `misspell`: from 0.7.0 to 0.8.0
* `revive`: from v1.13.0 to v1.14.0 (new rules: `epoch-naming`, `use-slices-sort`)
* `unqueryvet`: from 1.4.0 to 1.5.3 (new options: `check-n1`, `check-sql-injection`, `check-tx-leaks`, `allow`, `custom-rules`)
* `wsl_v5`: from 5.3.0 to 5.6.0 (new rule: `after-block`)
3. Linters bug fixes
* `modernize`: from 0.41.0 to 0.42.0
* `prealloc`: from 1.0.1 to 1.0.2
* `protogetter`: from 0.3.18 to 0.3.20
4. Misc.
* Log information about files when configuration verification
* Emit an error when no linters enabled
* Do not collect VCS information when loading code
### v2.8.0
_Released on 2026-01-07_
1. Linters new features or changes
* `godoclint`: from 0.10.2 to 0.11.1 (new rule: `require-stdlib-doclink`)
* `golines`: from 442fd0091d95 to 0.14.0
* `gomoddirectives`: from 0.7.1 to 0.8.0
* `gosec`: from daccba6b93d7 to 2.22.11 (new rule: `G116`)
* `modernize`: from 0.39.0 to 0.40.0 (new analyzers: `stringscut`, `unsafefuncs`)
* `prealloc`: from 1.0.0 to 1.0.1 (message changes)
* `unqueryvet`: from 1.3.0 to 1.4.0 (new options: `check-aliased-wildcard`, `check-string-concat`, `check-format-strings`, `check-string-builder`, `check-subqueries`, `ignored-functions`, `sql-builders`)
2. Linters bug fixes
* `gocritic`: from 0.14.2 to 0.14.3
* `errorlint`: from 1.8.0 to 1.9.0
* `govet`: from 0.39.0 to 0.40.0
* `protogetter`: from 0.3.17 to 0.3.18
* `revive`: add missing enable-default-rules setting
3. Documentation
* docs: split installation page
### v2.7.2
_Released on 2025-12-07_
1. Linter bug fixes
* `gosec`: from 2.22.10 to daccba6b93d7
### v2.7.1
_Released on 2025-12-04_
1. Linter bug fixes
* `modernize`: disable `stringscut` analyzer
### v2.7.0
_Released on 2025-12-03_
1. Bug fixes
* fix: clone args used by `custom` command
2. Linters new features or changes
* `nosprintfhostport`: from 0.2.0 to 0.3.1 (ignore string literals without a colon)
* `unqueryvet`: from 1.2.1 to 1.3.0 (handles `const` and `var` declarations)
* `revive`: from 1.12.0 to 1.13.0 (new option: `enable-default-rules`, new rules: `forbidden-call-in-wg-go`, `unnecessary-if`, `inefficient-map-lookup`)
* `modernize`: from 0.38.0 to 0.39.0 (new analyzers: `plusbuild`, `stringscut`)
3. Linters bug fixes
* `perfsprint`: from 0.10.0 to 0.10.1
* `wrapcheck`: from 2.11.0 to 2.12.0
* `godoclint`: from 0.10.1 to 0.10.2
4. Misc.
* Add some flags to the `custom` command
5. Documentation
* docs: split changelog v1 and v2
### v2.6.2
_Released on 2025-11-14_
1. Bug fixes
* `fmt` command with symlinks
* use file depending on build configuration to invalidate cache
2. Linters bug fixes
* `testableexamples`: from 1.0.0 to 1.0.1
* `testpackage`: from 1.1.1 to 1.1.2
### v2.6.1
_Released on 2025-11-04_
1. Linters bug fixes
* `copyloopvar`: from 1.2.1 to 1.2.2
* `gocritic`: from 0.14.0 to 0.14.2
### v2.6.0
_Released on 2025-10-29_
1. New linters
* Add `modernize` analyzer suite
2. Linters new features or changes
* `arangolint`: from 0.2.0 to 0.3.1
* `dupword`: from 0.1.6 to 0.1.7 (new option `comments-only`)
* `gocritic`: from 0.13.0 to 0.14.0 (new rules/checkers: `zeroByteRepeat`, `dupOption`)
* `gofumpt`: from 0.9.1 to 0.9.2 ("clothe" naked returns is now controlled by the `extra-rules` option)
* `perfsprint`: from 0.9.1 to 0.10.0 (new options: `concat-loop`, `loop-other-ops`)
* `wsl`: from 5.2.0 to 5.3.0
3. Linters bug fixes
* `dupword`: from 0.1.6 to 0.1.7
* `durationcheck`: from 0.0.10 to 0.0.11
* `exptostd`: from 0.4.4 to 0.4.5
* `fatcontext`: from 0.8.1 to 0.9.0
* `forbidigo`: from 2.1.0 to 2.3.0
* `ginkgolinter`: from 0.21.0 to 0.21.2
* `godoclint`: from 0.10.0 to 0.10.1
* `gomoddirectives`: from 0.7.0 to 0.7.1
* `gosec`: from 2.22.8 to 2.22.10
* `makezero`: from 2.0.1 to 2.1.0
* `nilerr`: from 0.1.1 to 0.1.2
* `paralleltest`: from 1.0.14 to 1.0.15
* `protogetter`: from 0.3.16 to 0.3.17
* `unparam`: from 0df0534333a4 to 5beb8c8f8f15
4. Misc.
* fix: ignore some files to hash the version for custom build
### v2.5.0
_Released on 2025-09-21_
1. New linters
* Add `godoclint` linter https://github.com/godoc-lint/godoc-lint
* Add `unqueryvet` linter https://github.com/MirrexOne/unqueryvet
* Add `iotamixing` linter https://github.com/AdminBenni/iota-mixing
2. Linters new features or changes
* `embeddedstructfieldcheck`: from 0.3.0 to 0.4.0 (new option: `empty-line`)
* `err113`: from aea10b59be24 to 0.1.1 (skip internals of `Is` methods for `error` type)
* `ginkgolinter`: from 0.20.0 to 0.21.0 (new option: `force-tonot`)
* `gofumpt`: from 0.8.0 to 0.9.1 (new rule is to "clothe" naked returns for the sake of clarity)
* `ineffassign`: from 0.1.0 to 0.2.0 (new option: `check-escaping-errors`)
* `musttag`: from 0.13.1 to 0.14.0 (support interface methods)
* `revive`: from 1.11.0 to 1.12.0 (new options: `identical-ifelseif-branches`, `identical-ifelseif-conditions`, `identical-switch-branches`, `identical-switch-conditions`, `package-directory-mismatch`, `unsecure-url-scheme`, `use-waitgroup-go`, `useless-fallthrough`)
* `thelper`: from 0.6.3 to 0.7.1 (skip `t.Helper` in functions passed to `synctest.Test`)
* `wsl_v5`: from 5.1.1 to 5.2.0 (improvements related to subexpressions)
3. Linters bug fixes
* `asciicheck`: from 0.4.1 to 0.5.0
* `errname`: from 1.1.0 to 1.1.1
* `fatcontext`: from 0.8.0 to 0.8.1
* `goprintffuncname`: from 0.1.0 to 0.1.1
* `godot`: from 1.5.1 to 1.5.4
* `gosec`: from 2.22.7 to 2.22.8
* `nilerr`: from 0.1.1 to a temporary fork
* `nilnil`: from 1.1.0 to 1.1.1
* `protogetter`: from 0.3.15 to 0.3.16
* `tagliatelle`: from 0.7.1 to 0.7.2
* `testifylint`: from 1.6.1 to 1.6.4
4. Misc.
* fix: "no export data" errors are now handled as a standard typecheck error
5. Documentation
* Improve nolint section about syntax
### v2.4.0
_Released on 2025-08-14_
1. Enhancements
* 🎉 go1.25 support
2. Linters new features or changes
* `exhaustruct`: from v3.3.1 to 4.0.0 (new options: `allow-empty`, `allow-empty-rx`, `allow-empty-returns`, `allow-empty-declarations`)
3. Linters bug fixes
* `godox`: trim filepath from report messages
* `staticcheck`: allow empty options
* `tagalign`: from 1.4.2 to 1.4.3
4. Documentation
* 🌟 New website (with a search engine)
### v2.3.1
_Released on 2025-08-02_
1. Linters bug fixes
* `gci`: from 0.13.6 to 0.13.7
* `gosec`: from 2.22.6 to 2.22.7
* `noctx`: from 0.3.5 to 0.4.0
* `wsl_v5`: from 5.1.0 to 5.1.1
* tagliatelle: force upper case for custom initialisms
### v2.3.0
_Released on 2025-07-21_
1. Linters new features or changes
* `ginkgolinter`: from 0.19.1 to 0.20.0 (new option: `force-assertion-description`)
* `iface`: from 1.4.0 to 1.4.1 (report message improvements)
* `noctx`: from 0.3.4 to 0.3.5 (new detections: `log/slog`, `exec`, `crypto/tls`)
* `revive`: from 1.10.0 to 1.11.0 (new rule: `enforce-switch-style`)
* `wsl_v5`: from 5.0.0 to 5.1.0
2. Linters bug fixes
* `gosec`: from 2.22.5 to 2.22.6
* `noinlineerr`: from 1.0.4 to 1.0.5
* `sloglint`: from 0.11.0 to 0.11.1
3. Misc.
* fix: panic close of closed channel
### v2.2.2
_Released on 2025-07-11_
1. Linters bug fixes
* `noinlineerr`: from 1.0.3 to 1.0.4
2. Documentation
* Improve debug keys documentation
3. Misc.
* fix: panic close of closed channel
* godot: add noinline value into the JSONSchema
### v2.2.1
_Released on 2025-06-28_
1. Linters bug fixes
* `varnamelen`: fix configuration
### v2.2.0
_Released on 2025-06-28_
1. New linters
* Add `arangolint` linter https://github.com/Crocmagnon/arangolint
* Add `embeddedstructfieldcheck` linter https://github.com/manuelarte/embeddedstructfieldcheck
* Add `noinlineerr` linter https://github.com/AlwxSin/noinlineerr
* Add `swaggo` formatter https://github.com/golangci/swaggoswag
2. Linters new features or changes
* `errcheck`: add `verbose` option
* `funcorder`: from 0.2.1 to 0.5.0 (new option `alphabetical`)
* `gomoddirectives`: from 0.6.1 to 0.7.0 (new option `ignore-forbidden`)
* `iface`: from 1.3.1 to 1.4.0 (new option `unexported`)
* `noctx`: from 0.1.0 to 0.3.3 (new report messages, and new rules related to `database/sql`)
* `noctx`: from 0.3.3 to 0.3.4 (new SQL functions detection)
* `revive`: from 1.9.0 to 1.10.0 (new rules: `time-date`, `unnecessary-format`, `use-fmt-print`)
* `usestdlibvars`: from 1.28.0 to 1.29.0 (new option `time-date-month`)
* `wsl`: deprecation
* `wsl_v5`: from 4.7.0 to 5.0.0 (major version with new configuration)
3. Linters bug fixes
* `dupword`: from 0.1.3 to 0.1.6
* `exptostd`: from 0.4.3 to 0.4.4
* `forbidigo`: from 1.6.0 to 2.1.0
* `gci`: consistently format the code
* `spancheck`: from 0.6.4 to 0.6.5
* `goconst`: from 1.8.1 to 1.8.2
* `gosec`: from 2.22.3 to 2.22.4
* `gosec`: from 2.22.4 to 2.22.5
* `makezero`: from 1.2.0 to 2.0.1
* `misspell`: from 0.6.0 to 0.7.0
* `usetesting`: from 0.4.3 to 0.5.0
4. Misc.
* exclusions: fix `path-expect`
* formatters: write the input to `stdout` when using `stdin` and there are no changes
* migration: improve the error message when trying to migrate a migrated config
* `typecheck`: deduplicate errors
* `typecheck`: stops the analysis after the first error
* Deprecate `print-resources-usage` flag
* Unique version per custom build
5. Documentation
* Improves typecheck FAQ
* Adds plugin systems recommendations
* Add description for `linters.default` sets
### v2.1.6
_Released on 2025-05-04_
1. Linters bug fixes
* `godot`: from 1.5.0 to 1.5.1
* `musttag`: from 0.13.0 to 0.13.1
2. Documentation
* Add note about golangci-lint v2 integration in VS Code
### v2.1.5
_Released on 2025-04-24_
Due to an error related to Snapcraft, some artifacts of the v2.1.4 release have not been published.
This release contains the same things as v2.1.3.
### v2.1.4
_Released on 2025-04-24_
Due to an error related to Snapcraft, some artifacts of the v2.1.3 release have not been published.
This release contains the same things as v2.1.3.
### v2.1.3
_Released on 2025-04-24_
1. Linters bug fixes
* `fatcontext`: from 0.7.2 to 0.8.0
2. Misc.
* migration: fix `nakedret.max-func-lines: 0`
* migration: fix order of `staticcheck` settings
* fix: add `go.mod` hash to the cache salt
* fix: use diagnostic position for related information position
### v2.1.2
_Released on 2025-04-15_
1. Linters bug fixes
* `exptostd`: from 0.4.2 to 0.4.3
* `gofumpt`: from 0.7.0 to 0.8.0
* `protogetter`: from 0.3.13 to 0.3.15
* `usetesting`: from 0.4.2 to 0.4.3
### v2.1.1
_Released on 2025-04-12_
The release process of v2.1.0 failed due to a regression inside goreleaser.
The binaries of v2.1.0 have been published, but not the other artifacts (AUR, Docker, etc.).
### v2.1.0
_Released on 2025-04-12_
1. Enhancements
* Add an option to display absolute paths (`--path-mode=abs`)
* Add configuration path placeholder (`${config-path}`)
* Add `warn-unused` option for `fmt` command
* Colored diff for `fmt` command (`golangci-lint fmt --diff-colored`)
2. New linters
* Add `funcorder` linter https://github.com/manuelarte/funcorder
3. Linters new features or changes
* `errorlint`: from 1.7.1 to 1.8.0 (automatic error comparison and type assertion fixes)
* ⚠️ `goconst`: `ignore-strings` is deprecated and replaced by `ignore-string-values`
* `goconst`: from 1.7.1 to 1.8.1 (new options: `find-duplicates`, `eval-const-expressions`)
* `govet`: add `httpmux` analyzer
* `nilnesserr`: from 0.1.2 to 0.2.0 (detect more cases)
* `paralleltest`: from 1.0.10 to 1.0.14 (checks only `_test.go` files)
* `revive`: from 1.7.0 to 1.9.0 (support kebab case for setting names)
* `sloglint`: from 0.9.0 to 0.11.0 (autofix, new option `msg-style`, suggest `slog.DiscardHandler`)
* `wrapcheck`: from 2.10.0 to 2.11.0 (new option `report-internal-errors`)
* `wsl`: from 4.6.0 to 4.7.0 (cgo files are always excluded)
4. Linters bug fixes
* `fatcontext`: from 0.7.1 to 0.7.2
* `gocritic`: fix `importshadow` checker
* `gosec`: from 2.22.2 to 2.22.3
* `ireturn`: from 0.3.1 to 0.4.0
* `loggercheck`: from 0.10.1 to 0.11.0
* `nakedret`: from 2.0.5 to 2.0.6
* `nonamedreturns`: from 1.0.5 to 1.0.6
* `protogetter`: from 0.3.12 to 0.3.13
* `testifylint`: from 1.6.0 to 1.6.1
* `unconvert`: update to HEAD
5. Misc.
* Fixes memory leaks when using go1.(N) with golangci-lint built with go1.(N-X)
* Adds `golangci-lint-fmt` pre-commit hook
6. Documentation
* Improvements
* Updates section about vscode integration
### v2.0.2
_Released on 2025-03-25_
1. Misc.
* Fixes flags parsing for formatters
* Fixes the filepath used by the exclusion `source` option
2. Documentation
* Adds a section about flags migration
* Cleaning pages with v1 options
### v2.0.1
_Released on 2025-03-24_
1. Linters/formatters bug fixes
* `golines`: fix settings during linter load
2. Misc.
* Validates the `version` field before the configuration
* `forbidigo`: fix migration
### v2.0.0
_Released on 2025-03-24_
1. Enhancements
* 🌟 New `golangci-lint fmt` command with dedicated [formatter configuration](https://golangci-lint.run/docs/welcome/quick-start/#formatting)
* ♻️ New `golangci-lint migrate` command to help migration from v1 to v2 (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#command-migrate))
* ⚠️ New default values (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/))
* ⚠️ No exclusions by default (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#issuesexclude-use-default))
* ⚠️ New default sort order (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#outputsort-order))
* 🌟 New option `run.relative-path-mode` (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#runrelative-path-mode))
* 🌟 New linters configuration (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#linters))
* 🌟 New output format configuration (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#output))
* 🌟 New `--fast-only` flag (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#lintersfast))
* 🌟 New option `linters.exclusions.warn-unused` to log a warning if an exclusion rule is unused.
2. New linters/formatters
* Add `golines` formatter https://github.com/segmentio/golines
3. Linters new features
* ⚠️ Merge `staticcheck`, `stylecheck`, `gosimple` into one linter (`staticcheck`) (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#lintersenablestylecheckgosimplestaticcheck))
* `gocritic`: from 0.12.0 to 0.13.0
* `gomodguard`: from 1.3.5 to 1.4.1 (block explicit indirect dependencies)
* `nilnil`: from 1.0.1 to 1.1.0 (new option: `only-two`)
* `perfsprint`: from 0.8.2 to 0.9.1 (checker name in the diagnostic message)
* `staticcheck`: new `quickfix` set of rules
* `testifylint`: from 1.5.2 to 1.6.0 (new options: `equal-values`, `suite-method-signature`, `require-string-msg`)
* `wsl`: from 4.5.0 to 4.6.0 (new option: `allow-cuddle-used-in-block`)
4. Linters bug fixes
* `bidichk`: from 0.3.2 to 0.3.3
* `errchkjson`: from 0.4.0 to 0.4.1
* `errname`: from 1.0.0 to 1.1.0
* `funlen`: fix `ignore-comments` option
* `gci`: from 0.13.5 to 0.13.6
* `gosmopolitan`: from 1.2.2 to 1.3.0
* `inamedparam`: from 0.1.3 to 0.2.0
* `intrange`: from 0.3.0 to 0.3.1
* `protogetter`: from 0.3.9 to 0.3.12
* `unparam`: from 8a5130ca722f to 0df0534333a4
5. Misc.
* 🧹 Configuration options renaming (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/))
* 🧹 Remove options (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/))
* 🧹 Remove flags (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/))
* 🧹 Remove alternative names (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/#alternative-linter-names))
* 🧹 Remove or replace deprecated elements (cf. [Migration guide](https://golangci-lint.run/docs/product/migration-guide/))
* Adds an option to display some commands as JSON:
* `golangci-lint config path --json`
* `golangci-lint help linters --json`
* `golangci-lint help formatters --json`
* `golangci-lint linters --json`
* `golangci-lint formatters --json`
* `golangci-lint version --json`
6. Documentation
* [Migration guide](https://golangci-lint.run/docs/product/migration-guide/)
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: Makefile
================================================
.DEFAULT_GOAL = test
.PHONY: FORCE
# enable consistent Go 1.12/1.13 GOPROXY behavior.
export GOPROXY = https://proxy.golang.org
BINARY = golangci-lint
ifeq ($(OS),Windows_NT)
BINARY := $(BINARY).exe
endif
# Build
build: $(BINARY)
.PHONY: build
build_race:
go build -race -o $(BINARY) ./cmd/golangci-lint
.PHONY: build_race
clean:
rm -f $(BINARY)
rm -f test/path
rm -f tools/Dracula.itermcolors
rm -f tools/svg-term
rm -rf tools/node_modules
.PHONY: clean
# Test
test: export GOLANGCI_LINT_INSTALLED = true
test: CGO_ENABLED=1
test: build
GL_TEST_RUN=1 ./$(BINARY) run -v
GL_TEST_RUN=1 go test -v -parallel 2 ./...
.PHONY: test
test_race: build_race
GL_TEST_RUN=1 ./$(BINARY) run -v --timeout=5m
.PHONY: test_race
# ex: T=output.go make test_integration
# the value of `T` is the name of a file from `test/testdata`
test_integration:
GL_TEST_RUN=1 go test -v ./test -count 1 -run TestSourcesFromTestdata/$T
.PHONY: test_integration
# ex: T=multiple-issues-fix.go make test_integration_fix
# the value of `T` is the name of a file from `test/testdata/fix`
test_integration_fix: build
GL_TEST_RUN=1 go test -v ./test -count 1 -run TestFix/$T
.PHONY: test_integration_fix
# Maintenance
fast_generate: assets/github-action-config.json
.PHONY: fast_generate
fast_check_generated:
$(MAKE) --always-make fast_generate
git checkout -- go.mod go.sum # can differ between go1.16 and go1.17
git diff --exit-code # check no changes
# Migration
clone_config:
go run ./pkg/commands/internal/migrate/cloner/
# Benchmark
# Benchmark with a local version
# LINTER=gosec VERSION=v1.59.0 make bench_local
bench_local: hyperfine
@:$(call check_defined, LINTER VERSION, 'missing parameter(s)')
@./scripts/bench/bench_local.sh $(LINTER) $(VERSION)
.PHONY: bench_local
# Benchmark between 2 existing versions
# make bench_version LINTER=gosec VERSION_OLD=v1.58.2 VERSION_NEW=v1.59.0
bench_version: hyperfine
@:$(call check_defined, LINTER VERSION_OLD VERSION_NEW, 'missing parameter(s)')
@./scripts/bench/bench_version.sh $(LINTER) $(VERSION_OLD) $(VERSION_NEW)
.PHONY: bench_version
hyperfine:
@which hyperfine > /dev/null || (echo "Please install hyperfine https://github.com/sharkdp/hyperfine#installation" && exit 1)
.PHONY: hyperfine
# Non-PHONY targets (real files)
$(BINARY): FORCE
go build -o $@ ./cmd/golangci-lint
assets/github-action-config.json: FORCE $(BINARY)
# go run ./scripts/gen_github_action_config/main.go $@
cd ./scripts/gen_github_action_config/; go run . ../../$@
go.mod: FORCE
go mod tidy
go mod verify
go.sum: go.mod
# Documentation
docs_serve: website_expand_templates
@make -C ./docs serve
.PHONY: docs_serve
docs_clean:
@make -C ./docs clean
.PHONY: docs_clean
docs_build: website_copy_install_sh website_copy_jsonschema website_expand_templates
@make -C ./docs build
.PHONY: docs_build
docs/static/demo.gif: FORCE
vhs docs/golangci-lint.tape
website_copy_jsonschema:
go run ./scripts/website/copy_jsonschema/
.PHONY: website_copy_jsonschema
website_copy_install_sh:
cp install.sh ./docs/static/
.PHONY: website_copy_install_sh
website_expand_templates:
go run ./scripts/website/expand_templates/
.PHONY: website_expand_templates
website_dump_info:
go run ./scripts/website/dump_info/
.PHONY: website_dump_info
# Functions
# Check that given variables are set and all have non-empty values,
# die with an error otherwise.
#
# Params:
# 1. Variable name(s) to test.
# 2. (optional) Error message to print.
#
# https://stackoverflow.com/a/10858332/8228109
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined $1$(if $2, ($2))))
================================================
FILE: README.md
================================================
golangci-lint
Fast linters runner for Go
---
`golangci-lint` is a fast Go linters runner.
It runs linters in parallel, uses caching, supports YAML configuration,
integrates with all major IDEs, and includes over a hundred linters.
## Install `golangci-lint`
- [On my machine](https://golangci-lint.run/docs/welcome/install/local);
- [On CI/CD systems](https://golangci-lint.run/docs/welcome/install/ci).
## Documentation
Documentation is hosted at https://golangci-lint.run.
## Social Networks
[](https://gophers.slack.com/archives/CS0TBRKPC)
[](https://fosstodon.org/@golangcilint)
[](https://bsky.app/profile/golangci-lint.run)
[](https://twitter.com/golangci)
## Support Us
`golangci-lint` is a free and open-source project built by volunteers.
If you value it, consider supporting us, we appreciate it! :heart:
[](https://donate.golangci.org)
[](https://golangci-lint.run/docs/product/thanks/)
## Badges

[](/LICENSE)
[](https://github.com/golangci/golangci-lint/releases/latest)
[](https://hub.docker.com/r/golangci/golangci-lint)
[](https://somsubhra.github.io/github-release-stats/?username=golangci&repository=golangci-lint)
## Contributors
This project exists thanks to all the people who contribute. [How to contribute](https://golangci-lint.run/docs/contributing/).
## Sponsors
## Stargazers over time
[](https://starchart.cc/golangci/golangci-lint)
================================================
FILE: assets/github-action-config-v1.json
================================================
{
"MinorVersionToConfig": {
"latest": {
"TargetVersion": "v1.64.8"
},
"v1.10": {
"Error": "golangci-lint version 'v1.10' isn't supported: we support only v1.28.3 and later versions"
},
"v1.11": {
"Error": "golangci-lint version 'v1.11' isn't supported: we support only v1.28.3 and later versions"
},
"v1.12": {
"Error": "golangci-lint version 'v1.12' isn't supported: we support only v1.28.3 and later versions"
},
"v1.13": {
"Error": "golangci-lint version 'v1.13' isn't supported: we support only v1.28.3 and later versions"
},
"v1.14": {
"Error": "golangci-lint version 'v1.14' isn't supported: we support only v1.28.3 and later versions"
},
"v1.15": {
"Error": "golangci-lint version 'v1.15' isn't supported: we support only v1.28.3 and later versions"
},
"v1.16": {
"Error": "golangci-lint version 'v1.16' isn't supported: we support only v1.28.3 and later versions"
},
"v1.17": {
"Error": "golangci-lint version 'v1.17' isn't supported: we support only v1.28.3 and later versions"
},
"v1.18": {
"Error": "golangci-lint version 'v1.18' isn't supported: we support only v1.28.3 and later versions"
},
"v1.19": {
"Error": "golangci-lint version 'v1.19' isn't supported: we support only v1.28.3 and later versions"
},
"v1.20": {
"Error": "golangci-lint version 'v1.20' isn't supported: we support only v1.28.3 and later versions"
},
"v1.21": {
"Error": "golangci-lint version 'v1.21' isn't supported: we support only v1.28.3 and later versions"
},
"v1.22": {
"Error": "golangci-lint version 'v1.22' isn't supported: we support only v1.28.3 and later versions"
},
"v1.23": {
"Error": "golangci-lint version 'v1.23' isn't supported: we support only v1.28.3 and later versions"
},
"v1.24": {
"Error": "golangci-lint version 'v1.24' isn't supported: we support only v1.28.3 and later versions"
},
"v1.25": {
"Error": "golangci-lint version 'v1.25' isn't supported: we support only v1.28.3 and later versions"
},
"v1.26": {
"Error": "golangci-lint version 'v1.26' isn't supported: we support only v1.28.3 and later versions"
},
"v1.27": {
"Error": "golangci-lint version 'v1.27' isn't supported: we support only v1.28.3 and later versions"
},
"v1.28": {
"TargetVersion": "v1.28.3"
},
"v1.29": {
"TargetVersion": "v1.29.0"
},
"v1.3": {
"Error": "golangci-lint version 'v1.3' isn't supported: we support only v1.28.3 and later versions"
},
"v1.30": {
"TargetVersion": "v1.30.0"
},
"v1.31": {
"TargetVersion": "v1.31.0"
},
"v1.32": {
"TargetVersion": "v1.32.2"
},
"v1.33": {
"TargetVersion": "v1.33.2"
},
"v1.34": {
"TargetVersion": "v1.34.1"
},
"v1.35": {
"TargetVersion": "v1.35.2"
},
"v1.36": {
"TargetVersion": "v1.36.0"
},
"v1.37": {
"TargetVersion": "v1.37.1"
},
"v1.38": {
"TargetVersion": "v1.38.0"
},
"v1.39": {
"TargetVersion": "v1.39.0"
},
"v1.4": {
"Error": "golangci-lint version 'v1.4' isn't supported: we support only v1.28.3 and later versions"
},
"v1.40": {
"TargetVersion": "v1.40.1"
},
"v1.41": {
"TargetVersion": "v1.41.1"
},
"v1.42": {
"TargetVersion": "v1.42.1"
},
"v1.43": {
"TargetVersion": "v1.43.0"
},
"v1.44": {
"TargetVersion": "v1.44.2"
},
"v1.45": {
"TargetVersion": "v1.45.2"
},
"v1.46": {
"TargetVersion": "v1.46.2"
},
"v1.47": {
"TargetVersion": "v1.47.3"
},
"v1.48": {
"TargetVersion": "v1.48.0"
},
"v1.49": {
"TargetVersion": "v1.49.0"
},
"v1.5": {
"Error": "golangci-lint version 'v1.5' isn't supported: we support only v1.28.3 and later versions"
},
"v1.50": {
"TargetVersion": "v1.50.1"
},
"v1.51": {
"TargetVersion": "v1.51.2"
},
"v1.52": {
"TargetVersion": "v1.52.2"
},
"v1.53": {
"TargetVersion": "v1.53.3"
},
"v1.54": {
"TargetVersion": "v1.54.2"
},
"v1.55": {
"TargetVersion": "v1.55.2"
},
"v1.56": {
"TargetVersion": "v1.56.2"
},
"v1.57": {
"TargetVersion": "v1.57.2"
},
"v1.58": {
"TargetVersion": "v1.58.2"
},
"v1.59": {
"TargetVersion": "v1.59.1"
},
"v1.6": {
"Error": "golangci-lint version 'v1.6' isn't supported: we support only v1.28.3 and later versions"
},
"v1.60": {
"TargetVersion": "v1.60.3"
},
"v1.61": {
"TargetVersion": "v1.61.0"
},
"v1.62": {
"TargetVersion": "v1.62.2"
},
"v1.63": {
"TargetVersion": "v1.63.4"
},
"v1.64": {
"TargetVersion": "v1.64.8"
},
"v1.7": {
"Error": "golangci-lint version 'v1.7' isn't supported: we support only v1.28.3 and later versions"
},
"v1.8": {
"Error": "golangci-lint version 'v1.8' isn't supported: we support only v1.28.3 and later versions"
},
"v1.9": {
"Error": "golangci-lint version 'v1.9' isn't supported: we support only v1.28.3 and later versions"
},
"v2.0": {
"Error": "golangci-lint version 'v2.0' isn't supported: only v1 versions are supported"
},
"v2.1": {
"Error": "golangci-lint version 'v2.1' isn't supported: only v1 versions are supported"
},
"v2.10": {
"Error": "golangci-lint version 'v2.10' isn't supported: only v1 versions are supported"
},
"v2.11": {
"Error": "golangci-lint version 'v2.11' isn't supported: only v1 versions are supported"
},
"v2.2": {
"Error": "golangci-lint version 'v2.2' isn't supported: only v1 versions are supported"
},
"v2.3": {
"Error": "golangci-lint version 'v2.3' isn't supported: only v1 versions are supported"
},
"v2.4": {
"Error": "golangci-lint version 'v2.4' isn't supported: only v1 versions are supported"
},
"v2.5": {
"Error": "golangci-lint version 'v2.5' isn't supported: only v1 versions are supported"
},
"v2.6": {
"Error": "golangci-lint version 'v2.6' isn't supported: only v1 versions are supported"
},
"v2.7": {
"Error": "golangci-lint version 'v2.7' isn't supported: only v1 versions are supported"
},
"v2.8": {
"Error": "golangci-lint version 'v2.8' isn't supported: only v1 versions are supported"
},
"v2.9": {
"Error": "golangci-lint version 'v2.9' isn't supported: only v1 versions are supported"
}
}
}
================================================
FILE: assets/github-action-config-v2.json
================================================
{
"MinorVersionToConfig": {
"latest": {
"TargetVersion": "v2.11.3"
},
"v1.10": {
"Error": "golangci-lint version 'v1.10' isn't supported: we support only v2.0.0 and later versions"
},
"v1.11": {
"Error": "golangci-lint version 'v1.11' isn't supported: we support only v2.0.0 and later versions"
},
"v1.12": {
"Error": "golangci-lint version 'v1.12' isn't supported: we support only v2.0.0 and later versions"
},
"v1.13": {
"Error": "golangci-lint version 'v1.13' isn't supported: we support only v2.0.0 and later versions"
},
"v1.14": {
"Error": "golangci-lint version 'v1.14' isn't supported: we support only v2.0.0 and later versions"
},
"v1.15": {
"Error": "golangci-lint version 'v1.15' isn't supported: we support only v2.0.0 and later versions"
},
"v1.16": {
"Error": "golangci-lint version 'v1.16' isn't supported: we support only v2.0.0 and later versions"
},
"v1.17": {
"Error": "golangci-lint version 'v1.17' isn't supported: we support only v2.0.0 and later versions"
},
"v1.18": {
"Error": "golangci-lint version 'v1.18' isn't supported: we support only v2.0.0 and later versions"
},
"v1.19": {
"Error": "golangci-lint version 'v1.19' isn't supported: we support only v2.0.0 and later versions"
},
"v1.20": {
"Error": "golangci-lint version 'v1.20' isn't supported: we support only v2.0.0 and later versions"
},
"v1.21": {
"Error": "golangci-lint version 'v1.21' isn't supported: we support only v2.0.0 and later versions"
},
"v1.22": {
"Error": "golangci-lint version 'v1.22' isn't supported: we support only v2.0.0 and later versions"
},
"v1.23": {
"Error": "golangci-lint version 'v1.23' isn't supported: we support only v2.0.0 and later versions"
},
"v1.24": {
"Error": "golangci-lint version 'v1.24' isn't supported: we support only v2.0.0 and later versions"
},
"v1.25": {
"Error": "golangci-lint version 'v1.25' isn't supported: we support only v2.0.0 and later versions"
},
"v1.26": {
"Error": "golangci-lint version 'v1.26' isn't supported: we support only v2.0.0 and later versions"
},
"v1.27": {
"Error": "golangci-lint version 'v1.27' isn't supported: we support only v2.0.0 and later versions"
},
"v1.28": {
"Error": "golangci-lint version 'v1.28' isn't supported: we support only v2.0.0 and later versions"
},
"v1.29": {
"Error": "golangci-lint version 'v1.29' isn't supported: we support only v2.0.0 and later versions"
},
"v1.3": {
"Error": "golangci-lint version 'v1.3' isn't supported: we support only v2.0.0 and later versions"
},
"v1.30": {
"Error": "golangci-lint version 'v1.30' isn't supported: we support only v2.0.0 and later versions"
},
"v1.31": {
"Error": "golangci-lint version 'v1.31' isn't supported: we support only v2.0.0 and later versions"
},
"v1.32": {
"Error": "golangci-lint version 'v1.32' isn't supported: we support only v2.0.0 and later versions"
},
"v1.33": {
"Error": "golangci-lint version 'v1.33' isn't supported: we support only v2.0.0 and later versions"
},
"v1.34": {
"Error": "golangci-lint version 'v1.34' isn't supported: we support only v2.0.0 and later versions"
},
"v1.35": {
"Error": "golangci-lint version 'v1.35' isn't supported: we support only v2.0.0 and later versions"
},
"v1.36": {
"Error": "golangci-lint version 'v1.36' isn't supported: we support only v2.0.0 and later versions"
},
"v1.37": {
"Error": "golangci-lint version 'v1.37' isn't supported: we support only v2.0.0 and later versions"
},
"v1.38": {
"Error": "golangci-lint version 'v1.38' isn't supported: we support only v2.0.0 and later versions"
},
"v1.39": {
"Error": "golangci-lint version 'v1.39' isn't supported: we support only v2.0.0 and later versions"
},
"v1.4": {
"Error": "golangci-lint version 'v1.4' isn't supported: we support only v2.0.0 and later versions"
},
"v1.40": {
"Error": "golangci-lint version 'v1.40' isn't supported: we support only v2.0.0 and later versions"
},
"v1.41": {
"Error": "golangci-lint version 'v1.41' isn't supported: we support only v2.0.0 and later versions"
},
"v1.42": {
"Error": "golangci-lint version 'v1.42' isn't supported: we support only v2.0.0 and later versions"
},
"v1.43": {
"Error": "golangci-lint version 'v1.43' isn't supported: we support only v2.0.0 and later versions"
},
"v1.44": {
"Error": "golangci-lint version 'v1.44' isn't supported: we support only v2.0.0 and later versions"
},
"v1.45": {
"Error": "golangci-lint version 'v1.45' isn't supported: we support only v2.0.0 and later versions"
},
"v1.46": {
"Error": "golangci-lint version 'v1.46' isn't supported: we support only v2.0.0 and later versions"
},
"v1.47": {
"Error": "golangci-lint version 'v1.47' isn't supported: we support only v2.0.0 and later versions"
},
"v1.48": {
"Error": "golangci-lint version 'v1.48' isn't supported: we support only v2.0.0 and later versions"
},
"v1.49": {
"Error": "golangci-lint version 'v1.49' isn't supported: we support only v2.0.0 and later versions"
},
"v1.5": {
"Error": "golangci-lint version 'v1.5' isn't supported: we support only v2.0.0 and later versions"
},
"v1.50": {
"Error": "golangci-lint version 'v1.50' isn't supported: we support only v2.0.0 and later versions"
},
"v1.51": {
"Error": "golangci-lint version 'v1.51' isn't supported: we support only v2.0.0 and later versions"
},
"v1.52": {
"Error": "golangci-lint version 'v1.52' isn't supported: we support only v2.0.0 and later versions"
},
"v1.53": {
"Error": "golangci-lint version 'v1.53' isn't supported: we support only v2.0.0 and later versions"
},
"v1.54": {
"Error": "golangci-lint version 'v1.54' isn't supported: we support only v2.0.0 and later versions"
},
"v1.55": {
"Error": "golangci-lint version 'v1.55' isn't supported: we support only v2.0.0 and later versions"
},
"v1.56": {
"Error": "golangci-lint version 'v1.56' isn't supported: we support only v2.0.0 and later versions"
},
"v1.57": {
"Error": "golangci-lint version 'v1.57' isn't supported: we support only v2.0.0 and later versions"
},
"v1.58": {
"Error": "golangci-lint version 'v1.58' isn't supported: we support only v2.0.0 and later versions"
},
"v1.59": {
"Error": "golangci-lint version 'v1.59' isn't supported: we support only v2.0.0 and later versions"
},
"v1.6": {
"Error": "golangci-lint version 'v1.6' isn't supported: we support only v2.0.0 and later versions"
},
"v1.60": {
"Error": "golangci-lint version 'v1.60' isn't supported: we support only v2.0.0 and later versions"
},
"v1.61": {
"Error": "golangci-lint version 'v1.61' isn't supported: we support only v2.0.0 and later versions"
},
"v1.62": {
"Error": "golangci-lint version 'v1.62' isn't supported: we support only v2.0.0 and later versions"
},
"v1.63": {
"Error": "golangci-lint version 'v1.63' isn't supported: we support only v2.0.0 and later versions"
},
"v1.64": {
"Error": "golangci-lint version 'v1.64' isn't supported: we support only v2.0.0 and later versions"
},
"v1.7": {
"Error": "golangci-lint version 'v1.7' isn't supported: we support only v2.0.0 and later versions"
},
"v1.8": {
"Error": "golangci-lint version 'v1.8' isn't supported: we support only v2.0.0 and later versions"
},
"v1.9": {
"Error": "golangci-lint version 'v1.9' isn't supported: we support only v2.0.0 and later versions"
},
"v2.0": {
"TargetVersion": "v2.0.2"
},
"v2.1": {
"TargetVersion": "v2.1.6"
},
"v2.10": {
"TargetVersion": "v2.10.1"
},
"v2.11": {
"TargetVersion": "v2.11.3"
},
"v2.2": {
"TargetVersion": "v2.2.2"
},
"v2.3": {
"TargetVersion": "v2.3.1"
},
"v2.4": {
"TargetVersion": "v2.4.0"
},
"v2.5": {
"TargetVersion": "v2.5.0"
},
"v2.6": {
"TargetVersion": "v2.6.2"
},
"v2.7": {
"TargetVersion": "v2.7.2"
},
"v2.8": {
"TargetVersion": "v2.8.0"
},
"v2.9": {
"TargetVersion": "v2.9.0"
}
}
}
================================================
FILE: assets/github-action-config.json
================================================
{
"MinorVersionToConfig": {
"latest": {
"TargetVersion": "v1.64.8"
},
"v1.10": {
"Error": "golangci-lint version 'v1.10' isn't supported: we support only v1.28.3 and later versions"
},
"v1.11": {
"Error": "golangci-lint version 'v1.11' isn't supported: we support only v1.28.3 and later versions"
},
"v1.12": {
"Error": "golangci-lint version 'v1.12' isn't supported: we support only v1.28.3 and later versions"
},
"v1.13": {
"Error": "golangci-lint version 'v1.13' isn't supported: we support only v1.28.3 and later versions"
},
"v1.14": {
"Error": "golangci-lint version 'v1.14' isn't supported: we support only v1.28.3 and later versions"
},
"v1.15": {
"Error": "golangci-lint version 'v1.15' isn't supported: we support only v1.28.3 and later versions"
},
"v1.16": {
"Error": "golangci-lint version 'v1.16' isn't supported: we support only v1.28.3 and later versions"
},
"v1.17": {
"Error": "golangci-lint version 'v1.17' isn't supported: we support only v1.28.3 and later versions"
},
"v1.18": {
"Error": "golangci-lint version 'v1.18' isn't supported: we support only v1.28.3 and later versions"
},
"v1.19": {
"Error": "golangci-lint version 'v1.19' isn't supported: we support only v1.28.3 and later versions"
},
"v1.20": {
"Error": "golangci-lint version 'v1.20' isn't supported: we support only v1.28.3 and later versions"
},
"v1.21": {
"Error": "golangci-lint version 'v1.21' isn't supported: we support only v1.28.3 and later versions"
},
"v1.22": {
"Error": "golangci-lint version 'v1.22' isn't supported: we support only v1.28.3 and later versions"
},
"v1.23": {
"Error": "golangci-lint version 'v1.23' isn't supported: we support only v1.28.3 and later versions"
},
"v1.24": {
"Error": "golangci-lint version 'v1.24' isn't supported: we support only v1.28.3 and later versions"
},
"v1.25": {
"Error": "golangci-lint version 'v1.25' isn't supported: we support only v1.28.3 and later versions"
},
"v1.26": {
"Error": "golangci-lint version 'v1.26' isn't supported: we support only v1.28.3 and later versions"
},
"v1.27": {
"Error": "golangci-lint version 'v1.27' isn't supported: we support only v1.28.3 and later versions"
},
"v1.28": {
"TargetVersion": "v1.28.3"
},
"v1.29": {
"TargetVersion": "v1.29.0"
},
"v1.3": {
"Error": "golangci-lint version 'v1.3' isn't supported: we support only v1.28.3 and later versions"
},
"v1.30": {
"TargetVersion": "v1.30.0"
},
"v1.31": {
"TargetVersion": "v1.31.0"
},
"v1.32": {
"TargetVersion": "v1.32.2"
},
"v1.33": {
"TargetVersion": "v1.33.2"
},
"v1.34": {
"TargetVersion": "v1.34.1"
},
"v1.35": {
"TargetVersion": "v1.35.2"
},
"v1.36": {
"TargetVersion": "v1.36.0"
},
"v1.37": {
"TargetVersion": "v1.37.1"
},
"v1.38": {
"TargetVersion": "v1.38.0"
},
"v1.39": {
"TargetVersion": "v1.39.0"
},
"v1.4": {
"Error": "golangci-lint version 'v1.4' isn't supported: we support only v1.28.3 and later versions"
},
"v1.40": {
"TargetVersion": "v1.40.1"
},
"v1.41": {
"TargetVersion": "v1.41.1"
},
"v1.42": {
"TargetVersion": "v1.42.1"
},
"v1.43": {
"TargetVersion": "v1.43.0"
},
"v1.44": {
"TargetVersion": "v1.44.2"
},
"v1.45": {
"TargetVersion": "v1.45.2"
},
"v1.46": {
"TargetVersion": "v1.46.2"
},
"v1.47": {
"TargetVersion": "v1.47.3"
},
"v1.48": {
"TargetVersion": "v1.48.0"
},
"v1.49": {
"TargetVersion": "v1.49.0"
},
"v1.5": {
"Error": "golangci-lint version 'v1.5' isn't supported: we support only v1.28.3 and later versions"
},
"v1.50": {
"TargetVersion": "v1.50.1"
},
"v1.51": {
"TargetVersion": "v1.51.2"
},
"v1.52": {
"TargetVersion": "v1.52.2"
},
"v1.53": {
"TargetVersion": "v1.53.3"
},
"v1.54": {
"TargetVersion": "v1.54.2"
},
"v1.55": {
"TargetVersion": "v1.55.2"
},
"v1.56": {
"TargetVersion": "v1.56.2"
},
"v1.57": {
"TargetVersion": "v1.57.2"
},
"v1.58": {
"TargetVersion": "v1.58.2"
},
"v1.59": {
"TargetVersion": "v1.59.1"
},
"v1.6": {
"Error": "golangci-lint version 'v1.6' isn't supported: we support only v1.28.3 and later versions"
},
"v1.60": {
"TargetVersion": "v1.60.3"
},
"v1.61": {
"TargetVersion": "v1.61.0"
},
"v1.62": {
"TargetVersion": "v1.62.2"
},
"v1.63": {
"TargetVersion": "v1.63.4"
},
"v1.64": {
"TargetVersion": "v1.64.8"
},
"v1.7": {
"Error": "golangci-lint version 'v1.7' isn't supported: we support only v1.28.3 and later versions"
},
"v1.8": {
"Error": "golangci-lint version 'v1.8' isn't supported: we support only v1.28.3 and later versions"
},
"v1.9": {
"Error": "golangci-lint version 'v1.9' isn't supported: we support only v1.28.3 and later versions"
},
"v2.0": {
"Error": "golangci-lint version 'v2.0' isn't supported: only v1 versions are supported"
},
"v2.1": {
"Error": "golangci-lint version 'v2.1' isn't supported: only v1 versions are supported"
},
"v2.10": {
"Error": "golangci-lint version 'v2.10' isn't supported: only v1 versions are supported"
},
"v2.11": {
"Error": "golangci-lint version 'v2.11' isn't supported: only v1 versions are supported"
},
"v2.2": {
"Error": "golangci-lint version 'v2.2' isn't supported: only v1 versions are supported"
},
"v2.3": {
"Error": "golangci-lint version 'v2.3' isn't supported: only v1 versions are supported"
},
"v2.4": {
"Error": "golangci-lint version 'v2.4' isn't supported: only v1 versions are supported"
},
"v2.5": {
"Error": "golangci-lint version 'v2.5' isn't supported: only v1 versions are supported"
},
"v2.6": {
"Error": "golangci-lint version 'v2.6' isn't supported: only v1 versions are supported"
},
"v2.7": {
"Error": "golangci-lint version 'v2.7' isn't supported: only v1 versions are supported"
},
"v2.8": {
"Error": "golangci-lint version 'v2.8' isn't supported: only v1 versions are supported"
},
"v2.9": {
"Error": "golangci-lint version 'v2.9' isn't supported: only v1 versions are supported"
}
}
}
================================================
FILE: build/buildx-alpine.Dockerfile
================================================
# syntax=docker/dockerfile:1.4
FROM golang:1.26-alpine
ARG TARGETPLATFORM
# related to https://github.com/golangci/golangci-lint/issues/3107
ENV GOROOT /usr/local/go
# Allow to download a more recent version of Go.
# https://go.dev/doc/toolchain
# GOTOOLCHAIN=auto is shorthand for GOTOOLCHAIN=local+auto
ENV GOTOOLCHAIN auto
# gcc is required to support cgo;
# git and mercurial are needed most times for go get`, etc.
# See https://github.com/docker-library/golang/issues/80
RUN apk --no-cache add gcc musl-dev git mercurial
# Set all directories as safe
RUN git config --global --add safe.directory '*'
COPY $TARGETPLATFORM/golangci-lint /usr/bin/
CMD ["golangci-lint"]
================================================
FILE: build/buildx.Dockerfile
================================================
# syntax=docker/dockerfile:1.4
FROM golang:1.26
ARG TARGETPLATFORM
# related to https://github.com/golangci/golangci-lint/issues/3107
ENV GOROOT /usr/local/go
# Allow to download a more recent version of Go.
# https://go.dev/doc/toolchain
# GOTOOLCHAIN=auto is shorthand for GOTOOLCHAIN=local+auto
ENV GOTOOLCHAIN auto
# Set all directories as safe
RUN git config --global --add safe.directory '*'
COPY $TARGETPLATFORM/golangci-lint /usr/bin/
CMD ["golangci-lint"]
================================================
FILE: cmd/golangci-lint/main.go
================================================
package main
import (
"cmp"
"fmt"
"os"
"regexp"
"runtime/debug"
"strings"
"github.com/golangci/golangci-lint/v2/pkg/commands"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
)
var (
goVersion = "unknown"
// Populated by goreleaser during build
version = "unknown"
commit = "?"
date = ""
)
func main() {
info := createBuildInfo()
if err := commands.Execute(info); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "The command is terminated due to an error: %v\n", err)
os.Exit(exitcodes.Failure)
}
}
func createBuildInfo() commands.BuildInfo {
info := commands.BuildInfo{
Commit: commit,
Version: version,
GoVersion: goVersion,
Date: date,
}
buildInfo, available := debug.ReadBuildInfo()
if !available {
return info
}
info.GoVersion = buildInfo.GoVersion
if date != "" {
return info
}
info.Version = buildInfo.Main.Version
matched, _ := regexp.MatchString(`v\d+\.\d+\.\d+`, buildInfo.Main.Version)
if matched {
info.Version = strings.TrimPrefix(buildInfo.Main.Version, "v")
}
var revision string
var modified string
for _, setting := range buildInfo.Settings {
// The `vcs.xxx` information is only available with `go build`.
// This information is not available with `go install` or `go run`.
switch setting.Key {
case "vcs.time":
info.Date = setting.Value
case "vcs.revision":
revision = setting.Value
case "vcs.modified":
modified = setting.Value
}
}
info.Date = cmp.Or(info.Date, "(unknown)")
info.Commit = fmt.Sprintf("(%s, modified: %s, mod sum: %q)",
cmp.Or(revision, "unknown"), cmp.Or(modified, "?"), buildInfo.Main.Sum)
return info
}
================================================
FILE: cmd/golangci-lint/plugins.go
================================================
package main
// This file is used to declare module plugins.
================================================
FILE: docs/.gitignore
================================================
### Hugo files
.hugo_build.lock
public/
resources/
# Copy of install.sh
/static/install.sh
### Generated files
# Generated by /scripts/copy_jsonschema
/static/jsonschema/
# Generated by /scripts/expand_templates
data/version.json
data/formatter_settings.json
data/linter_settings.json
.tmp/
================================================
FILE: docs/Makefile
================================================
.PHONY: default clean serve build
default: clean serve
clean:
rm -rf public/
serve: clean
hugo server --disableFastRender --buildDrafts --enableGitInfo
# IMPORTANT used by the CI to deploy documentation
build: clean
HUGO_ENVIRONMENT=production \
HUGO_ENV=production \
hugo \
--gc --minify \
--baseURL "https://golangci-lint.run/"
================================================
FILE: docs/archetypes/default.md
================================================
---
date: '{{ .Date }}'
draft: true
title: '{{ replace .File.ContentBaseName "-" " " | title }}'
---
================================================
FILE: docs/assets/css/custom.css
================================================
:root {
--primary-hue: 187deg;
--primary-saturation: 54.4%;
--primary-lightness: 57.8%;
}
/* Allow card subtitle with more than 3 lines */
.hx\:line-clamp-3.hextra-card-subtitle {
-webkit-line-clamp: 30;
}
.author-cards {
grid-template-columns: repeat(auto-fill, minmax(max(150px, calc((100% - 1rem * 4) / var(--hextra-cards-grid-cols))), 1fr));
}
.support-cards {
grid-template-columns: repeat(auto-fill, minmax(max(200px, calc((100% - 1rem * 4) / var(--hextra-cards-grid-cols))), 1fr));
}
.support-cards .hextra-card-image {
margin: 2rem;
}
.gl-hidden {
display: none;
}
.hextra-nav-container a[title="Support us"] {
transition: ease-in-out 0.2s;
}
.hextra-nav-container a[title="Support us"]:hover {
transform: scale(1.3, 1.3);
}
.hextra-footer .social-media {
transition: ease-in-out 0.2s;
}
.hextra-footer .social-media :hover{
transform: translateY(-2px);
}
.hextra-banner {
background: #833AB4;
background: linear-gradient(90deg,rgba(131, 58, 180, 1) 0%, rgba(253, 29, 29, 1) 50%, rgba(252, 176, 69, 1) 100%);
/*color: var(--hx-color-slate-900);*/
}
.extra-banner-close-button {
color: var(--hx-color-slate-50);
}
================================================
FILE: docs/content/_index.md
================================================
---
title: 'Golangci-lint'
layout: hextra-home
params:
width: wide
---
{{< hextra/hero-container image="images/golangci-lint-logo-anim.gif" imageWidth="300" imageHeight="300" imageTitle="golangci-lint" >}}
{{< hextra/hero-headline >}}
Golangci-lint is a fast linters runner for Go
{{< /hextra/hero-headline >}}
{{< hextra/hero-subtitle >}}
It runs linters in parallel, uses caching, supports YAML configuration, integrates with all major IDEs, and includes over a hundred linters.
{{< /hextra/hero-subtitle >}}
{{< hextra/hero-button text="Get Started" link="docs" >}}
{{< /hextra/hero-container >}}
{{< hextra/feature-grid cols=3 >}}
{{< hextra/feature-card
icon="fast-forward"
title="Fast"
subtitle="Runs linters in parallel, reuses Go build cache and caches analysis results."
style="background: radial-gradient(ellipse at 50% 80%,rgba(194,97,254,0.15),hsla(0,0%,100%,0));"
link="/docs/" >}}
{{< hextra/feature-card
icon="desktop-computer"
title="Integrations"
subtitle="Integrations with VS Code, Sublime Text, GoLand, GNU Emacs, Vim, GitHub Actions."
style="background: radial-gradient(ellipse at 50% 80%,rgba(142,53,74,0.15),hsla(0,0%,100%,0));"
link="/docs/welcome/integrations" >}}
{{< hextra/feature-card
icon="sparkles"
title="Nice outputs"
subtitle="Text with colors and source code lines, JSON, tab, HTML, Checkstyle, Code-Climate, JUnit-XML, TeamCity, SARIF."
style="background: radial-gradient(ellipse at 50% 80%,rgba(221,210,59,0.15),hsla(0,0%,100%,0));"
link="/docs/configuration/file/#output-configuration" >}}
{{< hextra/feature-card
icon="eye-off"
title="Minimum number of false positives"
subtitle="Tuned default settings."
link="/docs/linters/false-positives" >}}
{{< hextra/feature-card
icon="collection"
title="A lot of linters"
subtitle="No need to install them."
link="/docs/linters" >}}
{{< hextra/feature-card
icon="document-text"
title="YAML-based configuration"
subtitle="Easy to read and maintain."
link="/docs/configuration/file" >}}
{{< /hextra/feature-grid >}}
================================================
FILE: docs/content/docs/_index.md
================================================
---
title: 'Golangci-lint Documentation'
---
{{< hextra/hero-subtitle >}}
Everything you need to know for your golangci-lint journey.
{{< /hextra/hero-subtitle >}}

{{< cards >}}
{{< card
link="/docs/welcome/quick-start"
title="Getting Started"
subtitle="Get ready to use golangci-lint"
icon="arrow-circle-right" >}}
{{< card
link="/docs/linters"
title="Linters"
subtitle="List of all the linters"
icon="arrow-circle-right" >}}
{{< card
link="/docs/formatters"
title="Formatters"
subtitle="List of all the formatters"
icon="arrow-circle-right" >}}
{{< /cards >}}
## Support Us
Golangci-lint is a free and open-source project built by volunteers.
If you value it, consider supporting us, we appreciate it!
{{< golangci/button text="Donate ❤️" link="/docs/donate" >}}
## Contributors
This project exists thanks to all the people who contribute. [How to contribute](/docs/contributing/workflow/).
[](https://github.com/golangci/golangci-lint/graphs/contributors)
## Stargazers over time
{{< golangci/starcharts repo="golangci/golangci-lint" >}}
================================================
FILE: docs/content/docs/configuration/_index.md
================================================
---
title: Configuration
weight: 2
aliases:
- /usage/configuration/
---
The config file has lower priority than command-line options.
If the same bool/string/int option is provided on the command-line
and in the config file, the option from command-line will be used.
Slice options (e.g. list of enabled/disabled linters) are combined from the command-line and config file.
## More
{{< cards cols=2 >}}
{{< card link="/docs/configuration/cli" title="Command Line" icon="terminal" >}}
{{< card link="/docs/configuration/file" title="Configuration File" icon="adjustments" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/configuration/cli.md
================================================
---
title: Command-Line
weight: 1
---
{{% golangci/cli-output %}}
## `run`
{{< cards >}}
{{< card link="/docs/linters" title="Linters Overview" icon="collection" >}}
{{< card link="/docs/configuration/file/#linters-configuration" title="Global Configuration" icon="adjustments" >}}
{{< card link="/docs/linters/configuration/" title="Linter Settings" icon="adjustments" >}}
{{< /cards >}}
> [!NOTE]
> This command executes enabled linters, and the formatters defined in [`formatters`](/docs/configuration/file/#formatters-configuration),
> but it does not format the code.
>
> To only format code, use [`golangci-lint fmt`](/docs/configuration/cli/#fmt).
> To apply both linter fixes and formatting, use `golangci-lint run --fix`.
>
> The formatters cannot be enabled or disabled inside the [`linters`](/docs/configuration/file/#linters-configuration) section or the flags `-E/--enable`, `-D/--disable` of the command [`golangci-lint run`](/docs/configuration/cli/#run).
>
> The formatters can be enabled/disabled by defining them inside the [`formatters`](/docs/configuration/file/#formatters-configuration) section or by using the flags `-E/--enable`, `-D/--disable` of command [`golangci-lint fmt`](/docs/configuration/cli/#fmt).
{{% golangci/cli-output cmd="run" %}}
When the `--cpu-profile-path` or `--mem-profile-path` arguments are specified,
golangci-lint writes runtime profiling data in the format expected by the [pprof](https://github.com/google/pprof) visualization tool.
When the `--trace-path` argument is specified, `golangci-lint` writes runtime tracing data in the format expected by
the `go tool trace` command and visualization tool.
## fmt
{{< cards >}}
{{< card link="/docs/formatters" title="Formatters Overview" icon="collection" >}}
{{< card link="/docs/configuration/file/#formatters-configuration" title="Global Configuration" icon="adjustments" >}}
{{< card link="/docs/formatters/configuration/" title="Formatter Settings" icon="adjustments" >}}
{{< /cards >}}
{{% golangci/cli-output cmd="fmt" %}}
## `migrate`
{{% golangci/cli-output cmd="migrate" %}}
## `formatters`
{{% golangci/cli-output cmd="formatters" %}}
## `help`
{{% golangci/cli-output cmd="help" %}}
## `linters`
{{% golangci/cli-output cmd="linters" %}}
## `cache`
Golangci-lint stores its cache in the subdirectory `golangci-lint` inside the [default user cache directory](https://pkg.go.dev/os#UserCacheDir).
You can override the default cache directory with the environment variable `GOLANGCI_LINT_CACHE`; the path must be absolute.
The cache is only used by `golangci-lint run` (linters).
{{% golangci/cli-output cmd="cache" %}}
## `config`
{{% golangci/cli-output cmd="config" %}}
## `custom`
{{% golangci/cli-output cmd="custom" %}}
## `version`
{{% golangci/cli-output cmd="version" %}}
## `completion`
{{% golangci/cli-output cmd="completion" %}}
================================================
FILE: docs/content/docs/configuration/file.md
================================================
---
title: Configuration File
weight: 2
---
Golangci-lint looks for config files in the following paths from the current working directory:
- `.golangci.yml`
- `.golangci.yaml`
- `.golangci.toml`
- `.golangci.json`
Golangci-lint also searches for config files in all directories from the directory of the first analyzed path up to the root.
If no configuration file has been found, golangci-lint will try to find one in your home directory.
To see which config file is being used and where it was sourced from run golangci-lint with `-v` option.
Config options inside the file are identical to command-line options.
You can configure specific linters' options only within the config file (not the command-line).
There is a [`.golangci.reference.yml`](https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.reference.yml) file with all supported options, their descriptions, and default values.
This file is neither a working example nor a recommended configuration,
it's just a reference to display all the configuration options used to generate the documentation.
The configuration file can be validated with the JSON Schema: [golangci.jsonschema.json](https://golangci-lint.run/jsonschema/golangci.jsonschema.json)
{{% golangci/configuration-file-snippet section="root" %}}
## `version` configuration
{{% golangci/configuration-file-snippet section="version" %}}
## `linters` configuration
{{< cards cols=2 >}}
{{< card link="/docs/linters" title="Linters Overview" icon="collection" >}}
{{< card link="/docs/linters/configuration" title="Linters Settings" icon="adjustments" >}}
{{< /cards >}}
{{% golangci/configuration-file-snippet section="linters" %}}
## `formatters` configuration
{{< cards cols=2 >}}
{{< card link="/docs/formatters" title="Formatters Overview" icon="collection" >}}
{{< card link="/docs/formatters/configuration" title="Formatters Settings" icon="adjustments" >}}
{{< /cards >}}
{{% golangci/configuration-file-snippet section="formatters" %}}
## `issues` configuration
{{% golangci/configuration-file-snippet section="issues" %}}
## `output` configuration
{{% golangci/configuration-file-snippet section="output" %}}
## `run` configuration
{{% golangci/configuration-file-snippet section="run" %}}
## `severity` configuration
{{% golangci/configuration-file-snippet section="severity" %}}
================================================
FILE: docs/content/docs/contributing/_index.md
================================================
---
title: Contributing
weight: 6
aliases:
- /contributing/quick-start/
---
{{< cards >}}
{{< card link="/docs/contributing/workflow/" title="Contributing workflow" icon="document-text" >}}
{{< card link="/docs/contributing/architecture/" title="Architecture of golangci-lint" icon="code" >}}
{{< card link="/docs/contributing/new-linters/" title="How to add new linters" icon="document-text" >}}
{{< card link="/docs/contributing/debug/" title="Debugging golangci-lint" icon="code" >}}
{{< card link="/docs/contributing/faq/" title="FAQ" icon="question-mark-circle" >}}
{{< card link="/docs/contributing/website/" title="Contributing to this website" icon="globe" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/contributing/architecture.md
================================================
---
title: Architecture
weight: 3
aliases:
- /contributing/architecture/
---
There are the following golangci-lint execution steps:
```mermaid
graph LR
init[Init]
loadPackages[Load packages]
runLinters[Run linters]
postprocess[Postprocess issues]
print[Print issues]
init --> loadPackages --> runLinters --> postprocess --> print
```
## Init
The configuration is loaded from file and flags by `config.Loader` inside `PersistentPreRun` (or `PreRun`) of the commands that require configuration.
The linter database (`linterdb.Manager`) is fill based on the configuration:
- The linters ("internals" and plugins) are built by `linterdb.LinterBuilder` and `linterdb.PluginBuilder` builders.
- The configuration is validated by `linterdb.Validator`.
## Load Packages
Loading packages is listing all packages and their recursive dependencies for analysis.
Also, depending on the enabled linters set some parsing of the source code can be performed at this step.
Packages loading starts here:
```go {base_url="https://github.com/golangci/golangci-lint/blob/HEAD/", filename="pkg/lint/package.go"}
func (l *PackageLoader) Load(ctx context.Context, linters []*linter.Config) (pkgs, deduplicatedPkgs []*packages.Package, err error) {
loadMode := findLoadMode(linters)
pkgs, err = l.loadPackages(ctx, loadMode)
if err != nil {
return nil, nil, fmt.Errorf("failed to load packages: %w", err)
}
// ...
```
First, we find a load mode as union of load modes for all enabled linters.
We use [go/packages](https://pkg.go.dev/golang.org/x/tools/go/packages) for packages loading and use its enum `packages.Need*` for load modes.
Load mode sets which data a linter needs for execution.
A linter that works only with AST need minimum of information: only filenames and AST.
There is no need for packages dependencies or type information.
AST is built during `go/analysis` execution to reduce memory usage.
Such AST-based linters are configured with the following code:
```go {base_url="https://github.com/golangci/golangci-lint/blob/main/", filename="pkg/lint/linter/config.go"}
func (lc *Config) WithLoadFiles() *Config {
lc.LoadMode |= packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles
return lc
}
```
If a linter uses `go/analysis` and needs type information, we need to extract more data by `go/packages`:
```go {base_url="https://github.com/golangci/golangci-lint/blob/main/", filename="pkg/lint/linter/config.go"}
func (lc *Config) WithLoadForGoAnalysis() *Config {
lc = lc.WithLoadFiles()
lc.LoadMode |= packages.NeedImports | packages.NeedDeps | packages.NeedExportFile | packages.NeedTypesSizes
lc.IsSlow = true
return lc
}
```
After finding a load mode, we run `go/packages`:
the library get list of dirs (or `./...` as the default value) as input and outputs list of packages and requested information about them:
filenames, type information, AST, etc.
## Run Linters
First, we need to find all enabled linters. All linters are registered here:
```go {base_url="https://github.com/golangci/golangci-lint/blob/main/", filename="pkg/lint/lintersdb/builder_linter.go"}
func (b LinterBuilder) Build(cfg *config.Config) []*linter.Config {
// ...
return []*linter.Config{
// ...
linter.NewConfig(golinters.NewBodyclose()).
WithSince("v1.18.0").
WithLoadForGoAnalysis().
WithURL("https://github.com/timakin/bodyclose"),
// ...
linter.NewConfig(golinters.NewGovet(govetCfg)).
WithGroups(config.GroupStandard).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithURL("https://pkg.go.dev/cmd/vet"),
// ...
}
}
```
We filter requested in config and command-line linters in `EnabledSet`:
```go {base_url="https://github.com/golangci/golangci-lint/blob/main/", filename="pkg/lint/lintersdb/manager.go"}
func (m *Manager) GetEnabledLintersMap() (map[string]*linter.Config, error)
```
We merge enabled linters into one `MetaLinter` to improve execution time if we can:
```go {base_url="https://github.com/golangci/golangci-lint/blob/main/", filename="pkg/lint/lintersdb/manager.go"}
// GetOptimizedLinters returns enabled linters after optimization (merging) of multiple linters into a fewer number of linters.
// E.g. some go/analysis linters can be optimized into one metalinter for data reuse and speed up.
func (m *Manager) GetOptimizedLinters() ([]*linter.Config, error) {
// ...
m.combineGoAnalysisLinters(resultLintersSet)
// ...
}
```
The `MetaLinter` just stores all merged linters inside to run them at once:
```go {base_url="https://github.com/golangci/golangci-lint/blob/main/", filename="pkg/goanalysis/metalinter.go"}
type MetaLinter struct {
linters []*Linter
analyzerToLinterName map[*analysis.Analyzer]string
}
```
Currently, all linters except `unused` can be merged into this meta linter.
The `unused` isn't merged because it has high memory usage.
Linters execution starts in `runAnalyzers`.
It's the most complex part of the golangci-lint.
We use custom [go/analysis](https://pkg.go.dev/golang.org/x/tools/go/analysis) runner there.
It runs as much as it can in parallel.
It lazy-loads as much as it can to reduce memory usage.
Also, it sets all heavyweight data to `nil` as becomes unneeded to save memory.
We don't use existing [multichecker](https://pkg.go.dev/golang.org/x/tools/go/analysis/multichecker) because
it doesn't use caching and doesn't have some important performance optimizations.
All found by linters issues are represented with `result.Issue` struct:
```go {base_url="https://github.com/golangci/golangci-lint/blob/main/", filename="pkg/result/issue.go"}
type Issue struct {
FromLinter string
Text string
Severity string
// Source lines of a code with the issue to show
SourceLines []string
// Pkg is needed for proper caching of linting results
Pkg *packages.Package `json:"-"`
Pos token.Position
LineRange *Range `json:",omitempty"`
// HunkPos is used only when golangci-lint is run over a diff
HunkPos int `json:",omitempty"`
// If we know how to fix the issue we can provide replacement lines
SuggestedFixes []analysis.SuggestedFix `json:",omitempty"`
// If we are expecting a nolint (because this is from nolintlint), record the expected linter
ExpectNoLint bool
ExpectedNoLintLinter string
// ...
}
```
## Postprocess Issues
We have an abstraction of `result.Processor` to postprocess found issues:
{{< filetree/container >}}
{{< filetree/folder name="./pkg/result/processors/" >}}
{{< filetree/file name="cgo.go" >}}
{{< filetree/file name="diff.go" >}}
{{< filetree/file name="exclusion_generated_file_filter.go" >}}
{{< filetree/file name="exclusion_generated_file_matcher.go" >}}
{{< filetree/file name="exclusion_paths.go" >}}
{{< filetree/file name="exclusion_presets.go" >}}
{{< filetree/file name="exclusion_rules.go" >}}
{{< filetree/file name="filename_unadjuster.go" >}}
{{< filetree/file name="fixer.go" >}}
{{< filetree/file name="identifier_marker.go" >}}
{{< filetree/file name="invalid_issue.go" >}}
{{< filetree/file name="issues.go" >}}
{{< filetree/file name="max_from_linter.go" >}}
{{< filetree/file name="max_per_file_from_linter.go" >}}
{{< filetree/file name="max_same_issues.go" >}}
{{< filetree/file name="nolint_filter.go" >}}
{{< filetree/file name="path_absoluter.go" >}}
{{< filetree/file name="path_prettifier.go" >}}
{{< filetree/file name="path_relativity.go" >}}
{{< filetree/file name="path_shortener.go" >}}
{{< filetree/file name="processor.go" >}}
{{< filetree/file name="severity.go" >}}
{{< filetree/file name="sort_results.go" >}}
{{< filetree/file name="source_code.go" >}}
{{< filetree/file name="uniq_by_line.go" >}}
{{< /filetree/folder >}}
{{< /filetree/container >}}
The abstraction is simple:
```go {base_url="https://github.com/golangci/golangci-lint/blob/main/", filename="pkg/result/processors/processor.go"}
type Processor interface {
Process(issues []*result.Issue) ([]*result.Issue, error)
Name() string
Finish()
}
```
A processor can hide issues (`nolint`, `exclude`) or change issues (`path_prettifier`).
## Print Issues
We have an abstraction for printing found issues.
{{< filetree/container >}}
{{< filetree/folder name="./pkg/printers/" >}}
{{< filetree/file name="checkstyle.go" >}}
{{< filetree/file name="codeclimate.go" >}}
{{< filetree/file name="html.go" >}}
{{< filetree/file name="json.go" >}}
{{< filetree/file name="junitxml.go" >}}
{{< filetree/file name="printer.go" >}}
{{< filetree/file name="sarif.go" >}}
{{< filetree/file name="tab.go" >}}
{{< filetree/file name="teamcity.go" >}}
{{< filetree/file name="text.go" >}}
{{< /filetree/folder >}}
{{< /filetree/container >}}
================================================
FILE: docs/content/docs/contributing/debug.md
================================================
---
title: Debugging
weight: 5
aliases:
- /contributing/debug/
---
You can see a verbose output of linter by using `-v` option.
```bash
golangci-lint run -v
```
If you would like to see more detailed logs you can use the environment variable `GL_DEBUG`.
Its value is a list of debug tags.
The existing debug tags are documented in the following file: [/pkg/logutils/logutils.go](https://github.com/golangci/golangci-lint/blob/HEAD/pkg/logutils/logutils.go)
For example:
```bash
GL_DEBUG="loader,gocritic" golangci-lint run
```
```bash
GL_DEBUG="loader,env" golangci-lint run
```
================================================
FILE: docs/content/docs/contributing/faq.md
================================================
---
title: FAQ
weight: 6
aliases:
- /contributing/faq/
---
## How to add a new open-source linter to `golangci-lint`
See [there](/docs/contributing/new-linters#how-to-add-a-public-linter-to-golangci-lint).
## How to add a new private linter to `golangci-lint`
See [there](/docs/contributing/new-linters#how-to-add-a-private-linter-to-golangci-lint).
## How to update an existing linter
We use [Dependabot](https://github.com/golangci/golangci-lint/blob/HEAD/.github/dependabot.yml) to update dependencies, including linters.
The updates happen automatically at least once a week (Sunday 11am UTC).
No pull requests to update a linter will be accepted unless you are the author of the linter and specific changes are required.
## How to add a configuration option to an existing linter
Add a new field to the [linter settings struct](https://github.com/golangci/golangci-lint/blob/HEAD/pkg/config/linters_settings.go).
Document it in [.golangci.next.reference.yml](https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.next.reference.yml).
Pass it to the linter.
## How to see `INFO` or `DEBUG` logs
See [tutorial about debugging](/docs/contributing/debug/).
================================================
FILE: docs/content/docs/contributing/new-linters.md
================================================
---
title: New linters
weight: 4
aliases:
- /contributing/new-linters/
---
## How to write a linter
Use `go/analysis` and take a look at [this tutorial](https://web.archive.org/web/20250527152107/https://disaev.me/p/writing-useful-go-analysis-linter/):
it shows how to write `go/analysis` linter from scratch and integrate it into `golangci-lint`.
## How to add a public linter to `golangci-lint`
You need to implement a new linter using `go/analysis` API.
We don't accept non `go/analysis` linters.
After that:
1. Implement functional tests for the linter:
- Add one file into directory `pkg/golinters/{yourlintername}/testdata/`.
2. Add a new file `pkg/golinters/{yourlintername}/{yourlintername}.go`.
Other linters implementation can help you.
3. Add the new struct for the linter (which you've implemented in `pkg/golinters/{yourlintername}/{yourlintername}.go`) to the
list of all supported linters in [`pkg/lint/lintersdb/builder_linter.go`](https://github.com/golangci/golangci-lint/blob/HEAD/pkg/lint/lintersdb/builder_linter.go)
to the method `LinterBuilder.Build`.
- Add `WithSince("next_version")`, where `next_version` must be replaced by the next minor version. (ex: v1.2.0 if the current version is v1.1.0)
4. Find out what options do you need to configure for the linter.
For example, `nakedret` has only 1 option: [`max-func-lines`](https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.reference.yml).
Choose default values to not be annoying for users of golangci-lint. Add configuration options to:
- [.golangci.next.reference.yml](https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.next.reference.yml): the example of a configuration file.
You can also add them to [.golangci.yml](https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.yml)
if you think that this project needs not default values.
- [config struct](https://github.com/golangci/golangci-lint/blob/HEAD/pkg/config/config.go):
don't forget about `mapstructure` tags for proper configuration files parsing.
5. Take a look at the example of [pull requests with new linter support](https://github.com/golangci/golangci-lint/pulls?q=is%3Apr+is%3Amerged+label%3A%22linter%3A+new%22).
6. Run the tests:
```bash
go run ./cmd/golangci-lint/ run --no-config --default=none --enable={yourlintername} ./pkg/golinters/{yourlintername}/testdata/{yourlintername}.go
```
## How to add a private linter to `golangci-lint`
Some people and organizations may choose to have custom-made linters run as a part of `golangci-lint`.
Typically, these linters can't be open-sourced or too specific.
Such linters can be added through 2 plugin systems:
{{< cards cols=2 >}}
{{< card link="/docs/plugins/module-plugins" title="Module Plugin System" icon="puzzle" tag="Recommended" >}}
{{< card link="/docs/plugins/go-plugins" title="Go Plugin System" icon="puzzle" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/contributing/website.md
================================================
---
title: This Website
weight: 7
aliases:
- /contributing/website/
---
## Technology
We use [Hugo](https://gohugo.io/) for static site generation because sites built with it are very fast.
## Source Code
The website lives in `docs/` directory of [golangci-lint repository](https://github.com/golangci/golangci-lint).
## Theme
The site is based on [hextra](https://github.com/imfing/hextra) theme.
## Templating
We use [shortcodes](https://gohugo.io/templates/types/#shortcode) and [partials](https://gohugo.io/templates/types/#partial) based on files from `./docs/.tmp/` and `./docs/data/`.
- The files in `./docs/.tmp/` are used to be embedded with the shortcode `{{%/* golangci/embed file="filename.ext" */%}}`.
- The files in `./docs/data/` are used as [data sources](https://gohugo.io/content-management/data-sources/).
These files are created by running:
- `make website_expand_templates` in the root of the repository.
- `make website_dump_info` in the root of the repository. (only during a release)
### Some Notes
[shortcodes](https://gohugo.io/templates/types/#shortcode):
- cannot be used inside another shortcode
- can only be used inside a page
- can contain Markdown or HTML, but the tag is different: `{{%/* shortcode */%}}` vs `{{* shortcode */>}}`
[partials](https://gohugo.io/templates/types/#partial):
- are reusable HTML blocks or "functions"
- cannot be used inside a page
- can be used inside another partial
- can be used inside a shortcode
- can be used inside a layout
## Hosting
We use GitHub Pages for static website hosting and CD.
GitHub deploys the website to production after merging anything to a `main` branch.
## Local Testing
Install Hugo Extended (v0.148.1 or newer).
Run:
```bash
# (in the root of the repository)
make docs_serve
```
or
```bash
# (in the root of the repository)
make website_expand_templates
cd docs/
# (inside the docs/ folder)
make serve
```
And navigate to `http://localhost:1313` after a successful build.
There is no need to restart the Hugo server for almost all changes: it supports hot reload.
Also, there is no need to refresh a webpage: hot reload updates changed content on the open page.
## Website Build
To do this, run:
```bash
# (in the root of the repository)
make docs_build
```
or
```bash
# (in the root of the repository)
make website_copy_jsonschema website_expand_templates
cd docs/
# (inside the docs/ folder)
make build
```
================================================
FILE: docs/content/docs/contributing/workflow.md
================================================
---
title: Workflow
weight: 2
aliases:
- /contributing/workflow/
---
By participating in this project, you agree to abide our [code of conduct](https://github.com/golangci/golangci-lint?tab=coc-ov-file).
## Set up your machine
Golangci-lint is written in [Go](https://go.dev).
Prerequisites:
- `make`
- [Go](https://go.dev/doc/install)
Fork and clone [golangci-lint](https://github.com/golangci/golangci-lint) repository.
A good way of making sure everything is all right is running the following:
```bash
make build
./golangci-lint run -v
```
## Test your change
When you are satisfied with the changes, we suggest you run:
```bash
make test
```
Which runs all the linters and tests.
## Create or update parameters for docs
Add your new or updated parameters to [.golangci.next.reference.yml](https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.next.reference.yml) so they will be shown in the docs
## Submit a pull request
Push your branch to your golangci-lint fork and open a pull request against the
`main` branch.
## Pull request checks
First, please, accept CLA - [CLA assistant](https://cla-assistant.io/) will make a comment on the pull request about it.
Also, we run a few checks in CI by using GitHub Actions, you can see them [here](https://github.com/golangci/golangci-lint/blob/HEAD/.github/workflows).
## New releases
First, see [our versioning policy](/docs/product/roadmap/#versioning-policy).
To make a new release create a tag `vX.Y.Z`.
Don't forget to add zero patch version for a new minor release, e.g. `v1.99.0`.
A GitHub Action [workflow](https://github.com/golangci/golangci-lint/blob/HEAD/.github/workflows/release.yml) will start building and publishing release after that.
After making a release, you need to update GitHub [Action config](https://github.com/golangci/golangci-lint/blob/HEAD/assets/github-action-config.json) by running:
```bash
make assets/github-action-config.json
```
================================================
FILE: docs/content/docs/donate/_index.md
================================================
---
title: Support Us
weight: 8
aliases:
- /donate/
---
Golangci-lint is a free and open-source project built by volunteers.
If you value it, consider supporting us, we appreciate it! ❤️
You can support us via:
{{< cards class="support-cards" cols=7 >}}
{{< card link="https://github.com/sponsors/golangci" title="GitHub Sponsors" subtitle="Credit card" image="/images/github-sponsors.svg" >}}
{{< card link="https://opencollective.com/golangci-lint" title="Open Collective" subtitle="Credit card, PayPal, etc." image="/images/open-collective.svg" >}}
{{< card link="https://thanks.dev/u/gh/golangci" title="Thanks.dev" subtitle="Credit card" image="/images/thanks-dev.svg" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/formatters/_index.md
================================================
---
title: Formatters
weight: 4
excludeSearch: true
aliases:
- /usage/formatters/
---
To see a list of supported formatters and which formatters are enabled/disabled:
```bash
golangci-lint help formatters
```
To see a list of formatters enabled by your configuration, use:
```bash
golangci-lint formatters
```
{{< cards cols=2 >}}
{{< card link="/docs/welcome/quick-start/#formatting" title="Quick Start" icon="terminal" >}}
{{< card link="/docs/configuration/cli/#fmt" title="CLI" icon="terminal" >}}
{{< card link="/docs/configuration/file/#formatters-configuration" title="Global Configuration" icon="adjustments" >}}
{{< card link="/docs/formatters/configuration/" title="Formatter Settings" icon="adjustments" >}}
{{< /cards >}}
## All formatters
{{< golangci/items/filter >}}
{{< golangci/items/filter-badge class="gl-filter" data="new" icon="fire" content="New" color="yellow" >}}
{{< golangci/items/filter-badge class="gl-filter" data="deprecated" icon="emoji-sad" content="Deprecated" color="blue" >}}
{{< golangci/items/filter-badge class="gl-filter-reset gl-hidden" icon="trash" content="Reset" color="red" border=true >}}
{{< /golangci/items/filter >}}
{{< cards >}}
{{< golangci/items/cards path="formatters" data="formatters_info" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/formatters/configuration.md
================================================
---
title: Settings
weight: 2
---
{{% golangci/items/settings info="formatters_info" settings="formatter_settings" %}}
================================================
FILE: docs/content/docs/linters/_index.md
================================================
---
title: Linters
weight: 3
excludeSearch: true
aliases:
- /usage/linters/
---
To see a list of supported linters and which linters are enabled/disabled:
```bash
golangci-lint help linters
```
To see a list of linters enabled by your configuration, use:
```bash
golangci-lint linters
```
{{< cards cols=2 >}}
{{< card link="/docs/welcome/quick-start/#linting" title="Quick Start" icon="terminal" >}}
{{< card link="/docs/configuration/cli/#run" title="CLI" icon="terminal" >}}
{{< card link="/docs/configuration/file/#linters-configuration" title="Global Configuration" icon="adjustments" >}}
{{< card link="/docs/linters/configuration/" title="Linter Settings" icon="adjustments" >}}
{{< /cards >}}
## All Linters
{{< golangci/items/filter >}}
{{< golangci/items/filter-badge class="gl-filter" data="default" icon="inbox" content="Default" color="indigo" >}}
{{< golangci/items/filter-badge class="gl-filter" data="new" icon="fire" content="New" color="yellow" >}}
{{< golangci/items/filter-badge class="gl-filter" data="autofix" icon="sparkles" content="Autofix" color="blue" >}}
{{< golangci/items/filter-badge class="gl-filter" data="fast" icon="fast-forward" content="Fast" >}}
{{< golangci/items/filter-badge class="gl-filter" data="slow" icon="play" content="Slow" >}}
{{< golangci/items/filter-badge class="gl-filter" data="deprecated" icon="emoji-sad" content="Deprecated" color="blue" >}}
{{< golangci/items/filter-badge class="gl-filter-reset gl-hidden" icon="trash" content="Reset" color="red" border=true >}}
{{< /golangci/items/filter >}}
{{< cards >}}
{{< golangci/items/cards path="linters" data="linters_info" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/linters/configuration.md
================================================
---
title: Settings
weight: 2
---
{{% golangci/items/settings info="linters_info" settings="linter_settings" %}}
================================================
FILE: docs/content/docs/linters/false-positives.md
================================================
---
title: False Positives
weight: 3
aliases:
- /usage/false-positives/
---
False positives are inevitable, but we did our best to reduce their count.
If a false positive occurred, you have several choices.
## Specific Linter Excludes
Most of the linters have a configuration, sometimes false-positives can be related to a bad configuration of a linter.
So it's recommended to check the linter configurations.
Otherwise, some linters have dedicated configuration to exclude or disable rules.
An example with `staticcheck`:
```yaml
linters:
settings:
staticcheck:
checks:
- all
- '-SA1000' # disable the rule SA1000
- '-SA1004' # disable the rule SA1004
```
## Exclude
### Exclude Issue by Text
You can use `linters.exclusions.rules` config option for per-path or per-linter configuration.
In the following example, all the reports from the linters (`linters`) that contain the text (`text`) are excluded:
```yaml
linters:
exclusions:
rules:
- linters:
- mnd
text: "Magic number: 9"
```
In the following example, all the reports from the linters (`linters`) that originated from the source (`source`) are excluded:
```yaml
linters:
exclusions:
rules:
- linters:
- lll
source: "^//go:generate "
```
In the following example, all the reports that contain the text (`text`) in the path (`path`) are excluded:
```yaml
linters:
exclusions:
rules:
- path: path/to/a/file.go
text: "string `example` has (\\d+) occurrences, make it a constant"
```
### Exclude Issues by Path
Exclude issues in path by `linters.exclusions.paths` or `linters.exclusions.rules` config options.
In the following example, all the reports from the linters (`linters`) that concern the path (`path`) are excluded:
```yaml
linters:
exclusions:
rules:
- path: '(.+)_test\.go'
linters:
- funlen
- goconst
```
The opposite, excluding reports **except** for specific paths, is also possible.
In the following example, only test files get checked:
```yaml
linters:
exclusions:
rules:
- path-except: '(.+)_test\.go'
linters:
- funlen
- goconst
```
In the following example, all the reports related to the files (`paths`) are excluded:
```yaml
linters:
exclusions:
paths:
- path/to/a/file.go
```
In the following example, all the reports related to the directories (`paths`) are excluded:
```yaml
linters:
exclusions:
paths:
- path/to/a/dir/
```
## Nolint Directive
To exclude issues from all linters use `//nolint:all`.
For example, if it's used inline (not from the beginning of the line) it excludes issues only for this line.
```go
var bad_name int //nolint:all
```
To exclude issues from specific linters only:
```go
var bad_name int //nolint:wsl,unused
```
To exclude issues for the block of code, use this directive at the beginning of a line:
```go
//nolint:all
func allIssuesInThisFunctionAreExcluded() *string {
// ...
}
//nolint:govet
var (
a int
b int
)
```
Also, you can exclude all issues in a file by:
```go
//nolint:unparam
package pkg
```
You may add a comment explaining or justifying why a `nolint` directive is being used on the same line as the flag itself:
```go
//nolint:gocyclo // This legacy function is complex, but the team too busy to simplify it
func someLegacyFunction() *string {
// ...
}
```
You can see more examples of using `nolint` directives in [our tests](https://github.com/golangci/golangci-lint/tree/HEAD/pkg/result/processors/testdata) for it.
### Syntax
`nolint` is not regular comment but a directive.
> A directive comment is a line matching the regular expression `//(line |extern |export |[a-z0-9]+:[a-z0-9])`.
> https://go.dev/doc/comment#syntax
This means that no spaces are allowed between:
- `//` and `nolint`
- `nolint` and `:`
- `:` and the name of the linter.
Invalid syntax:
```go
// nolint
// nolint:xxx
//nolint :xxx
//nolint: xxx
```
Valid syntax:
```go
//nolint:xxx
```
## Exclusion Presets
Some exclusions are considered common.
To help golangci-lint users, those common exclusions are provided through presets.
{{% golangci/exclusion-presets-snippet %}}
{{% golangci/exclusion-preset-tables %}}
================================================
FILE: docs/content/docs/plugins/_index.md
================================================
---
title: Plugins
weight: 7
---
{{< cards >}}
{{< card link="/docs/plugins/module-plugins/" title="Module Plugin System" icon="puzzle" tag="Recommended" tagColor="icon-only:sparkles" >}}
{{< card link="/docs/plugins/go-plugins/" title="Go Plugin System" icon="puzzle" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/plugins/go-plugins.md
================================================
---
title: Go Plugin System
weight: 2
aliases:
- /plugins/go-plugins/
---
{{< callout type="warning" >}}
**We recommend using [Module Plugin System](/docs/plugins/module-plugins) instead of the Go Plugin System.**
{{< /callout >}}
Private linters can be added through [Go's plugin system](https://pkg.go.dev/plugin).
For a private linter (which acts as a plugin) to work properly,
the plugin as well as the golangci-lint binary **needs to be built for the same environment**.
`CGO_ENABLED` is another requirement.
This means that `golangci-lint` needs to be built for whatever machine you intend to run it on
(cloning the golangci-lint repository and running a `CGO_ENABLED=1 make build` should do the trick for your machine).
## Create a Plugin
Your linter must provide one or more `golang.org/x/tools/go/analysis.Analyzer` structs.
Your project should also use `go.mod`.
All versions of libraries that overlap `golangci-lint` (including replaced libraries) MUST be set to the same version as `golangci-lint`.
You can see the versions by running `go version -m golangci-lint`.
You'll also need to create a Go file like `plugin/example.go`.
This file MUST be in the package `main`, and MUST define an exposed function called `New` with the following signature:
```go
func New(conf any) ([]*analysis.Analyzer, error) {
// ...
}
```
See [plugin/example.go](https://github.com/golangci/example-plugin-linter/blob/HEAD/plugin/example.go) for more info.
To build the plugin, from the root project directory, run:
```bash
go build -buildmode=plugin plugin/example.go
```
This will create a plugin `*.so` file that can be copied into your project or another well-known location for usage in `golangci-lint`.
## Configure a Plugin
If you already have a linter plugin available, you can follow these steps to define its usage in a projects `.golangci.yml` file.
An example linter can be found at [here](https://github.com/golangci/example-plugin-linter).
If you're looking for instructions on how to configure your own custom linter, they can be found further down.
1. If the project you want to lint does not have one already, copy the [.golangci.yml](https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.yml) to the root directory.
2. Adjust the YAML to appropriate `linters.settings.custom` entries as so:
```yaml {filename=".golangci.yml"}
version: "2"
linters:
settings:
custom:
example:
path: /example.so
description: The description of the linter
original-url: github.com/golangci/example-linter
settings: # Settings are optional.
one: Foo
two:
- name: Bar
three:
name: Bar
```
That is all the configuration that is required to run a custom linter in your project.
Custom linters are enabled by default, but abide by the same rules as other linters.
If the 'disable all' option is specified either on command line or in `.golangci.yml` files `linters.default: none`, custom linters will be disabled;
they can be re-enabled by adding them to the `linters.enable` list,
or providing the enabled option on the command line, `golangci-lint run -Eexample`.
The configuration inside the `linters.settings` field of linter has some limitations (these are NOT related to the plugin system itself):
we use Viper to handle the configuration, but Viper puts all the keys in lowercase, and `.` cannot be used inside a key.
================================================
FILE: docs/content/docs/plugins/module-plugins.md
================================================
---
title: Module Plugin System
weight: 1
aliases:
- /plugins/module-plugins/
---
> [!TIP]
> An example linter can be found at [here](https://github.com/golangci/example-plugin-module-linter).
## The Automatic Way
- Define your building configuration into `.custom-gcl.yml`.
- Run the command `golangci-lint custom` (or `golangci-lint custom -v` to have logs).
- Define the plugin inside the `linters.settings.custom` section with the type `module`.
- Run the resulting custom binary of golangci-lint (`./custom-gcl` by default).
Requirements:
- Go
- git
### Configuration Example
```yaml {filename=".custom-gcl.yml"}
version: {{< golangci/latest-version >}}
plugins:
# a plugin from a Go proxy
- module: 'github.com/golangci/plugin1'
import: 'github.com/golangci/plugin1/foo'
version: v1.0.0
# a plugin from local source
- module: 'github.com/golangci/plugin2'
path: /my/local/path/plugin2
```
```yaml {filename=".golangci.yml"}
version: "2"
linters:
default: none
enable:
- foo
settings:
custom:
foo:
type: "module"
description: This is an example usage of a plugin linter.
settings:
message: hello
```
## The Manual Way
- Add a blank-import of your module inside `cmd/golangci-lint/plugins.go`.
- Run `go mod tidy` (the module containing the plugin will be imported).
- Run `make build`.
- Define the plugin inside the `linters.settings.custom` section with the type `module`.
- Run your custom version of golangci-lint.
### Configuration Example
```yaml {filename=".golangci.yml"}
version: "2"
linters:
default: none
enable:
- foo
settings:
custom:
foo:
type: "module"
description: This is an example usage of a plugin linter.
settings:
message: hello
```
## Reference
The configuration file can be validated with the JSON Schema: [custom-gcl.jsonschema.json](https://golangci-lint.run/jsonschema/custom-gcl.jsonschema.json)
```yml {filename=".custom-gcl.yml"}
{{% golangci/embed file=".tmp/.custom-gcl.reference.yml" %}}
```
================================================
FILE: docs/content/docs/product/_index.md
================================================
---
title: Product
weight: 5
---
{{< cards cols=2 >}}
{{< card link="/docs/product/thanks/" title="Thanks" icon="heart" >}}
{{< card link="/docs/product/migration-guide/" title="Migration Guide" icon="switch-horizontal" >}}
{{< card link="/docs/product/changelog/" title="Changelog" icon="document-text" >}}
{{< card link="/docs/product/roadmap/" title="Roadmap" icon="document-text" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/product/changelog-v1.md
================================================
---
title: Changelog v1
excludeSearch: true
sidebar:
exclude: true
---
Follow the news and releases on [Mastodon](https://fosstodon.org/@golangcilint) and on [Bluesky](https://bsky.app/profile/golangci-lint.run).
`golangci-lint` is a free and open-source project built by volunteers.
If you value it, consider supporting us, we appreciate it!
{{< golangci/button text="Donate ❤️" link="/docs/donate" >}}
{{% golangci/embed file=".tmp/raw_changelog_v1.tmp" %}}
================================================
FILE: docs/content/docs/product/changelog.md
================================================
---
title: Changelog
weight: 2
excludeSearch: true
aliases:
- /product/changelog/
---
Follow the news and releases on [Mastodon](https://fosstodon.org/@golangcilint) and on [Bluesky](https://bsky.app/profile/golangci-lint.run).
`golangci-lint` is a free and open-source project built by volunteers.
If you value it, consider supporting us, we appreciate it!
{{< golangci/button text="Donate ❤️" link="/docs/donate" >}}
{{% golangci/embed file=".tmp/raw_changelog.tmp" %}}
## v1.x.x
{{< cards cols=2 >}}
{{< card link="/docs/product/changelog-v1" title="Changelog of golangci-lint v1" icon="collection" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/product/migration-guide.md
================================================
---
title: Migration guide
weight: 3
aliases:
- /product/migration-guide/
---
## Command `migrate`
You can use golangci-lint to migrate your configuration with the `migrate` command:
```bash
golangci-lint migrate
```
Be aware that **comments inside a configuration file are not migrated.** You need to add them manually after the migration.
**Deprecated options from v1 or unknown fields are not migrated.**
The migration file format is based on the extension of the [configuration file](/docs/configuration/file).
The format can be overridden by using the `--format` flag:
```bash
golangci-lint migrate --format json
```
Before the migration, the previous configuration file is copied and saved to a file named `.bck.`.
By default, before the migration process, the configuration file is validated against the JSON Schema of configuration v1.
If you want to skip this validation, you can use the `--skip-validation` flag:
```bash
golangci-lint migrate --skip-validation
```
The `migrate` command enforces the following default values:
- `run.timeout`: the existing value is ignored because, in v2, there is no timeout by default.
- `issues.show-stats`: the existing value is ignored because, in v2, stats are enabled by default.
- `run.concurrency`: if the existing value was `0`, it is removed as `0` is the new default.
- `run.relative-path-mode`: if the existing value was `cfg`, it is removed as `cfg` is the new default.
`issues.exclude-generated` has a new default value (v1 `lax`, v2 `strict`), so this field will be added during the migration to maintain the previous behavior.
`issues.exclude-dirs-use-default` has been removed, so it is converted to `linters.exclusions.paths` and, if needed, `formatters.exclusions.paths`.
Other fields explicitly defined in the configuration file are migrated even if the value is the same as the default value.
The `migrate` command automatically migrates `linters.presets` in individual linters to `linters.enable`.
{{% golangci/cli-output cmd="migrate" %}}
## Changes
### `linters`
#### `linters.disable-all`
This property has been replaced with `linters.default: none`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters:
disable-all: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
default: none
```
{{< /tab >}}
{{< /tabs >}}
#### `linters.enable-all`
This property has been replaced with `linters.default: all`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters:
enable-all: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
default: all
```
{{< /tab >}}
{{< /tabs >}}
#### `linters.enable[].`
The linters `gci`, `gofmt`, `gofumpt`, and `goimports` have been moved to the `formatters` section.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters:
enable:
- gci
- gofmt
- gofumpt
- goimports
```
{{< /tab >}}
{{< tab >}}
```yaml
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
```
{{< /tab >}}
{{< /tabs >}}
#### `linters.enable[].{stylecheck,gosimple,staticcheck}`
The linters `stylecheck`, `gosimple`, and `staticcheck` has been merged inside the `staticcheck`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters:
enable:
- gosimple
- staticcheck
- stylecheck
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
enable:
- staticcheck
```
{{< /tab >}}
{{< /tabs >}}
#### `linters.fast`
This property has been removed.
There are 2 new options (they are not strictly equivalent to the previous option):
1. `linters.default: fast`: set all "fast" linters as the default set of linters.
```yaml
linters:
default: fast
```
2. `--fast-only`: filters all enabled linters to keep only "fast" linters.
#### `linters.presets`
This property has been removed.
The `migrate` command automatically migrates `linters.presets` in individual linters to `linters.enable`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
Presets:
| name | linters |
|------|---------|
| bugs | `asasalint`, `asciicheck`, `bidichk`, `bodyclose`, `contextcheck`, `durationcheck`, `errcheck`, `errchkjson`, `errorlint`, `exhaustive`, `gocheckcompilerdirectives`, `gochecksumtype`, `gosec`, `gosmopolitan`, `govet`, `loggercheck`, `makezero`, `musttag`, `nilerr`, `nilnesserr`, `noctx`, `protogetter`, `reassign`, `recvcheck`, `rowserrcheck`, `spancheck`, `sqlclosecheck`, `staticcheck`, `testifylint`, `zerologlint` |
| comment | `dupword`, `godot`, `godox`, `misspell` |
| complexity | `cyclop`, `funlen`, `gocognit`, `gocyclo`, `maintidx`, `nestif` |
| error | `err113`, `errcheck`, `errorlint`, `wrapcheck` |
| format | `gci`, `gofmt`, `gofumpt`, `goimports` |
| import | `depguard`, `gci`, `goimports`, `gomodguard` |
| metalinter | `gocritic`, `govet`, `revive`, `staticcheck` |
| module | `depguard`, `gomoddirectives`, `gomodguard` |
| performance | `bodyclose`, `fatcontext`, `noctx`, `perfsprint`, `prealloc` |
| sql | `rowserrcheck`, `sqlclosecheck` |
| style | `asciicheck`, `canonicalheader`, `containedctx`, `copyloopvar`, `decorder`, `depguard`, `dogsled`, `dupl`, `err113`, `errname`, `exhaustruct`, `exptostd`, `forbidigo`, `forcetypeassert`, `ginkgolinter`, `gochecknoglobals`, `gochecknoinits`, `goconst`, `gocritic`, `godot`, `godox`, `goheader`, `gomoddirectives`, `gomodguard`, `goprintffuncname`, `gosimple`, `grouper`, `iface`, `importas`, `inamedparam`, `interfacebloat`, `intrange`, `ireturn`, `lll`, `loggercheck`, `makezero`, `mirror`, `misspell`, `mnd`, `musttag`, `nakedret`, `nilnil`, `nlreturn`, `nolintlint`, `nonamedreturns`, `nosprintfhostport`, `paralleltest`, `predeclared`, `promlinter`, `revive`, `sloglint`, `stylecheck`, `tagalign`, `tagliatelle`, `testpackage`, `tparallel`, `unconvert`, `usestdlibvars`, `varnamelen`, `wastedassign`, `whitespace`, `wrapcheck`, `wsl` |
| test | `exhaustruct`, `paralleltest`, `testableexamples`, `testifylint`, `testpackage`, `thelper`, `tparallel`, `usetesting` |
| unused | `ineffassign`, `unparam`, `unused` |
{{< /tab >}}
{{< tab >}}
```yaml
# Removed
```
{{< /tab >}}
{{< /tabs >}}
#### `typecheck`
This `typecheck` is not a linter, so it cannot be enabled or disabled:
- [FAQ: Why do you have typecheck errors?](/docs/welcome/faq/#why-do-you-have-typecheck-errors)
- [FAQ: Why is it not possible to skip/ignore typecheck errors?](/docs/welcome/faq/#why-is-it-not-possible-to-skipignore-typecheck-errors)
#### Deprecated Linters
The following deprecated linters have been removed:
- `deadcode`
- `execinquery`
- `exhaustivestruct`
- `exportloopref`
- `golint`
- `ifshort`
- `interfacer`
- `maligned`
- `nosnakecase`
- `scopelint`
- `structcheck`
- `tenv`
- `varcheck`
#### Alternative Linter Names
The alternative linters has been removed.
| Alt Name v1 | Name v2 |
|-------------|---------------|
| `gas` | `gosec` |
| `goerr113` | `err113` |
| `gomnd` | `mnd` |
| `logrlint` | `loggercheck` |
| `megacheck` | `staticcheck` |
| `vet` | `govet` |
| `vetshadow` | `govet` |
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters:
enable:
- gas
- goerr113
- gomnd
- logrlint
- megacheck
- vet
- vetshadow
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
enable:
- gosec
- err113
- mnd
- loggercheck
- staticcheck
- govet
```
{{< /tab >}}
{{< /tabs >}}
### `linters-settings`
The `linters-settings` section has been split into `linters.settings` and `formatters.settings`.
Settings for `gci`, `gofmt`, `gofumpt`, and `goimports` are moved to the `formatters.settings` section.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
govet:
enable-all: true
gofmt:
simplify: false
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
govet:
enable-all: true
formatters:
settings:
gofmt:
simplify: false
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.asasalint.ignore-test`
This option has been removed.
To ignore test files, use `linters.exclusions.rules`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
asasalint:
ignore-test: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
rules:
- path: '(.+)_test\.go'
linters:
- asasalint
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.copyloopvar.ignore-alias`
This option has been deprecated since v1.58.0 and has been replaced with `linters.settings.copyloopvar.check-alias`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
copyloopvar:
ignore-alias: false
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
copyloopvar:
check-alias: true
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.cyclop.skip-tests`
This option has been removed.
To ignore test files, use `linters.exclusions.rules`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
cyclop:
skip-test: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
rules:
- path: '(.+)_test\.go'
linters:
- cyclop
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.errcheck.exclude`
This option has been deprecated since v1.42.0 and has been removed.
To exclude functions, use `linters.settings.errcheck.exclude-functions` instead.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
errcheck:
exclude: ./errcheck_excludes.txt
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
errcheck:
exclude-functions:
- io.ReadFile
- io.Copy(*bytes.Buffer)
- io.Copy(os.Stdout)
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.errcheck.ignore`
This option has been deprecated since v1.13.0 and has been removed.
To exclude functions, use `linters.settings.errcheck.exclude-functions` instead.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
errcheck:
ignore: 'io:.*'
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
errcheck:
exclude-functions:
- 'io.ReadFile'
- 'io.Copy(*bytes.Buffer)'
- 'io.Copy(os.Stdout)'
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.exhaustive.check-generated`
This option has been removed.
To analyze generated files, use `linters.exclusions.generated`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
exhaustive:
check-generated: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
generated: disable
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.forbidigo.forbid[].p`
This field has been replaced with `linters-settings.forbidigo.forbid[].pattern`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
forbidigo:
forbid:
- p: '^fmt\.Print.*$'
msg: Do not commit print statements.
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
forbidigo:
forbid:
- pattern: '^fmt\.Print.*$'
msg: Do not commit print statements.
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.forbidigo.forbid[]`
The `pattern` has become mandatory for the `forbid` field.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
forbidigo:
forbid:
- '^print(ln)?$'
- '^spew\.(ConfigState\.)?Dump$'
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
forbidigo:
forbid:
- pattern: '^print(ln)?$'
- pattern: '^spew\.(ConfigState\.)?Dump$'
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.gci.local-prefixes`
This option has been deprecated since v1.44.0 and has been removed.
Use `linters.settings.gci.sections` instead.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
gci:
local-prefixes: 'github.com/example/pkg'
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
gci:
sections:
- standard
- default
- prefix(github.com/example/pkg)
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.gci.skip-generated`
This option has been removed.
To analyze generated files, use `linters.exclusions.generated`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters:
settings:
gci:
skip-generated: false
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
generated: disable
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.goconst.ignore-tests`
This option has been removed.
To ignore test files, use `linters.exclusions.rules`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
goconst:
ignore-tests: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
rules:
- path: '(.+)_test\.go'
linters:
- goconst
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.gocritic.settings.ruleguard.rules`
The special variable `${configDir}` has been replaced with `${base-path}`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
gocritic:
settings:
ruleguard:
rules: '${configDir}/ruleguard/rules-*.go'
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
gocritic:
settings:
ruleguard:
rules: '${base-path}/ruleguard/rules-*.go'
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.govet.check-shadowing`
This option has been deprecated since v1.57.0 and has been removed.
Use `linters.settings.govet.enable: shadow` instead.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
govet:
check-shadowing: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
govet:
enable:
- shadow
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.misspell.ignore-words`
This option has been replaced with `linters.settings.misspell.ignore-rules`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
misspell:
ignore-words:
- foo
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
misspell:
ignore-rules:
- foo
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.predeclared.ignore`
This string option has been replaced with the slice option with the same name.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
predeclared:
ignore: "new,int"
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
predeclared:
ignore:
- new
- int
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.predeclared.q`
This option has been replaced with `linters.settings.predeclared.qualified-name`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
predeclared:
q: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
predeclared:
qualified-name: true
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.revive.ignore-generated-header`
This option has been removed.
Use `linters.exclusions.generated` instead.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
revive:
ignore-generated-header: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
generated: strict
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.sloglint.context-only`
This option has been deprecated since v1.58.0 and has been replaced with `linters.settings.sloglint.context`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
sloglint:
context-only: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
sloglint:
context: all
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.staticcheck.go`
This option has been deprecated since v1.47.0 and has been removed.
Use `run.go` instead.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
staticcheck:
go: '1.22'
```
{{< /tab >}}
{{< tab >}}
```yaml
run:
go: '1.22'
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.unused.exported-is-used`
This option has been deprecated since v1.60.0 and has been removed.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
unused:
exported-is-used: true
```
{{< /tab >}}
{{< tab >}}
```yaml
# Removed
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.usestdlibvars.os-dev-null`
This option has been deprecated since v1.51.0 and has been removed.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
usestdlibvars:
os-dev-null: true
```
{{< /tab >}}
{{< tab >}}
```yaml
# Removed
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.usestdlibvars.syslog-priority`
This option has been deprecated since v1.51.0 and has been removed.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
usestdlibvars:
syslog-priority: true
```
{{< /tab >}}
{{< tab >}}
```yaml
# Removed
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.wrapcheck.ignoreInterfaceRegexps`
This option has been renamed to `linters.settings.wrapcheck.ignore-interface-regexps`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
wrapcheck:
ignoreInterfaceRegexps:
- '^(?i)c(?-i)ach(ing|e)'
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
wrapcheck:
ignore-interface-regexps:
- '^(?i)c(?-i)ach(ing|e)'
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.wrapcheck.ignorePackageGlobs`
This option has been renamed to `linters.settings.wrapcheck.ignore-package-globs`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
wrapcheck:
ignorePackageGlobs:
- 'encoding/*'
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
wrapcheck:
ignore-package-globs:
- 'encoding/*'
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.wrapcheck.ignoreSigRegexps`
This option has been renamed to `linters.settings.wrapcheck.ignore-sig-regexps`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
wrapcheck:
ignoreSigRegexps:
- '\.New.*Error\('
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
wrapcheck:
ignore-sig-regexps:
- '\.New.*Error\('
```
{{< /tab >}}
{{< /tabs >}}
#### `linters-settings.wrapcheck.ignoreSigs`
This option has been renamed to `linters.settings.wrapcheck.ignore-sigs`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters-settings:
wrapcheck:
ignoreSigs:
- '.Errorf('
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
settings:
wrapcheck:
ignore-sigs:
- '.Errorf('
```
{{< /tab >}}
{{< /tabs >}}
### `issues`
#### `issues.exclude-case-sensitive`
This property has been removed.
`issues.exclude`, `issues.exclude-rules.text`, and `issues.exclude-rules.source` are case-sensitive by default.
To ignore case, use `(?i)` at the beginning of a regex syntax.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
issues:
exclude-case-sensitive: false
exclude:
- 'abcdef'
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
rules:
- path: '(.+)\.go$'
text: (?i)abcdef
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.exclude-dirs-use-default`
This property has been removed.
Use `linters.exclusions.paths` and `formatters.exclusions.paths` to exclude directories.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
issues:
exclude-dirs-use-default: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
paths:
- third_party$
- builtin$
- examples$
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.exclude-dirs`
This property has been replaced with `linters.exclusions.paths` and `formatters.exclusions.paths`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
issues:
exclude-dirs:
- src/external_libs
- autogenerated_by_my_lib
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
paths:
- src/external_libs
- autogenerated_by_my_lib
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.exclude-files`
This property has been replaced with `linters.exclusions.paths` and `formatters.exclusions.paths`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
issues:
exclude-files:
- '.*\.my\.go$'
- lib/bad.go
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
paths:
- '.*\.my\.go$'
- lib/bad.go
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.exclude-generated-strict`
This property has been deprecated since v1.59.0 and has been replaced with `linters.exclusions.generated: strict`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters:
exclude-generated-strict: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
generated: strict
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.exclude-generated`
This property has been replaced with `linters.exclusions.generated`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
linters:
exclude-generated: lax
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
generated: lax
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.exclude-rules`
This property has been replaced with `linters.exclusions.rules`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
issues:
exclude-rules:
- path: '_test\.go'
linters:
- gocyclo
- errcheck
- dupl
- gosec
- path-except: '_test\.go'
linters:
- staticcheck
- path: internal/hmac/
text: "weak cryptographic primitive"
linters:
- gosec
- linters:
- staticcheck
text: "SA9003:"
- linters:
- err113
source: "foo"
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
rules:
- path: '_test\.go'
linters:
- dupl
- errcheck
- gocyclo
- gosec
- path-except: '_test\.go'
linters:
- staticcheck
- path: internal/hmac/
text: weak cryptographic primitive
linters:
- gosec
- text: 'SA9003:'
linters:
- staticcheck
- source: foo
linters:
- err113
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.exclude-use-default`
This property has been replaced with `linters.exclusions.presets`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
issues:
exclude-use-default: true
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.exclude`
This property has been replaced with `linters.exclusions.rules`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
issues:
exclude:
- abcdef
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
rules:
- path: '(.+)\.go$'
text: abcdef
```
{{< /tab >}}
{{< /tabs >}}
#### `issues.include`
This property has been replaced with `linters.exclusions.presets`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
issues:
include:
- EXC0014
- EXC0015
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
presets:
- common-false-positives
- legacy
- std-error-handling
```
{{< /tab >}}
{{< /tabs >}}
### `output`
#### `output.format`
This property has been deprecated since v1.57.0 and has been replaced with `output.formats`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
output:
format: 'checkstyle:report.xml,json:stdout,colored-line-number'
```
{{< /tab >}}
{{< tab >}}
```yaml
output:
formats:
checkstyle:
path: 'report.xml'
json:
path: stdout
text:
path: stdout
color: true
```
{{< /tab >}}
{{< /tabs >}}
#### `output.formats[].format: `
The property `output.formats[].format` has been replaced with `output.formats[].`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
output:
formats:
- format: json
path: stderr
- format: checkstyle
path: report.xml
```
{{< /tab >}}
{{< tab >}}
```yaml
output:
formats:
json:
path: stderr
checkstyle:
path: report.xml
```
{{< /tab >}}
{{< /tabs >}}
#### `output.formats[].format: line-number`
This format has been replaced by the format `text`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
output:
formats:
- format: line-number
```
{{< /tab >}}
{{< tab >}}
```yaml
output:
formats:
text:
path: stdout
```
{{< /tab >}}
{{< /tabs >}}
#### `output.formats[].format: colored-line-number`
This format has been replaced by the format `text` with the option `colors` (`true` by default).
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
output:
formats:
- format: colored-line-number
```
{{< /tab >}}
{{< tab >}}
```yaml
output:
formats:
text:
path: stdout
colors: true
```
{{< /tab >}}
{{< /tabs >}}
#### `output.formats[].format: colored-tab`
This format has been replaced by the format `tab` with the option `colors` (`true` by default).
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
output:
formats:
- format: colored-tab
```
{{< /tab >}}
{{< tab >}}
```yaml
output:
formats:
tab:
path: stdout
colors: true
```
{{< /tab >}}
{{< /tabs >}}
#### `output.print-issued-lines`
This property has been removed.
To not print the lines with issues, use the `text` format with the option `print-issued-lines: false`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
output:
formats:
- format: line-number
path: stdout
print-issued-lines: false
```
{{< /tab >}}
{{< tab >}}
```yaml
output:
formats:
text:
path: stdout
print-issued-lines: false
```
{{< /tab >}}
{{< /tabs >}}
#### `output.print-linter-name`
This property has been removed.
To not print the linter name, use the `text` format with the option `print-linter-name: false`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
output:
formats:
- format: line-number
path: stdout
print-linter-name: false
```
{{< /tab >}}
{{< tab >}}
```yaml
output:
formats:
text:
path: stdout
print-linter-name: false
```
{{< /tab >}}
{{< /tabs >}}
#### `output.show-stats`
This property is `true` by default.
#### `output.sort-order`
This property has a new default value `['linter', 'file']` instead of `['file']`.
#### `output.sort-results`
The property has been removed.
The output results are always sorted.
#### `output.uniq-by-line`
This property has been deprecated since v1.63.0 and has been replaced by `issues.uniq-by-line`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
output:
uniq-by-line: true
```
{{< /tab >}}
{{< tab >}}
```yaml
issues:
uniq-by-line: true
```
{{< /tab >}}
{{< /tabs >}}
### `run`
#### `run.go`
The new fallback value for this property is `1.22` instead of `1.17`.
#### `run.concurrency`
This property value set to match Linux container CPU quota by default and fallback on the number of logical CPUs in the machine.
#### `run.relative-path-mode`
This property has a new default value of `cfg` instead of `wd`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
run:
# When not specified, relative-path-mode is set to 'wd' by default
```
{{< /tab >}}
{{< tab >}}
```yaml
run:
relative-path-mode: 'cfg'
```
{{< /tab >}}
{{< /tabs >}}
#### `run.show-stats`
This property has been deprecated since v1.57.0 and has been replaced by `output.show-stats`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
run:
show-stats: true
```
{{< /tab >}}
{{< tab >}}
```yaml
output:
show-stats: true
```
{{< /tab >}}
{{< /tabs >}}
#### `run.skip-dirs-use-default`
This property has been deprecated since v1.57.0 and has been replaced by `issues.exclude-dirs-use-default`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
run:
skip-dirs-use-default: false
```
{{< /tab >}}
{{< tab >}}
```yaml
issues:
exclude-dirs-use-default: false
```
{{< /tab >}}
{{< /tabs >}}
#### `run.skip-dirs`
This property has been deprecated since v1.57.0 and has been removed.
Use `linters.exclusions.paths` and `formatters.exclusions.paths` to exclude directories.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
run:
skip-dirs:
- src/external_libs
- autogenerated_by_my_lib
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
paths:
- src/external_libs
- autogenerated_by_my_lib
```
{{< /tab >}}
{{< /tabs >}}
#### `run.skip-files`
This property has been deprecated since v1.57.0 and has been removed.
Use `linters.exclusions.paths` and `formatters.exclusions.paths` to exclude files.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
run:
skip-files:
- '.*\.my\.go$'
- lib/bad.go
```
{{< /tab >}}
{{< tab >}}
```yaml
linters:
exclusions:
paths:
- '.*\.my\.go$'
- lib/bad.go
```
{{< /tab >}}
{{< /tabs >}}
#### `run.timeout`
This property value is disabled by default (`0`).
### `severity`
#### `severity.default-severity`
This property has been replaced with `severity.default`.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
severity:
default-severity: error
```
{{< /tab >}}
{{< tab >}}
```yaml
severity:
default: error
```
{{< /tab >}}
{{< /tabs >}}
#### `severity.rules.case-sensitive`
`severity.rules.text` and `severity.rules.source` are case-sensitive by default.
To ignore case, use `(?i)` at the beginning of a regex syntax.
{{< tabs items="v1,v2" >}}
{{< tab >}}
```yaml
severity:
case-sensitive: true
rules:
- severity: info
linters:
- foo
text: 'Example.*'
```
{{< /tab >}}
{{< tab >}}
```yaml
severity:
rules:
- severity: info
linters:
- foo
text: '(?i)Example.*'
```
{{< /tab >}}
{{< /tabs >}}
### `version`
The `version` property has been added to the configuration file.
```yaml
version: "2"
```
### Integration
#### Visual Studio Code
{{< tabs items="v1,v2" >}}
{{< tab >}}
```JSONata
"go.lintTool": "golangci-lint",
"go.lintFlags": [
"--fast"
]
```
{{< /tab >}}
{{< tab >}}
```JSONata
"go.lintTool": "golangci-lint",
"go.lintFlags": [
"--fast-only"
],
"go.formatTool": "custom",
"go.alternateTools": {
"customFormatter": "golangci-lint"
},
"go.formatFlags": [
"fmt",
"--stdin"
]
```
{{< /tab >}}
{{< /tabs >}}
### Command Line Flags
The following flags have been removed:
- `--disable-all`
- `--enable-all`
- `-p, --presets`
- `--fast`
- `-e, --exclude`
- `--exclude-case-sensitive`
- `--exclude-dirs-use-default`
- `--exclude-dirs`
- `--exclude-files`
- `--exclude-generated`
- `--exclude-use-default`
- `--go string`
- `--sort-order`
- `--sort-results`
- `--out-format`
- `--print-issued-lines`
- `--print-linter-name`
#### `--out-format`
`--out-format` has been replaced with the following flags:
```bash
# Previously 'colored-line-number' and 'line-number'
--output.text.path
--output.text.print-linter-name
--output.text.print-issued-lines
--output.text.colors
```
```bash
# Previously 'json'
--output.json.path
```
```bash
# Previously 'colored-tab' and 'tab'
--output.tab.path
--output.tab.print-linter-name
--output.tab.colors
```
```bash
# Previously 'html'
--output.html.path
```
```bash
# Previously 'checkstyle'
--output.checkstyle.path
```
```bash
# Previously 'code-climate'
--output.code-climate.path
```
```bash
# Previously 'junit-xml' and 'junit-xml-extended'
--output.junit-xml.path
--output.junit-xml.extended
```
```bash
# Previously 'teamcity'
--output.teamcity.path
```
```bash
# Previously 'sarif'
--output.sarif.path
```
#### `--print-issued-lines`
`--print-issued-lines` has been replaced with `--output.text.print-issued-lines`.
#### `--print-linter-name`
`--print-linter-name` has been replaced with `--output.text.print-linter-name` or `--output.tab.print-linter-name`.
#### `--disable-all` and `--enable-all`
`--disable-all` has been replaced with `--default=none`.
`--enable-all` has been replaced with `--default=all`.
#### Examples
Run only the `govet` linter, output results to stdout in JSON format, and sort results:
{{< tabs items="v1,v2" >}}
{{< tab >}}
```bash
golangci-lint run --disable-all --enable=govet --out-format=json --sort-order=linter --sort-results
```
{{< /tab >}}
{{< tab >}}
```bash
golangci-lint run --default=none --enable=govet --output.json.path=stdout
```
{{< /tab >}}
{{< /tabs >}}
Do not print issued lines, output results to stdout without colors in text format, and to `gl-code-quality-report.json` file in Code Climate's format:
{{< tabs items="v1,v2" >}}
{{< tab >}}
```bash
golangci-lint run --print-issued-lines=false --out-format code-climate:gl-code-quality-report.json,line-number
```
{{< /tab >}}
{{< tab >}}
```bash
golangci-lint run --output.text.path=stdout --output.text.colors=false --output.text.print-issued-lines=false --output.code-climate.path=gl-code-quality-report.json
```
{{< /tab >}}
{{< /tabs >}}
================================================
FILE: docs/content/docs/product/roadmap.md
================================================
---
title: Roadmap
weight: 4
aliases:
- /product/roadmap/
---
## 💡 Feature Requests
Please file an issue to suggest new features. Vote on feature requests by adding a 👍. This helps maintainers prioritize what to work on.
[See Feature Requests](https://github.com/golangci/golangci-lint/issues?utf8=✓&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3Aenhancement)
## 🐛 Bugs
Please file an issue for bugs, missing documentation or unexpected behavior.
[See Bugs](https://github.com/golangci/golangci-lint/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3A%22bug%22+sort%3Acreated-desc)
## Versioning Policy
golangci-lint follows [semantic versioning](https://semver.org). However, due to the nature of golangci-lint as a code quality tool,
it's not always clear when a minor or major version bump occurs.
To help clarify this for everyone, we've defined the following semantic versioning policy:
- Patch release (intended to not break your lint build)
- A patch version update in a specific linter that results in golangci-lint reporting fewer errors.
- A bug fix to the CLI or core (packages loading, runner, postprocessors, etc).
- Improvements to documentation.
- Non-user-facing changes such as refactoring code, adding, deleting, or modifying tests, and increasing test coverage.
- Re-releasing after a failed release (i.e., publishing a release that doesn't work for anyone).
- Minor release (might break your lint build because of newly found issues)
- A major or minor version update of a specific linter that results in golangci-lint reporting more errors.
- A new linter is added.
- An existing configuration option or linter is deprecated.
- A new CLI command is created.
- Backward incompatible change of configuration.
- Major release (likely to break your lint build)
- Backward incompatible change of configuration with huge impact.
According to our policy, any minor update may report more errors than the previous release (ex: from a bug fix).
As such, we recommend using the fixed minor version and fixed or the latest patch version to guarantee the results of your builds.
For example, in our [GitHub Action](https://github.com/golangci/golangci-lint-action) we require users to explicitly set the minor version of golangci-lint
and we always use the latest patch version.
## Linter Deprecation Cycle
A linter can be deprecated for various reasons, e.g. the linter stops working with a newer version of Go or the author has abandoned its linter.
The deprecation of a linter will follow 3 phases:
1. **Display of a warning message**: The linter can still be used (unless it's completely non-functional),
but it's recommended to remove it from your configuration.
2. **Display of an error message**: At this point, you should remove the linter.
The original implementation is replaced by a placeholder that does nothing.
The linter is NOT enabled when using `default: all` and should be removed from the `disable` option.
3. **Removal of the linter** from golangci-lint.
Each phase corresponds to a minor version:
- v1.0.0 -> warning message
- v1.1.0 -> error message
- v1.2.0 -> linter removed
We will provide clear information about those changes on different supports: changelog, logs, social network, etc.
We consider the removal of a linter as non-breaking changes for golangci-lint itself.
No major version will be created when a linter is removed.
## Future Plans
1. Upstream all changes of forked linters.
2. Make it easy to write own linter/checker: it should take a minimum code, have perfect documentation, debugging and testing tooling.
3. Speed up SSA loading: on-disk cache and existing code profiling-optimizing.
4. Analyze (don't only filter) only new code: analyze only changed files and dependencies, make incremental analysis, caches.
5. Smart new issues detector: don't print existing issues on changed lines.
6. Minimize false-positives by fixing linters and improving testing tooling.
7. Documentation for every issue type.
================================================
FILE: docs/content/docs/product/thanks.md
================================================
---
title: Thanks
weight: 1
aliases:
- /product/thanks/
---
## ❤️
### Thanks to developers and authors of used linters
{{< cards class="author-cards" cols=7 >}}
{{< golangci/authors >}}
{{< /cards >}}
### Thanks to all contributors
[](https://github.com/golangci/golangci-lint/graphs/contributors)
### Special thanks
Thanks to Ludovic Fernandez ([@ldez](https://github.com/ldez)) for actively maintaining the golangci-lint project.
Thanks to Denis Isaev ([@jirfag](https://github.com/jirfag)) for creating golangci-lint and the GitHub Action [golangci-lint-action](https://github.com/golangci/golangci-lint-action).
Thanks to Alec Thomas ([@alecthomas](https://github.com/alecthomas)) and [alecthomas/gometalinter](https://github.com/alecthomas/gometalinter) for inspiration and amazing work.
Thanks to Bradley Falzon ([@bradleyfalzon](https://github.com/bradleyfalzon)) and [bradleyfalzon/revgrep](https://github.com/bradleyfalzon/revgrep) for cool diff tool.
The golangci-lint logo is inspired by the Go gopher designed by Renee French [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/).
================================================
FILE: docs/content/docs/welcome/_index.md
================================================
---
title: Welcome
weight: 1
---
This quickstart guide provides step-by-step instructions to help you install, configure, and begin using `golangci-lint` efficiently.
{{< cards >}}
{{< card link="/docs/welcome/install/local" title="Local Installation" icon="archive" >}}
{{< card link="/docs/welcome/install/ci" title="CI Installation" icon="archive" >}}
{{< card link="/docs/welcome/integrations/" title="Integrations" icon="sparkles" >}}
{{< card link="/docs/welcome/quick-start/#linting" title="Quick Start: Linting" icon="fast-forward" >}}
{{< card link="/docs/welcome/quick-start/#formatting" title="Quick Start: Formatting" icon="fast-forward" >}}
{{< card link="/docs/welcome/faq/" title="FAQ" icon="question-mark-circle" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/welcome/faq.md
================================================
---
title: FAQ
toc: false
weight: 5
aliases:
- /welcome/faq/
---
## Which Go versions are supported?
The same as the Go team (the 2 latest minor versions).
Basically, golangci-lint supports Go versions lower or equal to the Go version used to compile it.
New versions of Go are not automatically supported because, in addition to the Go version used to build it,
some linters and/or internal pieces of golangci-lint could need to be adapted to support this new Go version.
## How to use golangci-lint in CI
Run golangci-lint in CI and check the exit code. If it's non-zero - fail the build.
See [how to properly install golangci-lint in CI](/docs/welcome/install/ci)
## golangci-lint doesn't work
1. Please ensure you are using the latest binary release.
2. Run it with `-v` option and check the output.
3. If it doesn't help, create a [GitHub issue](https://github.com/golangci/golangci-lint/issues/new/choose) with the output from the error and #2 above.
## Why do you have `typecheck` errors?
`typecheck` is like a front-end for the Go compiler errors.
Compilation errors are identified/labeled as reports of `typecheck` but they are not produced by a linter called `typecheck`.
`typecheck` is not a linter, it doesn't perform any analysis,
it's just a way to identify, parse, and display compiling errors (produced by the `types.Checker`) and some linter errors.
It cannot be disabled because of that.
Of course, this is just as good as the compiler itself, and a lot of compilation issues will not properly show where in the code your error lies.
As a consequence, the code to analyze should compile.
It means that if you try to run an analysis on a single file or a group of files or a package or a group of packages,
with dependencies on other files or packages of your project, as it doesn't compile (because of the missing pieces of code),
it also cannot be analyzed.
If there are `typecheck` errors, golangci-lint will not be able to produce other reports because that kind of error doesn't allow it to perform any analysis.
How to troubleshoot:
1. Ensure the version of golangci-lint is built with a compatible version of Go (`golangci-lint version`).
2. Ensure dependencies are up to date with `go mod tidy`.
3. Ensure building works with `go run ./...`/`go build ./...` - whole package.
4. Ensure you are not running an analysis on code that depends on files/packages outside the scope of the analyzed elements.
5. If using CGO, ensure all required system libraries are installed.
6. If you are using private repositories/dependencies, ensure the [Go proxy](https://go.dev/ref/mod#module-proxy) (`GOPROXY`) and [checksum database](https://go.dev/ref/mod#checksum-database) (`GOSUMDB`) are right and/or your git configuration.
## Why is it not possible to skip/ignore `typecheck` errors?
For mainly the same reasons that you cannot compile when you have a compiler error.
`typecheck` errors are reported in the same style as linter reports/issues,
but are completely different because they are related to problems that block the analysis (`typecheck` is not a linter).
When there are `typecheck` errors,
most linters are not able to perform the analysis,
and they simply do not produce any reports,
so it's not possible to skip/ignore `typecheck` errors.
## Why running with `--fast-only` can be slow on the first run?
Because the first run caches type information.
All subsequent runs will be faster.
Usually this option is used during development on a local machine and compilation was already performed.
## How do you add a custom linter?
You can integrate it yourself, see this [manual](/docs/contributing/new-linters/).
Or you can create a [GitHub Issue](https://github.com/golangci/golangci-lint/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.yml) and we will integrate when time permits.
## How to integrate golangci-lint into a large project with thousands of issues
We are sure that every project can easily integrate golangci-lint, even the large one.
The idea is to not fix all existing issues.
Fix only newly added issue: issues in new code.
To do this, set up the CI to run golangci-lint with options `--new-from-merge-base=main` or `--new-from-rev=HEAD~1`.
Also, take a look at option `--new`,
but consider that CI scripts that generate unstaged files will make `--new` only point out issues in those files and not in the last commit.
In that regard `--new-from-merge-base=main` or `--new-from-rev=HEAD~1` are safer.
By doing this you won't create new issues in your code and can choose to fix existing issues (or not).
## Why `--new-from-xxx` don't seem to be working in some cases?
The options `--new-from-merge-base`, `--new-from-rev`, and `--new-from-patch` work by comparing `git diff` output and issues.
If an issue is not reported as the same line as the changes then the issue will be skipped.
This is because the line of the issue is not inside the lines changed.
To fix that, you have to use the option `--whole-files`.
The side effect is the issues inside the file that contain changes but not directly related to the changes themselves will be reported.
================================================
FILE: docs/content/docs/welcome/install/_index.md
================================================
---
title: "Install"
weight: 1
aliases:
- /welcome/install/
---
Where do you want to install golangci-lint?
{{< cards >}}
{{< card link="/docs/welcome/install/local" title="On my machine" icon="archive" >}}
{{< card link="/docs/welcome/install/ci" title="On CI/CD systems" icon="archive" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/welcome/install/ci.md
================================================
---
title: "CI Installation"
weight: 3
---
It's important to have reproducible CI: don't start to fail all builds at the same time.
With golangci-lint this can happen if you use option `linters.default: all` and a new linter is added
or even without `linters.default: all` when one upstream linter is upgraded.
> [!IMPORTANT]
> It's highly recommended installing a specific version of golangci-lint available on the [releases page](https://github.com/golangci/golangci-lint/releases).
## GitHub Actions
We recommend using [our GitHub Action](https://github.com/golangci/golangci-lint-action) for running golangci-lint in CI for GitHub projects.
It's [fast and uses smart caching](https://github.com/golangci/golangci-lint-action#performance) inside,
and it can be much faster than the simple binary installation.
Also, the action creates GitHub annotations for found issues (you don't need to dig into build log to see found by golangci-lint issues).
{{< cards cols=2 >}}
{{< golangci/image-card src="/images/colored-line-number.png" title="Console Output" >}}
{{< golangci/image-card src="/images/annotations.png" title="Annotations" >}}
{{< /cards >}}
## GitLab CI
GitLab provides a [guide for integrating golangci-lint into the Code Quality widget](https://docs.gitlab.com/ci/testing/code_quality/#golangci-lint).
A simple quickstart is their [CI component](https://gitlab.com/explore/catalog/components/code-quality-oss/codequality-os-scanners-integration), which can be used like this:
```yaml {filename=".gitlab-ci.yml"}
include:
- component: $CI_SERVER_FQDN/components/code-quality-oss/codequality-os-scanners-integration/golangci@1.0.1
```
Note that you [can only reference components in the same GitLab instance as your project](https://docs.gitlab.com/ci/components/#use-a-component)
## Buildkite
Buildkite provides a [plugin](https://buildkite.com/resources/plugins/buildkite-plugins/golangci-lint-buildkite-plugin/) for running golangci-lint in Buildkite pipelines.
It utilizes the [Docker image of golangci-lint](/docs/welcome/install/local/#docker) by default, but can be set to use a binary if available on the agent.
The plugin will annotate builds with results, providing an easily readable summary of fixes.
```yaml {filename=".pipeline.yml"}
plugins:
- golangci-lint#v1.0.0:
config: .golangci.yml
```
## Other CI
Here are the other ways to install golangci-lint:
{{< cards >}}
{{< card link="/docs/welcome/install/local/#binaries" title="Bash/Binaries" icon="archive" >}}
{{< card link="/docs/welcome/install/local/#docker" title="Docker" icon="archive" >}}
{{< /cards >}}
================================================
FILE: docs/content/docs/welcome/install/local.md
================================================
---
title: "Local Installation"
weight: 2
---
## Binaries
```bash
# binary will be $(go env GOPATH)/bin/golangci-lint
curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin {{< golangci/latest-version >}}
# or install it into ./bin/
curl -sSfL https://golangci-lint.run/install.sh | sh -s {{< golangci/latest-version >}}
# In Alpine Linux (as it does not come with curl by default)
wget -O- -nv https://golangci-lint.run/install.sh | sh -s {{< golangci/latest-version >}}
golangci-lint --version
```
On Windows, you can run the above commands with Git Bash, which comes with [Git for Windows](https://git-scm.com/download/win).
## Linux
Golangci-lint is available inside the majority of the package managers.
{{% details closed="true" title="Packaging status" %}}
[](https://repology.org/project/golangci-lint/versions)
{{% /details %}}
## macOS
### Homebrew
Note: Homebrew can use an unexpected version of Go to build the binary,
so we recommend either using our binaries or ensuring the version of Go used to build.
You can install a binary release on macOS using [brew](https://brew.sh/):
```bash
brew install golangci-lint
brew upgrade golangci-lint
```
Note: Previously, we used a [Homebrew tap](https://github.com/golangci/homebrew-tap).
We recommend using the [official formula](https://formulae.brew.sh/formula/golangci-lint) instead of the tap,
but sometimes the most recent release isn't immediately available via Homebrew core due to manual updates that need to occur from Homebrew core maintainers.
In this case, the tap formula, which is updated automatically,
can be used to install the latest version of golangci-lint:
```bash
brew tap golangci/tap
brew install golangci/tap/golangci-lint
```
### MacPorts
It can also be installed through [MacPorts](https://www.macports.org/)
The MacPorts installation mode is community-driven and not officially maintained by the golangci team.
```bash
sudo port install golangci-lint
```
## Windows
### Chocolatey
You can install a binary on Windows using [chocolatey](https://community.chocolatey.org/packages/golangci-lint).
```bash
choco install golangci-lint
```
### Scoop
You can install a binary on Windows using [scoop](https://scoop.sh).
```bash
scoop install main/golangci-lint
```
The scoop package is not officially maintained by golangci team.
## Docker
The Docker image is available on [Docker Hub](https://hub.docker.com/r/golangci/golangci-lint).
```bash
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:{{< golangci/latest-version >}} golangci-lint run
```
Colored output:
```bash
docker run -t --rm -v $(pwd):/app -w /app golangci/golangci-lint:{{< golangci/latest-version >}} golangci-lint run
```
Preserving caches between consecutive runs:
```bash
docker run --rm -t -v $(pwd):/app -w /app \
--user $(id -u):$(id -g) \
-v $(go env GOCACHE):/.cache/go-build -e GOCACHE=/.cache/go-build \
-v $(go env GOMODCACHE):/.cache/mod -e GOMODCACHE=/.cache/mod \
-v ~/.cache/golangci-lint:/.cache/golangci-lint -e GOLANGCI_LINT_CACHE=/.cache/golangci-lint \
golangci/golangci-lint:{{< golangci/latest-version >}} golangci-lint run
```
## mise
Note: `mise` is using the [aqua](https://aquaproj.github.io/) backend for this tool, so binaries installed came from GitHub assets (recommended).
You can install golangci-lint by using [`mise`](https://github.com/jdx/mise).
```bash
mise use -g golangci-lint@{{< golangci/latest-version >}}
```
The `mise` integration is not officially maintained by golangci team.
## Install from Sources
> [!WARNING]
> Using `go install`/`go get`, "tools pattern", and `tool` command/directives installations aren't guaranteed to work.
> We recommend using binary installation.
These installations aren't recommended because of the following points:
1. These installations compile golangci-lint locally. The Go version used to build will depend on your local Go version.
2. Some users use the `-u` flag for `go get`, which upgrades our dependencies. The resulting binary was not tested and is not guaranteed to work.
3. When using the "tools pattern" or `tool` command/directives, the dependencies of a tool can modify the dependencies of another tool or your project. The resulting binary was not tested and is not guaranteed to work.
4. We've encountered issues with Go module hashes due to the unexpected recreation of dependency tags.
5. `go.mod` replacement directives don't apply transitively. It means a user will be using a patched version of golangci-lint if we use such replacements.
6. It allows installation from the main branch, which can't be considered stable.
7. It's slower than binary installation.
```bash
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@{{< golangci/latest-version >}}
```
{{% details title="`go tool` usage recommendations" closed="true" %}}
> [!WARNING]
> We don't recommend using `go tool`.
But if you want to use `go tool` to install and run golangci-lint (**once again we don't recommend that**),
the best approach is to use a dedicated module or module file to isolate golangci-lint from other tools or dependencies.
This approach avoids modifying your project dependencies and the golangci-lint dependencies.
> [!CAUTION]
> You should never update golangci-lint dependencies manually.
**Method 1: dedicated module file**
```sh
# Create a dedicated module file
go mod init -modfile=golangci-lint.mod /golangci-lint
# Example: go mod init -modfile=golangci-lint.mod github.com/org/repo/golangci-lint
```
```sh
# Add golangci-lint as a tool
go get -tool -modfile=golangci-lint.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint@{{< golangci/latest-version >}}
```
```sh
# Run golangci-lint as a tool
go tool -modfile=golangci-lint.mod golangci-lint run
```
```sh
# Update golangci-lint
go get -tool -modfile=golangci-lint.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
```
**Method 2: dedicated module**
```sh
# Create a dedicated directory
mkdir golangci-lint
```
```sh
# Create a dedicated module file
go mod init -modfile=tools/go.mod /golangci-lint
# Example: go mod init -modfile=golangci-lint/go.mod github.com/org/repo/golangci-lint
```
```sh
# Setup a Go workspace
go work init . golangci-lint
```
```sh
# Add golangci-lint as a tool
go get -tool -modfile=golangci-lint/go.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint
```
```sh
# Run golangci-lint as a tool
go tool golangci-lint run
```
```sh
# Update golangci-lint
go get -tool -modfile=golangci-lint/go.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
```
{{% /details %}}
================================================
FILE: docs/content/docs/welcome/integrations.md
================================================
---
title: Integrations
weight: 3
aliases:
- /welcome/integrations/
---
## Editor Integration
### GoLand
Starting from version 2025.1, GoLand has built-in support of golangci-lint.
For IntelliJ IDEA with the Go plugin, please install the [plugin](https://plugins.jetbrains.com/plugin/12496-go-linter).
Both v1 and v2 versions are supported.
### Visual Studio Code
Install the [extension](https://marketplace.visualstudio.com/items?itemName=golang.Go).
{{% details title="Recommended settings for those who installed golangci-lint manually" closed="true" %}}
```JSONata
"go.lintTool": "golangci-lint",
"go.lintFlags": [
"--path-mode=abs",
"--fast-only"
],
"go.formatTool": "custom",
"go.alternateTools": {
"customFormatter": "golangci-lint"
},
"go.formatFlags": [
"fmt",
"--stdin"
]
```
Using it in an editor without `--fast-only` can freeze your editor.
Golangci-lint automatically discovers the `.golangci.yml` config for the edited file, so you don't need to configure it in VS Code settings.
{{% /details %}}
{{% details title="Recommended settings for those who installed golangci-lint via extension" closed="true" %}}
Install `golangci-lint-v2` via the `Go: Install/Update Tools` command after setting these configs.
This will enable golangci-lint v1 to co-exist with v2.
And use the following settings:
```JSONata
"go.lintTool": "golangci-lint-v2",
"go.lintFlags": [
"--path-mode=abs",
"--fast-only"
],
"go.formatTool": "custom",
"go.alternateTools": {
"customFormatter": "golangci-lint-v2"
},
"go.formatFlags": [
"fmt",
"--stdin"
]
```
Using it in an editor without `--fast-only` can freeze your editor.
Golangci-lint automatically discovers the `.golangci.yml` config for the edited file, so you don't need to configure it in VS Code settings.
{{% /details %}}
### GNU Emacs
There are available plugins:
- [Spacemacs](https://github.com/syl20bnr/spacemacs/blob/develop/layers/+lang/go/README.org#linting)
- [Flycheck checker](https://github.com/weijiangan/flycheck-golangci-lint)
### Vim
The following plugins support golangci-lint:
- [vim-go](https://github.com/fatih/vim-go)
- [ALE](https://github.com/w0rp/ale)
### LSP Server
[golangci-lint-langserver](https://github.com/nametake/golangci-lint-langserver) (NeoVim, Vim, Emacs, ...)
### Sublime Text
There is a [plugin](https://github.com/SublimeLinter/SublimeLinter-golangcilint) for SublimeLinter.
## Shell Completion
Golangci-lint can generate Bash, fish, PowerShell, and Zsh completion files.
See the instructions on `golangci-lint completion --help` (replace `` with your favorite one).
{{% details title="Bash & macOS" closed="true" %}}
There are two versions of `bash-completion`, v1 and v2. V1 is for Bash 3.2 (which is the default on macOS), and v2 is for Bash 4.1+.
The golangci-lint completion script doesn’t work correctly with bash-completion v1 and Bash 3.2. It requires bash-completion v2 and Bash 4.1+.
Thus, to be able to correctly use golangci-lint completion on macOS, you have to install and use Bash 4.1+ ([instructions](https://itnext.io/upgrading-bash-on-macos-7138bd1066ba)).
The following instructions assume that you use Bash 4.1+ (that is, any Bash version of 4.1 or newer).
Install `bash-completion v2`:
```bash
brew install bash-completion@2
echo 'export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"' >>~/.bashrc
echo '[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"' >>~/.bashrc
exec bash # reload and replace (if it was updated) shell
type _init_completion && echo "completion is OK" # verify that bash-completion v2 is correctly installed
```
Add golangci-lint bash completion:
```bash
echo 'source <(golangci-lint completion bash)' >>~/.bashrc
source ~/.bashrc
```
{{% /details %}}
## CI Integration
Check out our [documentation for CI integrations](/docs/welcome/install#ci-installation).
================================================
FILE: docs/content/docs/welcome/quick-start.md
================================================
---
title: Quick Start
weight: 2
aliases:
- /welcome/quick-start/
---
## Linting
To run golangci-lint:
```bash
golangci-lint run
```
It's an equivalent of:
```bash
golangci-lint run ./...
```
You can choose which directories or files to analyze:
```bash
golangci-lint run dir1 dir2/...
golangci-lint run file1.go
```
Directories are NOT analyzed recursively.
To analyze them recursively append `/...` to their path.
It's not possible to mix files and packages/directories, and files must come from the same package.
Golangci-lint can be used with zero configuration. By default, the following linters are enabled:
{{% golangci/cli-output section="defaultEnabledLinters" cmd="help linters" %}}
Pass `-E/--enable` to enable linter and `-D/--disable` to disable:
```bash
golangci-lint run --default=none -E errcheck
```
More information about available linters can be found in the [linters page](/docs/linters/).
## Formatting
To format your code:
```bash
golangci-lint fmt
```
You can choose which directories or files to analyze:
```bash
golangci-lint fmt dir1 dir2/...
golangci-lint fmt file1.go
```
More information about available formatters can be found in the [formatters page](/docs/formatters/).
================================================
FILE: docs/data/cli_help.json
================================================
{
"defaultEnabledLinters": "Enabled by default linters:\nerrcheck: Errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases.\ngovet: Vet examines Go source code and reports suspicious constructs. It is roughly the same as 'go vet' and uses its passes. [auto-fix]\nineffassign: Detects when assignments to existing variables are not used. [fast]\nstaticcheck: It's the set of rules from staticcheck. [auto-fix]\nunused: Checks Go code for unused constants, variables, functions and types.",
"rootOutput": "Smart, fast linters runner.\n\nUsage:\n golangci-lint [flags]\n golangci-lint [command]\n\nAvailable Commands:\n cache Cache control and information.\n completion Generate the autocompletion script for the specified shell\n config Configuration file information and verification.\n custom Build a version of golangci-lint with custom linters.\n fmt Format Go source files.\n formatters List current formatters configuration.\n help Display extra help\n linters List current linters configuration.\n migrate Migrate configuration file from v1 to v2.\n run Lint the code.\n version Display the golangci-lint version.\n\nFlags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n --version Print version\n\nUse \"golangci-lint [command] --help\" for more information about a command.\n",
"runOutput": "Lint the code.\n\nUsage:\n golangci-lint run [flags]\n\nFlags:\n -c, --config PATH Read config from file path PATH\n --no-config Don't read config file\n --default string Default set of linters to enable (default \"standard\")\n -D, --disable strings Disable specific linter\n -E, --enable strings Enable specific linter\n --enable-only strings Override linters configuration section to only run the specific linter(s)\n --fast-only Filter enabled linters to run only fast linters\n -j, --concurrency int Number of CPUs to use (Default: Automatically set to match Linux container CPU quota and fall back to the number of logical CPUs in the machine)\n --modules-download-mode string Modules download mode. If not empty, passed as -mod=\u003cmode\u003e to go tools\n --issues-exit-code int Exit code when issues were found (default 1)\n --build-tags strings Build tags\n --timeout duration Timeout for total work. Disabled by default\n --tests Analyze tests (*_test.go) (default true)\n --allow-parallel-runners Allow multiple parallel golangci-lint instances running.\n If false (default) - golangci-lint acquires file lock on start.\n --allow-serial-runners Allow multiple golangci-lint instances running, but serialize them around a lock.\n If false (default) - golangci-lint exits with an error if it fails to acquire file lock on start.\n --path-prefix string Path prefix to add to output\n --path-mode string Path mode to use (empty, or 'abs')\n --show-stats Show statistics per linter (default true)\n --output.text.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --output.text.print-linter-name Print linter name in the end of issue text. (default true)\n --output.text.print-issued-lines Print lines of code with issue. (default true)\n --output.text.colors Use colors. (default true)\n --output.json.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --output.tab.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --output.tab.print-linter-name Print linter name in the end of issue text. (default true)\n --output.tab.colors Use colors. (default true)\n --output.html.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --output.checkstyle.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --output.code-climate.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --output.junit-xml.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --output.junit-xml.extended Support extra JUnit XML fields.\n --output.teamcity.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --output.sarif.path stdout Output path can be either stdout, `stderr` or path to the file to write to.\n --max-issues-per-linter int Maximum issues count per one linter. Set to 0 to disable (default 50)\n --max-same-issues int Maximum count of issues with the same text. Set to 0 to disable (default 3)\n --uniq-by-line Make issues output unique by line (default true)\n -n, --new Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.\n It's a super-useful option for integration of golangci-lint into existing large codebase.\n It's not practical to fix all existing issues at the moment of integration: much better to not allow issues in new code.\n For CI setups, prefer --new-from-rev=HEAD~, as --new can skip linting the current patch if any scripts generate unstaged files before golangci-lint runs.\n --new-from-rev REV Show only new issues created after git revision REV\n --new-from-patch PATH Show only new issues created in git patch with file path PATH\n --new-from-merge-base string Show only new issues created after the best common ancestor (merge-base against HEAD)\n --whole-files Show issues in any part of update files (requires new-from-rev or new-from-patch)\n --fix Apply the fixes detected by the linters and formatters (if it's supported by the linter)\n --cpu-profile-path string Path to CPU profile output file\n --mem-profile-path string Path to memory profile output file\n --trace-path string Path to trace output file\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n",
"lintersOutput": "List current linters configuration.\n\nUsage:\n golangci-lint linters [flags]\n\nFlags:\n -c, --config PATH Read config from file path PATH\n --no-config Don't read config file\n --default string Default set of linters to enable (default \"standard\")\n -D, --disable strings Disable specific linter\n -E, --enable strings Enable specific linter\n --enable-only strings Override linters configuration section to only run the specific linter(s)\n --fast-only Filter enabled linters to run only fast linters\n --json Display as JSON\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n",
"fmtOutput": "Format Go source files.\n\nUsage:\n golangci-lint fmt [flags]\n\nFlags:\n -c, --config PATH Read config from file path PATH\n --no-config Don't read config file\n -E, --enable strings Enable specific formatter\n -d, --diff Display diffs instead of rewriting files\n --diff-colored Display diffs instead of rewriting files (with colors)\n --stdin Use standard input for piping source files\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n",
"formattersOutput": "List current formatters configuration.\n\nUsage:\n golangci-lint formatters [flags]\n\nFlags:\n -c, --config PATH Read config from file path PATH\n --no-config Don't read config file\n -E, --enable strings Enable specific formatter\n --json Display as JSON\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n",
"helpOutput": "Display extra help\n\nUsage:\n golangci-lint help [flags]\n golangci-lint help [command]\n\nAvailable Commands:\n formatters Display help for formatters.\n linters Display help for linters.\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n\nUse \"golangci-lint help [command] --help\" for more information about a command.\n",
"migrateOutput": "Migrate configuration file from v1 to v2.\n\nUsage:\n golangci-lint migrate [flags]\n\nFlags:\n -c, --config PATH Read config from file path PATH\n --no-config Don't read config file\n --format string Output file format.\n By default, the format of the input configuration file is used.\n It can be 'yml', 'yaml', 'toml', or 'json'.\n --skip-validation Skip validation of the configuration file against the JSON Schema for v1.\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n",
"configOutput": "Configuration file information and verification.\n\nUsage:\n golangci-lint config [flags]\n golangci-lint config [command]\n\nAvailable Commands:\n path Print used configuration path.\n verify Verify configuration against JSON schema.\n\nFlags:\n -c, --config PATH Read config from file path PATH\n --no-config Don't read config file\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n\nUse \"golangci-lint config [command] --help\" for more information about a command.\n",
"customOutput": "Build a version of golangci-lint with custom linters.\n\nUsage:\n golangci-lint custom [flags]\n\nFlags:\n --destination string The directory path used to store the custom binary\n --name string The name of the custom binary\n --version string The golangci-lint version used to build the custom binary\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n",
"cacheOutput": "Cache control and information.\n\nUsage:\n golangci-lint cache [flags]\n golangci-lint cache [command]\n\nAvailable Commands:\n clean Clean cache\n status Show cache status\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n\nUse \"golangci-lint cache [command] --help\" for more information about a command.\n",
"versionOutput": "Display the golangci-lint version.\n\nUsage:\n golangci-lint version [flags]\n\nFlags:\n --debug Add build information\n --json Display as JSON\n --short Display only the version number\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n",
"completionOutput": "Generate the autocompletion script for golangci-lint for the specified shell.\nSee each sub-command's help for details on how to use the generated script.\n\nUsage:\n golangci-lint completion [command]\n\nAvailable Commands:\n bash Generate the autocompletion script for bash\n fish Generate the autocompletion script for fish\n powershell Generate the autocompletion script for powershell\n zsh Generate the autocompletion script for zsh\n\nGlobal Flags:\n --color string Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n -h, --help Help for a command\n -v, --verbose Verbose output\n\nUse \"golangci-lint completion [command] --help\" for more information about a command.\n"
}
================================================
FILE: docs/data/configuration_file.json
================================================
{
"formatters": "formatters:\n # Enable specific formatter.\n # Default: [] (uses standard Go formatting)\n enable:\n - gci\n - gofmt\n - gofumpt\n - goimports\n - golines\n - swaggo\n # Formatters settings.\n settings:\n # See the dedicated \"formatters.settings\" documentation section.\n option: value\n exclusions:\n # Log a warning if an exclusion path is unused.\n # Default: false\n warn-unused: true\n # Mode of the generated files analysis.\n #\n # - `strict`: sources are excluded by strictly following the Go generated file convention.\n # Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\\.$`\n # This line must appear before the first non-comment, non-blank text in the file.\n # https://go.dev/s/generatedcode\n # - `lax`: sources are excluded if they contain lines like `autogenerated file`, `code generated`, `do not edit`, etc.\n # - `disable`: disable the generated files exclusion.\n #\n # Default: lax\n generated: strict\n # Which file paths to exclude.\n # This option is ignored when using `--stdin` as the path is unknown.\n # Default: []\n paths:\n - \".*\\\\.my\\\\.go$\"\n - lib/bad.go\n",
"issues": "issues:\n # Maximum issues count per one linter.\n # Set to 0 to disable.\n # Default: 50\n max-issues-per-linter: 0\n # Maximum count of issues with the same text.\n # Set to 0 to disable.\n # Default: 3\n max-same-issues: 0\n # Make issues output unique by line.\n # Default: true\n uniq-by-line: false\n # Show only new issues: if there are unstaged changes or untracked files,\n # only those changes are analyzed, else only changes in HEAD~ are analyzed.\n # It's a super-useful option for integration of golangci-lint into existing large codebase.\n # It's not practical to fix all existing issues at the moment of integration:\n # much better don't allow issues in new code.\n #\n # Default: false\n new: true\n # Show only new issues created after the best common ancestor (merge-base against HEAD).\n # Default: \"\"\n new-from-merge-base: main\n # Show only new issues created after git revision `REV`.\n # Default: \"\"\n new-from-rev: HEAD\n # Show only new issues created in git patch with set file path.\n # Default: \"\"\n new-from-patch: path/to/patch/file\n # Show issues in any part of update files (requires new-from-rev or new-from-patch).\n # Default: false\n whole-files: true\n # Apply the fixes detected by the linters and formatters (if it's supported by the linter).\n # Default: false\n fix: true\n",
"linters": "linters:\n # Default set of linters.\n # The value can be:\n # - `standard`: https://golangci-lint.run/docs/linters/#enabled-by-default\n # - `all`: enables all linters by default.\n # - `none`: disables all linters by default.\n # - `fast`: enables only linters considered as \"fast\" (`golangci-lint help linters --json | jq '[ .[] | select(.fast==true) ] | map(.name)'`).\n # Default: standard\n default: all\n # Enable specific linter.\n enable:\n - arangolint\n - asasalint\n - asciicheck\n - bidichk\n - bodyclose\n - canonicalheader\n - containedctx\n - contextcheck\n - copyloopvar\n - cyclop\n - decorder\n - depguard\n - dogsled\n - dupl\n - dupword\n - durationcheck\n - embeddedstructfieldcheck\n - err113\n - errcheck\n - errchkjson\n - errname\n - errorlint\n - exhaustive\n - exhaustruct\n - exptostd\n - fatcontext\n - forbidigo\n - forcetypeassert\n - funcorder\n - funlen\n - ginkgolinter\n - gocheckcompilerdirectives\n - gochecknoglobals\n - gochecknoinits\n - gochecksumtype\n - gocognit\n - goconst\n - gocritic\n - gocyclo\n - godoclint\n - godot\n - godox\n - goheader\n - gomoddirectives\n - gomodguard\n - goprintffuncname\n - gosec\n - gosmopolitan\n - govet\n - grouper\n - iface\n - importas\n - inamedparam\n - ineffassign\n - interfacebloat\n - intrange\n - iotamixing\n - ireturn\n - lll\n - loggercheck\n - maintidx\n - makezero\n - mirror\n - misspell\n - mnd\n - modernize\n - musttag\n - nakedret\n - nestif\n - nilerr\n - nilnesserr\n - nilnil\n - nlreturn\n - noctx\n - noinlineerr\n - nolintlint\n - nonamedreturns\n - nosprintfhostport\n - paralleltest\n - perfsprint\n - prealloc\n - predeclared\n - promlinter\n - protogetter\n - reassign\n - recvcheck\n - revive\n - rowserrcheck\n - sloglint\n - spancheck\n - sqlclosecheck\n - staticcheck\n - tagalign\n - tagliatelle\n - testableexamples\n - testifylint\n - testpackage\n - thelper\n - tparallel\n - unconvert\n - unparam\n - unqueryvet\n - unused\n - usestdlibvars\n - usetesting\n - varnamelen\n - wastedassign\n - whitespace\n - wrapcheck\n - wsl\n - wsl_v5\n - zerologlint\n # Disable specific linters.\n disable:\n - arangolint\n - asasalint\n - asciicheck\n - bidichk\n - bodyclose\n - canonicalheader\n - containedctx\n - contextcheck\n - copyloopvar\n - cyclop\n - decorder\n - depguard\n - dogsled\n - dupl\n - dupword\n - durationcheck\n - embeddedstructfieldcheck\n - err113\n - errcheck\n - errchkjson\n - errname\n - errorlint\n - exhaustive\n - exhaustruct\n - exptostd\n - fatcontext\n - forbidigo\n - forcetypeassert\n - funcorder\n - funlen\n - ginkgolinter\n - gocheckcompilerdirectives\n - gochecknoglobals\n - gochecknoinits\n - gochecksumtype\n - gocognit\n - goconst\n - gocritic\n - gocyclo\n - godoclint\n - godot\n - godox\n - goheader\n - gomoddirectives\n - gomodguard\n - goprintffuncname\n - gosec\n - gosmopolitan\n - govet\n - grouper\n - iface\n - importas\n - inamedparam\n - ineffassign\n - interfacebloat\n - intrange\n - iotamixing\n - ireturn\n - lll\n - loggercheck\n - maintidx\n - makezero\n - mirror\n - misspell\n - mnd\n - modernize\n - musttag\n - nakedret\n - nestif\n - nilerr\n - nilnesserr\n - nilnil\n - nlreturn\n - noctx\n - noinlineerr\n - nolintlint\n - nonamedreturns\n - nosprintfhostport\n - paralleltest\n - perfsprint\n - prealloc\n - predeclared\n - promlinter\n - protogetter\n - reassign\n - recvcheck\n - revive\n - rowserrcheck\n - sloglint\n - spancheck\n - sqlclosecheck\n - staticcheck\n - tagalign\n - tagliatelle\n - testableexamples\n - testifylint\n - testpackage\n - thelper\n - tparallel\n - unconvert\n - unparam\n - unqueryvet\n - unused\n - usestdlibvars\n - usetesting\n - varnamelen\n - wastedassign\n - whitespace\n - wrapcheck\n - wsl\n - wsl_v5\n - zerologlint\n # All available settings of specific linters.\n settings:\n # See the dedicated \"linters.settings\" documentation section.\n option: value\n # Defines a set of rules to ignore issues.\n # It does not skip the analysis, and so does not ignore \"typecheck\" errors.\n exclusions:\n # Mode of the generated files analysis.\n #\n # - `strict`: sources are excluded by strictly following the Go generated file convention.\n # Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\\.$`\n # This line must appear before the first non-comment, non-blank text in the file.\n # https://go.dev/s/generatedcode\n # - `lax`: sources are excluded if they contain lines like `autogenerated file`, `code generated`, `do not edit`, etc.\n # - `disable`: disable the generated files exclusion.\n #\n # Default: strict\n generated: lax\n # Log a warning if an exclusion rule is unused.\n # Default: false\n warn-unused: true\n # Predefined exclusion rules.\n # Default: []\n presets:\n - comments\n - std-error-handling\n - common-false-positives\n - legacy\n # Excluding configuration per-path, per-linter, per-text and per-source.\n rules:\n # Exclude some linters from running on tests files.\n - path: _test\\.go\n linters:\n - gocyclo\n - errcheck\n - dupl\n - gosec\n # Run some linter only for test files by excluding its issues for everything else.\n - path-except: _test\\.go\n linters:\n - forbidigo\n # Exclude known linters from partially hard-vendored code,\n # which is impossible to exclude via `nolint` comments.\n # `/` will be replaced by the current OS file path separator to properly work on Windows.\n - path: internal/hmac/\n text: \"weak cryptographic primitive\"\n linters:\n - gosec\n # Exclude some `staticcheck` messages.\n - linters:\n - staticcheck\n text: \"SA9003:\"\n # Exclude `lll` issues for long lines with `go:generate`.\n - linters:\n - lll\n source: \"^//go:generate \"\n # Which file paths to exclude: they will be analyzed, but issues from them won't be reported.\n # \"/\" will be replaced by the current OS file path separator to properly work on Windows.\n # Default: []\n paths:\n - \".*\\\\.my\\\\.go$\"\n - lib/bad.go\n # Which file paths to not exclude.\n # Default: []\n paths-except:\n - \".*\\\\.my\\\\.go$\"\n - lib/bad.go\n",
"output": "# Output configuration options.\noutput:\n # The formats used to render issues.\n formats:\n # Prints issues in a text format with colors, line number, and linter name.\n # This format is the default format.\n text:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.txt\n # Print linter name in the end of issue text.\n # Default: true\n print-linter-name: false\n # Print lines of code with issue.\n # Default: true\n print-issued-lines: false\n # Use colors.\n # Default: true\n colors: false\n # Prints issues in a JSON representation.\n json:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.json\n # Prints issues in columns representation separated by tabulations.\n tab:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.txt\n # Print linter name in the end of issue text.\n # Default: true\n print-linter-name: true\n # Use colors.\n # Default: true\n colors: false\n # Prints issues in an HTML page.\n # It uses the Cloudflare CDN (cdnjs) and React.\n html:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.html\n # Prints issues in the Checkstyle format.\n checkstyle:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.xml\n # Prints issues in the Code Climate format.\n code-climate:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.json\n # Prints issues in the JUnit XML format.\n junit-xml:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.xml\n # Support extra JUnit XML fields.\n # Default: false\n extended: true\n # Prints issues in the TeamCity format.\n teamcity:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.txt\n # Prints issues in the SARIF format.\n sarif:\n # Output path can be either `stdout`, `stderr` or path to the file to write to.\n # Default: stdout\n path: ./path/to/output.json\n # Add a prefix to the output file references.\n # This option is ignored when using `output.path-mode: abs` mode.\n # Default: \"\"\n path-prefix: \"\"\n # By default, the report are related to the path obtained by `run.relative-path-mode`.\n # The mode `abs` allows to show absolute file paths instead of relative file paths.\n # The option `output.path-prefix` is ignored when using `abs` mode.\n # Default: \"\"\n path-mode: \"abs\"\n # Order to use when sorting results.\n # Possible values: `file`, `linter`, and `severity`.\n #\n # If the severity values are inside the following list, they are ordered in this order:\n # 1. error\n # 2. warning\n # 3. high\n # 4. medium\n # 5. low\n # Either they are sorted alphabetically.\n #\n # Default: [\"linter\", \"file\"]\n sort-order:\n - linter\n - severity\n - file # filepath, line, and column.\n # Show statistics per linter.\n # Default: true\n show-stats: false\n",
"root": "# See the dedicated \"version\" documentation section.\nversion: \"2\"\nlinters:\n # See the dedicated \"linters\" documentation section.\n option: value\nformatters:\n # See the dedicated \"formatters\" documentation section.\n option: value\nissues:\n # See the dedicated \"issues\" documentation section.\n option: value\n# Output configuration options.\noutput:\n # See the dedicated \"output\" documentation section.\n option: value\n# Options for analysis running.\nrun:\n # See the dedicated \"run\" documentation section.\n option: value\nseverity:\n # See the dedicated \"severity\" documentation section.\n option: value\n",
"run": "# Options for analysis running.\nrun:\n # Timeout for total work, e.g. 30s, 5m, 5m30s.\n # If the value is lower or equal to 0, the timeout is disabled.\n # Default: 0 (disabled)\n timeout: 5m\n # The mode used to evaluate relative paths.\n # It's used by exclusions, Go plugins, and some linters.\n # The value can be:\n # - `gomod`: the paths will be relative to the directory of the `go.mod` file.\n # - `gitroot`: the paths will be relative to the git root (the parent directory of `.git`).\n # - `cfg`: the paths will be relative to the configuration file.\n # - `wd` (NOT recommended): the paths will be relative to the place where golangci-lint is run.\n # Default: cfg\n relative-path-mode: gomod\n # Exit code when at least one issue was found.\n # Default: 1\n issues-exit-code: 2\n # Include test files or not.\n # Default: true\n tests: false\n # List of build tags, all linters use it.\n # Default: []\n build-tags:\n - mytag\n # If set, we pass it to \"go list -mod={option}\". From \"go help modules\":\n # If invoked with -mod=readonly, the go command is disallowed from the implicit\n # automatic updating of go.mod described above. Instead, it fails when any changes\n # to go.mod are needed. This setting is most useful to check that go.mod does\n # not need updates, such as in a continuous integration and testing system.\n # If invoked with -mod=vendor, the go command assumes that the vendor\n # directory holds the correct copies of dependencies and ignores\n # the dependency descriptions in go.mod.\n #\n # Allowed values: readonly|vendor|mod\n # Default: \"\"\n modules-download-mode: readonly\n # Uses version control information during the loading of packages.\n # Default: false (implies `-buildvcs=false`)\n enable-build-vcs: true\n # Allow multiple parallel golangci-lint instances running.\n # If false, golangci-lint acquires file lock on start.\n # Default: false\n allow-parallel-runners: true\n # Allow multiple golangci-lint instances running, but serialize them around a lock.\n # If false, golangci-lint exits with an error if it fails to acquire file lock on start.\n # Default: false\n allow-serial-runners: true\n # Define the Go version limit.\n # Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.22.\n go: '1.23'\n # Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously.\n # Default: 0 (automatically set to match Linux container CPU quota and\n # fall back to the number of logical CPUs in the machine)\n concurrency: 4\n",
"severity": "severity:\n # Set the default severity for issues.\n #\n # If severity rules are defined and the issues do not match or no severity is provided to the rule\n # this will be the default severity applied.\n # Severities should match the supported severity names of the selected out format.\n # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity\n # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#SeverityLevel\n # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message\n # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance\n #\n # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)\n #\n # Default: \"\"\n default: error\n # When a list of severity rules are provided, severity information will be added to lint issues.\n # Severity rules have the same filtering capability as exclude rules\n # except you are allowed to specify one matcher per severity rule.\n #\n # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)\n #\n # Only affects out formats that support setting severity information.\n #\n # Default: []\n rules:\n - linters:\n - dupl\n severity: info\n",
"version": "# Defines the configuration version.\n# The only possible value is \"2\".\nversion: \"2\"\n"
}
================================================
FILE: docs/data/exclusion_presets.json
================================================
{
"comments": [
{
"linters": [
"staticcheck"
],
"text": "(ST1000|ST1020|ST1021|ST1022)"
},
{
"linters": [
"revive"
],
"text": "exported (.+) should have comment( \\(or a comment on this block\\))? or be unexported"
},
{
"linters": [
"revive"
],
"text": "package comment should be of the form \"(.+)...\""
},
{
"linters": [
"revive"
],
"text": "comment on exported (.+) should be of the form \"(.+)...\""
},
{
"linters": [
"revive"
],
"text": "should have a package comment"
}
],
"common-false-positives": [
{
"linters": [
"gosec"
],
"text": "G103: Use of unsafe calls should be audited"
},
{
"linters": [
"gosec"
],
"text": "G204: Subprocess launched with variable"
},
{
"linters": [
"gosec"
],
"text": "G304: Potential file inclusion via variable"
}
],
"legacy": [
{
"linters": [
"govet"
],
"text": "(possible misuse of unsafe.Pointer|should have signature)"
},
{
"linters": [
"staticcheck"
],
"text": "SA4011"
},
{
"linters": [
"gosec"
],
"text": "G104"
},
{
"linters": [
"gosec"
],
"text": "(G301|G302|G307): Expect (directory permissions to be 0750|file permissions to be 0600) or less"
}
],
"std-error-handling": [
{
"linters": [
"errcheck"
],
"text": "(?i)Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked"
}
]
}
================================================
FILE: docs/data/formatters_info.json
================================================
[
{
"name": "gci",
"desc": "Check if code and import statements are formatted, with additional rules.",
"loadMode": 8199,
"originalURL": "https://github.com/daixiang0/gci",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.30.0"
},
{
"name": "gofmt",
"desc": "Check if the code is formatted according to 'gofmt' command.",
"loadMode": 8199,
"originalURL": "https://pkg.go.dev/cmd/gofmt",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.0.0"
},
{
"name": "gofumpt",
"desc": "Check if code and import statements are formatted, with additional rules.",
"loadMode": 8199,
"originalURL": "https://github.com/mvdan/gofumpt",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.28.0"
},
{
"name": "golines",
"desc": "Checks if code is formatted, and fixes long lines",
"loadMode": 8199,
"originalURL": "https://github.com/segmentio/golines",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v2.0.0"
},
{
"name": "goimports",
"desc": "Checks if the code and import statements are formatted according to the 'goimports' command.",
"loadMode": 8199,
"originalURL": "https://pkg.go.dev/golang.org/x/tools/cmd/goimports",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.20.0"
},
{
"name": "swaggo",
"desc": "Check if swaggo comments are formatted",
"loadMode": 8199,
"originalURL": "https://github.com/swaggo/swag",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v2.2.0"
}
]
================================================
FILE: docs/data/icons.yaml
================================================
heart-red:
================================================
FILE: docs/data/linters_info.json
================================================
[
{
"name": "arangolint",
"desc": "opinionated best practices for arangodb client",
"loadMode": 8767,
"originalURL": "https://github.com/Crocmagnon/arangolint",
"internal": false,
"isSlow": true,
"since": "v2.2.0"
},
{
"name": "asasalint",
"desc": "check for pass []any as any in variadic func(...any)",
"loadMode": 8767,
"originalURL": "https://github.com/alingse/asasalint",
"internal": false,
"isSlow": true,
"since": "v1.47.0"
},
{
"name": "asciicheck",
"desc": "checks that all code identifiers does not have non-ASCII symbols in the name",
"loadMode": 8199,
"originalURL": "https://github.com/golangci/asciicheck",
"internal": false,
"isSlow": false,
"since": "v1.26.0"
},
{
"name": "bidichk",
"desc": "Checks for dangerous unicode character sequences",
"loadMode": 8199,
"originalURL": "https://github.com/breml/bidichk",
"internal": false,
"isSlow": false,
"since": "v1.43.0"
},
{
"name": "bodyclose",
"desc": "checks whether HTTP response body is closed successfully",
"loadMode": 8767,
"originalURL": "https://github.com/timakin/bodyclose",
"internal": false,
"isSlow": true,
"since": "v1.18.0"
},
{
"name": "canonicalheader",
"desc": "canonicalheader checks whether net/http.Header uses canonical header",
"loadMode": 8767,
"originalURL": "https://github.com/lasiar/canonicalheader",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.58.0"
},
{
"name": "containedctx",
"desc": "containedctx is a linter that detects struct contained context.Context field",
"loadMode": 8767,
"originalURL": "https://github.com/sivchari/containedctx",
"internal": false,
"isSlow": true,
"since": "v1.44.0"
},
{
"name": "contextcheck",
"desc": "check whether the function uses a non-inherited context",
"loadMode": 8767,
"originalURL": "https://github.com/kkHAIKE/contextcheck",
"internal": false,
"isSlow": true,
"since": "v1.43.0"
},
{
"name": "copyloopvar",
"desc": "a linter detects places where loop variables are copied",
"loadMode": 8199,
"originalURL": "https://github.com/karamaru-alpha/copyloopvar",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.57.0"
},
{
"name": "cyclop",
"desc": "checks function and package cyclomatic complexity",
"loadMode": 8199,
"originalURL": "https://github.com/bkielbasa/cyclop",
"internal": false,
"isSlow": false,
"since": "v1.37.0"
},
{
"name": "decorder",
"desc": "check declaration order and count of types, constants, variables and functions",
"loadMode": 8199,
"originalURL": "https://gitlab.com/bosi/decorder",
"internal": false,
"isSlow": false,
"since": "v1.44.0"
},
{
"name": "depguard",
"desc": "Go linter that checks if package imports are in a list of acceptable packages",
"loadMode": 8199,
"originalURL": "https://github.com/OpenPeeDeeP/depguard",
"internal": false,
"isSlow": false,
"since": "v1.4.0"
},
{
"name": "dogsled",
"desc": "Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())",
"loadMode": 8199,
"originalURL": "https://github.com/alexkohler/dogsled",
"internal": false,
"isSlow": false,
"since": "v1.19.0"
},
{
"name": "dupl",
"desc": "Detects duplicate fragments of code.",
"loadMode": 8199,
"originalURL": "https://github.com/mibk/dupl",
"internal": false,
"isSlow": false,
"since": "v1.0.0"
},
{
"name": "dupword",
"desc": "Checks for duplicate words in the source code",
"loadMode": 8199,
"originalURL": "https://github.com/Abirdcfly/dupword",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.50.0"
},
{
"name": "durationcheck",
"desc": "check for two durations multiplied together",
"loadMode": 8767,
"originalURL": "https://github.com/charithe/durationcheck",
"internal": false,
"isSlow": true,
"since": "v1.37.0"
},
{
"name": "embeddedstructfieldcheck",
"desc": "Embedded types should be at the top of the field list of a struct, and there must be an empty line separating embedded fields from regular fields.",
"loadMode": 8199,
"originalURL": "https://github.com/manuelarte/embeddedstructfieldcheck",
"internal": false,
"isSlow": false,
"since": "v2.2.0"
},
{
"name": "errcheck",
"desc": "errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases",
"groups": [
"standard"
],
"loadMode": 8767,
"originalURL": "https://github.com/kisielk/errcheck",
"internal": false,
"isSlow": true,
"since": "v1.0.0"
},
{
"name": "errchkjson",
"desc": "Checks types passed to the json encoding functions. Reports unsupported types and reports occurrences where the check for the returned error can be omitted.",
"loadMode": 8767,
"originalURL": "https://github.com/breml/errchkjson",
"internal": false,
"isSlow": true,
"since": "v1.44.0"
},
{
"name": "errname",
"desc": "Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`.",
"loadMode": 8767,
"originalURL": "https://github.com/Antonboom/errname",
"internal": false,
"isSlow": true,
"since": "v1.42.0"
},
{
"name": "errorlint",
"desc": "Find code that can cause problems with the error wrapping scheme introduced in Go 1.13.",
"loadMode": 8767,
"originalURL": "https://codeberg.org/polyfloyd/go-errorlint",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.32.0"
},
{
"name": "exhaustive",
"desc": "check exhaustiveness of enum switch statements",
"loadMode": 8767,
"originalURL": "https://github.com/nishanths/exhaustive",
"internal": false,
"isSlow": true,
"since": "v1.28.0"
},
{
"name": "exhaustruct",
"desc": "Checks if all structure fields are initialized",
"loadMode": 8767,
"originalURL": "https://github.com/GaijinEntertainment/go-exhaustruct",
"internal": false,
"isSlow": true,
"since": "v1.46.0"
},
{
"name": "exptostd",
"desc": "Detects functions from golang.org/x/exp/ that can be replaced by std functions.",
"loadMode": 8767,
"originalURL": "https://github.com/ldez/exptostd",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.63.0"
},
{
"name": "forbidigo",
"desc": "Forbids identifiers",
"loadMode": 8767,
"originalURL": "https://github.com/ashanbrown/forbidigo",
"internal": false,
"isSlow": true,
"since": "v1.34.0"
},
{
"name": "forcetypeassert",
"desc": "Find forced type assertions",
"loadMode": 8767,
"originalURL": "https://github.com/gostaticanalysis/forcetypeassert",
"internal": false,
"isSlow": true,
"since": "v1.38.0"
},
{
"name": "funcorder",
"desc": "checks the order of functions, methods, and constructors",
"loadMode": 8199,
"originalURL": "https://github.com/manuelarte/funcorder",
"internal": false,
"isSlow": false,
"since": "v2.1.0"
},
{
"name": "fatcontext",
"desc": "detects nested contexts in loops and function literals",
"loadMode": 8767,
"originalURL": "https://github.com/Crocmagnon/fatcontext",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.58.0"
},
{
"name": "funlen",
"desc": "Checks for long functions.",
"loadMode": 8199,
"originalURL": "https://github.com/ultraware/funlen",
"internal": false,
"isSlow": false,
"since": "v1.18.0"
},
{
"name": "ginkgolinter",
"desc": "enforces standards of using ginkgo and gomega",
"loadMode": 8767,
"originalURL": "https://github.com/nunnatsa/ginkgolinter",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.51.0"
},
{
"name": "gocheckcompilerdirectives",
"desc": "Checks that go compiler directive comments (//go:) are valid.",
"loadMode": 8199,
"originalURL": "https://github.com/leighmcculloch/gocheckcompilerdirectives",
"internal": false,
"isSlow": false,
"since": "v1.51.0"
},
{
"name": "gochecknoglobals",
"desc": "Check that no global variables exist.",
"loadMode": 8767,
"originalURL": "https://github.com/leighmcculloch/gochecknoglobals",
"internal": false,
"isSlow": true,
"since": "v1.12.0"
},
{
"name": "gochecknoinits",
"desc": "Checks that no init functions are present in Go code",
"loadMode": 8199,
"internal": false,
"isSlow": false,
"since": "v1.12.0"
},
{
"name": "gochecksumtype",
"desc": "Run exhaustiveness checks on Go \"sum types\"",
"loadMode": 8767,
"originalURL": "https://github.com/alecthomas/go-check-sumtype",
"internal": false,
"isSlow": true,
"since": "v1.55.0"
},
{
"name": "gocognit",
"desc": "Computes and checks the cognitive complexity of functions",
"loadMode": 8199,
"originalURL": "https://github.com/uudashr/gocognit",
"internal": false,
"isSlow": false,
"since": "v1.20.0"
},
{
"name": "goconst",
"desc": "Finds repeated strings that could be replaced by a constant",
"loadMode": 8767,
"originalURL": "https://github.com/jgautheron/goconst",
"internal": false,
"isSlow": true,
"since": "v1.0.0"
},
{
"name": "gocritic",
"desc": "Provides diagnostics that check for bugs, performance and style issues.\nExtensible without recompilation through dynamic rules.\nDynamic rules are written declaratively with AST patterns, filters, report message and optional suggestion.",
"loadMode": 8767,
"originalURL": "https://github.com/go-critic/go-critic",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.12.0"
},
{
"name": "gocyclo",
"desc": "Computes and checks the cyclomatic complexity of functions",
"loadMode": 8199,
"originalURL": "https://github.com/fzipp/gocyclo",
"internal": false,
"isSlow": false,
"since": "v1.0.0"
},
{
"name": "godoclint",
"desc": "Checks Golang's documentation practice (godoc)",
"loadMode": 8199,
"originalURL": "https://github.com/godoc-lint/godoc-lint",
"internal": false,
"isSlow": false,
"since": "v2.5.0"
},
{
"name": "godot",
"desc": "Check if comments end in a period",
"loadMode": 8199,
"originalURL": "https://github.com/tetafro/godot",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.25.0"
},
{
"name": "godox",
"desc": "Detects usage of FIXME, TODO and other keywords inside comments",
"loadMode": 8199,
"originalURL": "https://github.com/matoous/godox",
"internal": false,
"isSlow": false,
"since": "v1.19.0"
},
{
"name": "err113",
"desc": "Check errors handling expressions",
"loadMode": 8767,
"originalURL": "https://github.com/Djarvur/go-err113",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.26.0"
},
{
"name": "goheader",
"desc": "Check if file header matches to pattern",
"loadMode": 8199,
"originalURL": "https://github.com/denis-tingaikin/go-header",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.28.0"
},
{
"name": "mnd",
"desc": "An analyzer to detect magic numbers.",
"loadMode": 8199,
"originalURL": "https://github.com/tommy-muehle/go-mnd",
"internal": false,
"isSlow": false,
"since": "v1.22.0"
},
{
"name": "modernize",
"desc": "A suite of analyzers that suggest simplifications to Go code, using modern language and library features.",
"loadMode": 8767,
"originalURL": "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize",
"internal": false,
"isSlow": true,
"since": "v2.6.0"
},
{
"name": "gomoddirectives",
"desc": "Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.",
"loadMode": 8199,
"originalURL": "https://github.com/ldez/gomoddirectives",
"internal": false,
"isSlow": false,
"since": "v1.39.0"
},
{
"name": "gomodguard",
"desc": "Allow and blocklist linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations.",
"loadMode": 8199,
"originalURL": "https://github.com/ryancurrah/gomodguard",
"internal": false,
"isSlow": false,
"since": "v1.25.0"
},
{
"name": "goprintffuncname",
"desc": "Checks that printf-like functions are named with `f` at the end.",
"loadMode": 8199,
"originalURL": "https://github.com/golangci/go-printf-func-name",
"internal": false,
"isSlow": false,
"since": "v1.23.0"
},
{
"name": "gosec",
"desc": "Inspects source code for security problems",
"loadMode": 8767,
"originalURL": "https://github.com/securego/gosec",
"internal": false,
"isSlow": true,
"since": "v1.0.0"
},
{
"name": "gosmopolitan",
"desc": "Report certain i18n/l10n anti-patterns in your Go codebase",
"loadMode": 8767,
"originalURL": "https://github.com/xen0n/gosmopolitan",
"internal": false,
"isSlow": true,
"since": "v1.53.0"
},
{
"name": "govet",
"desc": "Vet examines Go source code and reports suspicious constructs. It is roughly the same as 'go vet' and uses its passes.",
"groups": [
"standard"
],
"loadMode": 8767,
"originalURL": "https://pkg.go.dev/cmd/vet",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.0.0"
},
{
"name": "grouper",
"desc": "Analyze expression groups.",
"loadMode": 8199,
"originalURL": "https://github.com/leonklingele/grouper",
"internal": false,
"isSlow": false,
"since": "v1.44.0"
},
{
"name": "iface",
"desc": "Detect the incorrect use of interfaces, helping developers avoid interface pollution.",
"loadMode": 8767,
"originalURL": "https://github.com/uudashr/iface",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.62.0"
},
{
"name": "importas",
"desc": "Enforces consistent import aliases",
"loadMode": 8767,
"originalURL": "https://github.com/julz/importas",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.38.0"
},
{
"name": "inamedparam",
"desc": "reports interfaces with unnamed method parameters",
"loadMode": 8199,
"originalURL": "https://github.com/macabu/inamedparam",
"internal": false,
"isSlow": false,
"since": "v1.55.0"
},
{
"name": "ineffassign",
"desc": "detects when assignments to existing variables are not used",
"groups": [
"standard"
],
"loadMode": 8199,
"originalURL": "https://github.com/gordonklaus/ineffassign",
"internal": false,
"isSlow": false,
"since": "v1.0.0"
},
{
"name": "interfacebloat",
"desc": "A linter that checks the number of methods inside an interface.",
"loadMode": 8199,
"originalURL": "https://github.com/sashamelentyev/interfacebloat",
"internal": false,
"isSlow": false,
"since": "v1.49.0"
},
{
"name": "intrange",
"desc": "intrange is a linter to find places where for loops could make use of an integer range.",
"loadMode": 8199,
"originalURL": "https://github.com/ckaznocha/intrange",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.57.0"
},
{
"name": "iotamixing",
"desc": "checks if iotas are being used in const blocks with other non-iota declarations.",
"loadMode": 8199,
"originalURL": "https://github.com/AdminBenni/iota-mixing",
"internal": false,
"isSlow": false,
"since": "v2.5.0"
},
{
"name": "ireturn",
"desc": "Accept Interfaces, Return Concrete Types",
"loadMode": 8767,
"originalURL": "https://github.com/butuzov/ireturn",
"internal": false,
"isSlow": true,
"since": "v1.43.0"
},
{
"name": "lll",
"desc": "Reports long lines",
"loadMode": 8199,
"internal": false,
"isSlow": false,
"since": "v1.8.0"
},
{
"name": "loggercheck",
"desc": "Checks key value pairs for common logger libraries (kitlog,klog,logr,slog,zap).",
"loadMode": 8767,
"originalURL": "https://github.com/timonwong/loggercheck",
"internal": false,
"isSlow": true,
"since": "v1.49.0"
},
{
"name": "maintidx",
"desc": "maintidx measures the maintainability index of each function.",
"loadMode": 8199,
"originalURL": "https://github.com/yagipy/maintidx",
"internal": false,
"isSlow": false,
"since": "v1.44.0"
},
{
"name": "makezero",
"desc": "Find slice declarations with non-zero initial length",
"loadMode": 8767,
"originalURL": "https://github.com/ashanbrown/makezero",
"internal": false,
"isSlow": true,
"since": "v1.34.0"
},
{
"name": "mirror",
"desc": "reports wrong mirror patterns of bytes/strings usage",
"loadMode": 8767,
"originalURL": "https://github.com/butuzov/mirror",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.53.0"
},
{
"name": "misspell",
"desc": "Finds commonly misspelled English words",
"loadMode": 8199,
"originalURL": "https://github.com/golangci/misspell",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.8.0"
},
{
"name": "musttag",
"desc": "enforce field tags in (un)marshaled structs",
"loadMode": 8767,
"originalURL": "https://github.com/go-simpler/musttag",
"internal": false,
"isSlow": true,
"since": "v1.51.0"
},
{
"name": "nakedret",
"desc": "Checks that functions with naked returns are not longer than a maximum size (can be zero).",
"loadMode": 8199,
"originalURL": "https://github.com/alexkohler/nakedret",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.19.0"
},
{
"name": "nestif",
"desc": "Reports deeply nested if statements",
"loadMode": 8199,
"originalURL": "https://github.com/nakabonne/nestif",
"internal": false,
"isSlow": false,
"since": "v1.25.0"
},
{
"name": "nilerr",
"desc": "Find the code that returns nil even if it checks that the error is not nil.",
"loadMode": 8767,
"originalURL": "https://github.com/gostaticanalysis/nilerr",
"internal": false,
"isSlow": true,
"since": "v1.38.0"
},
{
"name": "nilnesserr",
"desc": "Reports constructs that checks for err != nil, but returns a different nil value error.\nPowered by nilness and nilerr.",
"loadMode": 8767,
"originalURL": "https://github.com/alingse/nilnesserr",
"internal": false,
"isSlow": true,
"since": "v1.63.0"
},
{
"name": "nilnil",
"desc": "Checks that there is no simultaneous return of `nil` error and an invalid value.",
"loadMode": 8767,
"originalURL": "https://github.com/Antonboom/nilnil",
"internal": false,
"isSlow": true,
"since": "v1.43.0"
},
{
"name": "nlreturn",
"desc": "Checks for a new line before return and branch statements to increase code clarity",
"loadMode": 8199,
"originalURL": "https://github.com/ssgreg/nlreturn",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.30.0"
},
{
"name": "noctx",
"desc": "Detects function and method with missing usage of context.Context",
"loadMode": 8767,
"originalURL": "https://github.com/sonatard/noctx",
"internal": false,
"isSlow": true,
"since": "v1.28.0"
},
{
"name": "noinlineerr",
"desc": "Disallows inline error handling (`if err := ...; err != nil {`)",
"loadMode": 8767,
"originalURL": "https://github.com/AlwxSin/noinlineerr",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v2.2.0"
},
{
"name": "nonamedreturns",
"desc": "Reports all named returns",
"loadMode": 8767,
"originalURL": "https://github.com/firefart/nonamedreturns",
"internal": false,
"isSlow": true,
"since": "v1.46.0"
},
{
"name": "nosprintfhostport",
"desc": "Checks for misuse of Sprintf to construct a host with port in a URL.",
"loadMode": 8199,
"originalURL": "https://github.com/stbenjam/no-sprintf-host-port",
"internal": false,
"isSlow": false,
"since": "v1.46.0"
},
{
"name": "paralleltest",
"desc": "Detects missing usage of t.Parallel() method in your Go test",
"loadMode": 8767,
"originalURL": "https://github.com/kunwardeep/paralleltest",
"internal": false,
"isSlow": true,
"since": "v1.33.0"
},
{
"name": "perfsprint",
"desc": "Checks that fmt.Sprintf can be replaced with a faster alternative.",
"loadMode": 8767,
"originalURL": "https://github.com/catenacyber/perfsprint",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.55.0"
},
{
"name": "prealloc",
"desc": "Find slice declarations that could potentially be pre-allocated",
"loadMode": 8767,
"originalURL": "https://github.com/alexkohler/prealloc",
"internal": false,
"isSlow": true,
"since": "v1.19.0"
},
{
"name": "predeclared",
"desc": "find code that shadows one of Go's predeclared identifiers",
"loadMode": 8199,
"originalURL": "https://github.com/nishanths/predeclared",
"internal": false,
"isSlow": false,
"since": "v1.35.0"
},
{
"name": "promlinter",
"desc": "Check Prometheus metrics naming via promlint",
"loadMode": 8199,
"originalURL": "https://github.com/yeya24/promlinter",
"internal": false,
"isSlow": false,
"since": "v1.40.0"
},
{
"name": "protogetter",
"desc": "Reports direct reads from proto message fields when getters should be used",
"loadMode": 8767,
"originalURL": "https://github.com/ghostiam/protogetter",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.55.0"
},
{
"name": "reassign",
"desc": "Checks that package variables are not reassigned",
"loadMode": 8767,
"originalURL": "https://github.com/curioswitch/go-reassign",
"internal": false,
"isSlow": true,
"since": "v1.49.0"
},
{
"name": "recvcheck",
"desc": "checks for receiver type consistency",
"loadMode": 8767,
"originalURL": "https://github.com/raeperd/recvcheck",
"internal": false,
"isSlow": true,
"since": "v1.62.0"
},
{
"name": "revive",
"desc": "Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint.",
"loadMode": 8199,
"originalURL": "https://github.com/mgechev/revive",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.37.0"
},
{
"name": "rowserrcheck",
"desc": "checks whether Rows.Err of rows is checked successfully",
"loadMode": 8767,
"originalURL": "https://github.com/jingyugao/rowserrcheck",
"internal": false,
"isSlow": true,
"since": "v1.23.0"
},
{
"name": "sloglint",
"desc": "ensure consistent code style when using log/slog",
"loadMode": 8767,
"originalURL": "https://github.com/go-simpler/sloglint",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.55.0"
},
{
"name": "sqlclosecheck",
"desc": "Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed.",
"loadMode": 8767,
"originalURL": "https://github.com/ryanrolds/sqlclosecheck",
"internal": false,
"isSlow": true,
"since": "v1.28.0"
},
{
"name": "spancheck",
"desc": "Checks for mistakes with OpenTelemetry/Census spans.",
"loadMode": 8767,
"originalURL": "https://github.com/jjti/go-spancheck",
"internal": false,
"isSlow": true,
"since": "v1.56.0"
},
{
"name": "staticcheck",
"desc": "It's the set of rules from staticcheck.",
"groups": [
"standard"
],
"loadMode": 8767,
"originalURL": "https://github.com/dominikh/go-tools",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.0.0"
},
{
"name": "tagalign",
"desc": "check that struct tags are well aligned",
"loadMode": 8199,
"originalURL": "https://github.com/4meepo/tagalign",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.53.0"
},
{
"name": "tagliatelle",
"desc": "Checks the struct tags.",
"loadMode": 8767,
"originalURL": "https://github.com/ldez/tagliatelle",
"internal": false,
"isSlow": true,
"since": "v1.40.0"
},
{
"name": "testableexamples",
"desc": "linter checks if examples are testable (have an expected output)",
"loadMode": 8199,
"originalURL": "https://github.com/maratori/testableexamples",
"internal": false,
"isSlow": false,
"since": "v1.50.0"
},
{
"name": "testifylint",
"desc": "Checks usage of github.com/stretchr/testify.",
"loadMode": 8767,
"originalURL": "https://github.com/Antonboom/testifylint",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.55.0"
},
{
"name": "testpackage",
"desc": "linter that makes you use a separate _test package",
"loadMode": 8199,
"originalURL": "https://github.com/maratori/testpackage",
"internal": false,
"isSlow": false,
"since": "v1.25.0"
},
{
"name": "thelper",
"desc": "thelper detects tests helpers which do not start with the t.Helper() method.",
"loadMode": 8767,
"originalURL": "https://github.com/kulti/thelper",
"internal": false,
"isSlow": true,
"since": "v1.34.0"
},
{
"name": "tparallel",
"desc": "tparallel detects inappropriate usage of t.Parallel() method in your Go test codes.",
"loadMode": 8767,
"originalURL": "https://github.com/moricho/tparallel",
"internal": false,
"isSlow": true,
"since": "v1.32.0"
},
{
"name": "typecheck",
"desc": "Like the front-end of a Go compiler, parses and type-checks Go code",
"loadMode": 8199,
"internal": true,
"isSlow": false,
"since": "v1.3.0"
},
{
"name": "unconvert",
"desc": "Remove unnecessary type conversions",
"loadMode": 8767,
"originalURL": "https://github.com/mdempsky/unconvert",
"internal": false,
"isSlow": true,
"since": "v1.0.0"
},
{
"name": "unparam",
"desc": "Reports unused function parameters",
"loadMode": 8767,
"originalURL": "https://github.com/mvdan/unparam",
"internal": false,
"isSlow": true,
"since": "v1.9.0"
},
{
"name": "unqueryvet",
"desc": "detects SELECT * in SQL queries and SQL builders, preventing performance issues and encouraging explicit column selection",
"loadMode": 8199,
"originalURL": "https://github.com/MirrexOne/unqueryvet",
"internal": false,
"isSlow": false,
"since": "v2.5.0"
},
{
"name": "unused",
"desc": "Checks Go code for unused constants, variables, functions and types",
"groups": [
"standard"
],
"loadMode": 8767,
"originalURL": "https://github.com/dominikh/go-tools/tree/HEAD/unused",
"internal": false,
"isSlow": true,
"doesChangeTypes": true,
"since": "v1.20.0"
},
{
"name": "usestdlibvars",
"desc": "A linter that detect the possibility to use variables/constants from the Go standard library.",
"loadMode": 8199,
"originalURL": "https://github.com/sashamelentyev/usestdlibvars",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.48.0"
},
{
"name": "usetesting",
"desc": "Reports uses of functions with replacement inside the testing package.",
"loadMode": 8767,
"originalURL": "https://github.com/ldez/usetesting",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v1.63.0"
},
{
"name": "varnamelen",
"desc": "checks that the length of a variable's name matches its scope",
"loadMode": 8767,
"originalURL": "https://github.com/blizzy78/varnamelen",
"internal": false,
"isSlow": true,
"since": "v1.43.0"
},
{
"name": "wastedassign",
"desc": "Finds wasted assignment statements",
"loadMode": 8767,
"originalURL": "https://github.com/sanposhiho/wastedassign",
"internal": false,
"isSlow": true,
"since": "v1.38.0"
},
{
"name": "whitespace",
"desc": "Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc.",
"loadMode": 8199,
"originalURL": "https://github.com/ultraware/whitespace",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.19.0"
},
{
"name": "wrapcheck",
"desc": "Checks that errors returned from external packages are wrapped",
"loadMode": 8767,
"originalURL": "https://github.com/tomarrell/wrapcheck",
"internal": false,
"isSlow": true,
"since": "v1.32.0"
},
{
"name": "wsl",
"desc": "add or remove empty lines",
"loadMode": 8199,
"originalURL": "https://github.com/bombsimon/wsl",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.20.0",
"deprecation": {
"since": "v2.2.0",
"message": "new major version.",
"replacement": "wsl_v5"
}
},
{
"name": "wsl_v5",
"desc": "add or remove empty lines",
"loadMode": 8767,
"originalURL": "https://github.com/bombsimon/wsl",
"internal": false,
"canAutoFix": true,
"isSlow": true,
"since": "v2.2.0"
},
{
"name": "zerologlint",
"desc": "Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg`",
"loadMode": 8767,
"originalURL": "https://github.com/ykadowak/zerologlint",
"internal": false,
"isSlow": true,
"since": "v1.53.0"
},
{
"name": "nolintlint",
"desc": "Reports ill-formed or insufficient nolint directives",
"loadMode": 8199,
"originalURL": "https://github.com/golangci/golangci-lint/tree/HEAD/pkg/golinters/nolintlint/internal",
"internal": false,
"canAutoFix": true,
"isSlow": false,
"since": "v1.26.0"
}
]
================================================
FILE: docs/data/thanks.json
================================================
[
{
"name": "4meepo",
"linters": [
"tagalign"
],
"profile": "https://github.com/sponsors/4meepo",
"avatar": "https://github.com/4meepo.png"
},
{
"name": "Abirdcfly",
"linters": [
"dupword"
],
"profile": "https://github.com/sponsors/Abirdcfly",
"avatar": "https://github.com/Abirdcfly.png"
},
{
"name": "AdminBenni",
"linters": [
"iotamixing"
],
"profile": "https://github.com/sponsors/AdminBenni",
"avatar": "https://github.com/AdminBenni.png"
},
{
"name": "alecthomas",
"linters": [
"gochecksumtype"
],
"profile": "https://github.com/sponsors/alecthomas",
"avatar": "https://github.com/alecthomas.png"
},
{
"name": "alexkohler",
"linters": [
"dogsled",
"nakedret",
"prealloc"
],
"profile": "https://github.com/sponsors/alexkohler",
"avatar": "https://github.com/alexkohler.png"
},
{
"name": "alingse",
"linters": [
"asasalint",
"nilnesserr"
],
"profile": "https://github.com/sponsors/alingse",
"avatar": "https://github.com/alingse.png"
},
{
"name": "AlwxSin",
"linters": [
"noinlineerr"
],
"profile": "https://github.com/sponsors/AlwxSin",
"avatar": "https://github.com/AlwxSin.png"
},
{
"name": "Antonboom",
"linters": [
"errname",
"nilnil",
"testifylint"
],
"profile": "https://github.com/sponsors/Antonboom",
"avatar": "https://github.com/Antonboom.png"
},
{
"name": "ashanbrown",
"linters": [
"forbidigo",
"makezero"
],
"profile": "https://github.com/sponsors/ashanbrown",
"avatar": "https://github.com/ashanbrown.png"
},
{
"name": "babakks",
"linters": [
"godoclint"
],
"profile": "https://github.com/sponsors/babakks",
"avatar": "https://github.com/babakks.png"
},
{
"name": "bkielbasa",
"linters": [
"cyclop"
],
"profile": "https://github.com/sponsors/bkielbasa",
"avatar": "https://github.com/bkielbasa.png"
},
{
"name": "blizzy78",
"linters": [
"varnamelen"
],
"profile": "https://github.com/sponsors/blizzy78",
"avatar": "https://github.com/blizzy78.png"
},
{
"name": "bombsimon",
"linters": [
"wsl",
"wsl_v5"
],
"profile": "https://github.com/sponsors/bombsimon",
"avatar": "https://github.com/bombsimon.png"
},
{
"name": "bosi",
"linters": [
"decorder"
],
"profile": "https://gitlab.com/bosi",
"avatar": "https://github.com/bosix.png"
},
{
"name": "breml",
"linters": [
"bidichk",
"errchkjson"
],
"profile": "https://github.com/sponsors/breml",
"avatar": "https://github.com/breml.png"
},
{
"name": "butuzov",
"linters": [
"ireturn",
"mirror"
],
"profile": "https://github.com/sponsors/butuzov",
"avatar": "https://github.com/butuzov.png"
},
{
"name": "catenacyber",
"linters": [
"perfsprint"
],
"profile": "https://github.com/sponsors/catenacyber",
"avatar": "https://github.com/catenacyber.png"
},
{
"name": "charithe",
"linters": [
"durationcheck"
],
"profile": "https://github.com/sponsors/charithe",
"avatar": "https://github.com/charithe.png"
},
{
"name": "chokoswitch",
"linters": [
"reassign"
],
"profile": "https://github.com/sponsors/chokoswitch",
"avatar": "https://github.com/chokoswitch.png"
},
{
"name": "ckaznocha",
"linters": [
"intrange"
],
"profile": "https://github.com/sponsors/ckaznocha",
"avatar": "https://github.com/ckaznocha.png"
},
{
"name": "client9",
"linters": [
"misspell"
],
"profile": "https://github.com/sponsors/client9",
"avatar": "https://github.com/client9.png"
},
{
"name": "Crocmagnon",
"linters": [
"arangolint",
"fatcontext"
],
"profile": "https://github.com/sponsors/Crocmagnon",
"avatar": "https://github.com/Crocmagnon.png"
},
{
"name": "daixiang0",
"linters": [
"gci"
],
"profile": "https://github.com/sponsors/daixiang0",
"avatar": "https://github.com/daixiang0.png"
},
{
"name": "denis-tingaikin",
"linters": [
"goheader"
],
"profile": "https://github.com/sponsors/denis-tingaikin",
"avatar": "https://github.com/denis-tingaikin.png"
},
{
"name": "dixonwille",
"linters": [
"depguard"
],
"profile": "https://github.com/sponsors/dixonwille",
"avatar": "https://github.com/dixonwille.png"
},
{
"name": "Djarvur",
"linters": [
"err113"
],
"profile": "https://github.com/sponsors/Djarvur",
"avatar": "https://github.com/Djarvur.png"
},
{
"name": "dominikh",
"linters": [
"staticcheck",
"unused"
],
"profile": "https://github.com/sponsors/dominikh",
"avatar": "https://github.com/dominikh.png"
},
{
"name": "firefart",
"linters": [
"nonamedreturns"
],
"profile": "https://github.com/sponsors/firefart",
"avatar": "https://github.com/firefart.png"
},
{
"name": "fzipp",
"linters": [
"gocyclo"
],
"profile": "https://github.com/sponsors/fzipp",
"avatar": "https://github.com/fzipp.png"
},
{
"name": "ghostiam",
"linters": [
"protogetter"
],
"profile": "https://github.com/sponsors/ghostiam",
"avatar": "https://github.com/ghostiam.png"
},
{
"name": "go-critic",
"linters": [
"gocritic"
],
"profile": "https://github.com/sponsors/go-critic",
"avatar": "https://github.com/go-critic.png"
},
{
"name": "golang",
"linters": [
"gofmt",
"goimports",
"modernize",
"govet"
],
"profile": "https://github.com/sponsors/golang",
"avatar": "https://github.com/golang.png"
},
{
"name": "gordonklaus",
"linters": [
"ineffassign"
],
"profile": "https://github.com/sponsors/gordonklaus",
"avatar": "https://github.com/gordonklaus.png"
},
{
"name": "jgautheron",
"linters": [
"goconst"
],
"profile": "https://github.com/sponsors/jgautheron",
"avatar": "https://github.com/jgautheron.png"
},
{
"name": "jingyugao",
"linters": [
"rowserrcheck"
],
"profile": "https://github.com/sponsors/jingyugao",
"avatar": "https://github.com/jingyugao.png"
},
{
"name": "jirfag",
"linters": [
"goprintffuncname"
],
"profile": "https://github.com/sponsors/jirfag",
"avatar": "https://github.com/jirfag.png"
},
{
"name": "jjti",
"linters": [
"spancheck"
],
"profile": "https://github.com/sponsors/jjti",
"avatar": "https://github.com/jjti.png"
},
{
"name": "julz",
"linters": [
"importas"
],
"profile": "https://github.com/sponsors/julz",
"avatar": "https://github.com/julz.png"
},
{
"name": "karamaru-alpha",
"linters": [
"copyloopvar"
],
"profile": "https://github.com/sponsors/karamaru-alpha",
"avatar": "https://github.com/karamaru-alpha.png"
},
{
"name": "kisielk",
"linters": [
"errcheck"
],
"profile": "https://github.com/sponsors/kisielk",
"avatar": "https://github.com/kisielk.png"
},
{
"name": "kkHAIKE",
"linters": [
"contextcheck"
],
"profile": "https://github.com/sponsors/kkHAIKE",
"avatar": "https://github.com/kkHAIKE.png"
},
{
"name": "kulti",
"linters": [
"thelper"
],
"profile": "https://github.com/sponsors/kulti",
"avatar": "https://github.com/kulti.png"
},
{
"name": "kunwardeep",
"linters": [
"paralleltest"
],
"profile": "https://github.com/sponsors/kunwardeep",
"avatar": "https://github.com/kunwardeep.png"
},
{
"name": "lasiar",
"linters": [
"canonicalheader"
],
"profile": "https://github.com/sponsors/lasiar",
"avatar": "https://github.com/lasiar.png"
},
{
"name": "ldez",
"linters": [
"exptostd",
"gomoddirectives",
"tagliatelle",
"usetesting"
],
"profile": "https://github.com/sponsors/ldez",
"avatar": "https://github.com/ldez.png"
},
{
"name": "leighmcculloch",
"linters": [
"gocheckcompilerdirectives",
"gochecknoglobals"
],
"profile": "https://github.com/sponsors/leighmcculloch",
"avatar": "https://github.com/leighmcculloch.png"
},
{
"name": "leonklingele",
"linters": [
"grouper"
],
"profile": "https://github.com/sponsors/leonklingele",
"avatar": "https://github.com/leonklingele.png"
},
{
"name": "macabu",
"linters": [
"inamedparam"
],
"profile": "https://github.com/sponsors/macabu",
"avatar": "https://github.com/macabu.png"
},
{
"name": "manuelarte",
"linters": [
"embeddedstructfieldcheck",
"funcorder"
],
"profile": "https://github.com/sponsors/manuelarte",
"avatar": "https://github.com/manuelarte.png"
},
{
"name": "maratori",
"linters": [
"testableexamples",
"testpackage"
],
"profile": "https://github.com/sponsors/maratori",
"avatar": "https://github.com/maratori.png"
},
{
"name": "matoous",
"linters": [
"godox"
],
"profile": "https://github.com/sponsors/matoous",
"avatar": "https://github.com/matoous.png"
},
{
"name": "mdempsky",
"linters": [
"unconvert"
],
"profile": "https://github.com/sponsors/mdempsky",
"avatar": "https://github.com/mdempsky.png"
},
{
"name": "mgechev",
"linters": [
"revive"
],
"profile": "https://github.com/sponsors/mgechev",
"avatar": "https://github.com/mgechev.png"
},
{
"name": "mibk",
"linters": [
"dupl"
],
"profile": "https://github.com/sponsors/mibk",
"avatar": "https://github.com/mibk.png"
},
{
"name": "MirrexOne",
"linters": [
"unqueryvet"
],
"profile": "https://github.com/sponsors/MirrexOne",
"avatar": "https://github.com/MirrexOne.png"
},
{
"name": "moricho",
"linters": [
"tparallel"
],
"profile": "https://github.com/sponsors/moricho",
"avatar": "https://github.com/moricho.png"
},
{
"name": "mvdan",
"linters": [
"gofumpt",
"unparam"
],
"profile": "https://github.com/sponsors/mvdan",
"avatar": "https://github.com/mvdan.png"
},
{
"name": "nakabonne",
"linters": [
"nestif"
],
"profile": "https://github.com/sponsors/nakabonne",
"avatar": "https://github.com/nakabonne.png"
},
{
"name": "nishanths",
"linters": [
"exhaustive",
"predeclared"
],
"profile": "https://github.com/sponsors/nishanths",
"avatar": "https://github.com/nishanths.png"
},
{
"name": "nunnatsa",
"linters": [
"ginkgolinter"
],
"profile": "https://github.com/sponsors/nunnatsa",
"avatar": "https://github.com/nunnatsa.png"
},
{
"name": "polyfloyd",
"linters": [
"errorlint"
],
"profile": "https://codeberg.org/polyfloyd",
"avatar": "https://codeberg.org/polyfloyd.png"
},
{
"name": "raeperd",
"linters": [
"recvcheck"
],
"profile": "https://github.com/sponsors/raeperd",
"avatar": "https://github.com/raeperd.png"
},
{
"name": "ryancurrah",
"linters": [
"gomodguard"
],
"profile": "https://github.com/sponsors/ryancurrah",
"avatar": "https://github.com/ryancurrah.png"
},
{
"name": "ryanrolds",
"linters": [
"sqlclosecheck"
],
"profile": "https://github.com/sponsors/ryanrolds",
"avatar": "https://github.com/ryanrolds.png"
},
{
"name": "sanposhiho",
"linters": [
"wastedassign"
],
"profile": "https://github.com/sponsors/sanposhiho",
"avatar": "https://github.com/sanposhiho.png"
},
{
"name": "sashamelentyev",
"linters": [
"interfacebloat",
"usestdlibvars"
],
"profile": "https://github.com/sponsors/sashamelentyev",
"avatar": "https://github.com/sashamelentyev.png"
},
{
"name": "securego",
"linters": [
"gosec"
],
"profile": "https://github.com/sponsors/securego",
"avatar": "https://github.com/securego.png"
},
{
"name": "segmentio",
"linters": [
"golines"
],
"profile": "https://github.com/sponsors/segmentio",
"avatar": "https://github.com/segmentio.png"
},
{
"name": "sivchari",
"linters": [
"containedctx"
],
"profile": "https://github.com/sponsors/sivchari",
"avatar": "https://github.com/sivchari.png"
},
{
"name": "sonatard",
"linters": [
"noctx"
],
"profile": "https://github.com/sponsors/sonatard",
"avatar": "https://github.com/sonatard.png"
},
{
"name": "ssgreg",
"linters": [
"nlreturn"
],
"profile": "https://github.com/sponsors/ssgreg",
"avatar": "https://github.com/ssgreg.png"
},
{
"name": "stbenjam",
"linters": [
"nosprintfhostport"
],
"profile": "https://github.com/sponsors/stbenjam",
"avatar": "https://github.com/stbenjam.png"
},
{
"name": "swaggo",
"linters": [
"swaggo"
],
"profile": "https://github.com/sponsors/swaggo",
"avatar": "https://github.com/swaggo.png"
},
{
"name": "tenntenn",
"linters": [
"forcetypeassert",
"nilerr"
],
"profile": "https://github.com/sponsors/tenntenn",
"avatar": "https://github.com/tenntenn.png"
},
{
"name": "tetafro",
"linters": [
"godot"
],
"profile": "https://github.com/sponsors/tetafro",
"avatar": "https://github.com/tetafro.png"
},
{
"name": "timakin",
"linters": [
"bodyclose"
],
"profile": "https://github.com/sponsors/timakin",
"avatar": "https://github.com/timakin.png"
},
{
"name": "timonwong",
"linters": [
"loggercheck"
],
"profile": "https://github.com/sponsors/timonwong",
"avatar": "https://github.com/timonwong.png"
},
{
"name": "tmzane",
"linters": [
"musttag",
"sloglint"
],
"profile": "https://github.com/sponsors/tmzane",
"avatar": "https://github.com/tmzane.png"
},
{
"name": "tomarrell",
"linters": [
"wrapcheck"
],
"profile": "https://github.com/sponsors/tomarrell",
"avatar": "https://github.com/tomarrell.png"
},
{
"name": "tommy-muehle",
"linters": [
"mnd"
],
"profile": "https://github.com/sponsors/tommy-muehle",
"avatar": "https://github.com/tommy-muehle.png"
},
{
"name": "ultraware",
"linters": [
"funlen",
"whitespace"
],
"profile": "https://github.com/sponsors/ultraware",
"avatar": "https://github.com/ultraware.png"
},
{
"name": "uudashr",
"linters": [
"gocognit",
"iface"
],
"profile": "https://github.com/sponsors/uudashr",
"avatar": "https://github.com/uudashr.png"
},
{
"name": "xen0n",
"linters": [
"gosmopolitan"
],
"profile": "https://github.com/sponsors/xen0n",
"avatar": "https://github.com/xen0n.png"
},
{
"name": "xobotyi",
"linters": [
"exhaustruct"
],
"profile": "https://github.com/sponsors/xobotyi",
"avatar": "https://github.com/xobotyi.png"
},
{
"name": "yagipy",
"linters": [
"maintidx"
],
"profile": "https://github.com/sponsors/yagipy",
"avatar": "https://github.com/yagipy.png"
},
{
"name": "yeya24",
"linters": [
"promlinter"
],
"profile": "https://github.com/sponsors/yeya24",
"avatar": "https://github.com/yeya24.png"
},
{
"name": "ykadowak",
"linters": [
"zerologlint"
],
"profile": "https://github.com/sponsors/ykadowak",
"avatar": "https://github.com/ykadowak.png"
}
]
================================================
FILE: docs/go.mod
================================================
module github.com/golangci/docs
go 1.24.0
require github.com/imfing/hextra v0.11.0 // indirect
================================================
FILE: docs/go.sum
================================================
github.com/imfing/hextra v0.11.0 h1:2HswtfKD/TFg2VWp0hvsH5F3/WoEugiz8s3n2JFouqY=
github.com/imfing/hextra v0.11.0/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
================================================
FILE: docs/golangci-lint.tape
================================================
Output docs/static/images/demo.gif
# NOTE: it should be run at the root of the repository.
# vhs docs/golangci-lint.tape
Require golangci-lint
Set Shell zsh
Set Theme Dracula
Set FontSize 25
Set Width 2000
Set Height 900
Set WindowBar Colorful
Set WindowBarSize 50
Set Padding 20
Set MarginFill "#17afc2"
Set Margin 20
Set BorderRadius 30
Type "golangci-lint run" Sleep 500ms Enter
Sleep 2s
Sleep 1s
# VHS documentation
# https://github.com/charmbracelet/vhs
#
# Output:
# Output .gif Create a GIF output at the given
# Output .mp4 Create an MP4 output at the given
# Output .webm Create a WebM output at the given
#
# Require:
# Require Ensure a program is on the $PATH to proceed
#
# Settings:
# Set FontSize Set the font size of the terminal
# Set FontFamily Set the font family of the terminal
# Set Height Set the height of the terminal
# Set Width Set the width of the terminal
# Set LetterSpacing Set the font letter spacing (tracking)
# Set LineHeight Set the font line height
# Set LoopOffset % Set the starting frame offset for the GIF loop
# Set Theme Set the theme of the terminal
# Set Padding Set the padding of the terminal
# Set Framerate Set the framerate of the recording
# Set PlaybackSpeed Set the playback speed of the recording
# Set MarginFill Set the file or color the margin will be filled with.
# Set Margin Set the size of the margin. Has no effect if MarginFill isn't set.
# Set BorderRadius Set terminal border radius, in pixels.
# Set WindowBar Set window bar type. (one of: Rings, RingsRight, Colorful, ColorfulRight)
# Set WindowBarSize Set window bar size, in pixels. Default is 40.
# Set TypingSpeed Set the typing speed of the terminal. Default is 50ms.
#
# Sleep:
# Sleep Sleep for a set amount of in seconds
#
# Type:
# Type[@] "" Type into the terminal with a
# delay between each character
#
# Keys:
# Escape[@] [number] Press the Escape key
# Backspace[@] [number] Press the Backspace key
# Delete[@] [number] Press the Delete key
# Insert[@] [number] Press the Insert key
# Down[@] [number] Press the Down key
# Enter[@] [number] Press the Enter key
# Space[@] [number] Press the Space key
# Tab[@] [number] Press the Tab key
# Left[@] [number] Press the Left Arrow key
# Right[@] [number] Press the Right Arrow key
# Up[@] [number] Press the Up Arrow key
# Down[@] [number] Press the Down Arrow key
# PageUp[@] [number] Press the Page Up key
# PageDown[@] [number] Press the Page Down key
# Ctrl+ Press the Control key + (e.g. Ctrl+C)
#
# Display:
# Hide Hide the subsequent commands from the output
# Show Show the subsequent commands in the output
================================================
FILE: docs/hugo.yaml
================================================
baseURL: https://golangci-lint.run
languageCode: en-us
title: Golangci-lint
enableRobotsTXT: true
enableGitInfo: true
markup:
highlight:
noClasses: false
goldmark:
renderer:
unsafe: true
extensions:
passthrough:
delimiters:
block: [['\[', '\]'], ['$$', '$$']]
inline: [['\(', '\)']]
enable: true
enableInlineShortcodes: true
defaultContentLanguage: en
module:
hugoVersion:
extended: true
min: "0.148.1"
imports:
- path: github.com/imfing/hextra
outputs:
home: [HTML]
page: [HTML]
section: [HTML, RSS]
menu:
main:
- name: Documentation
pageRef: /docs
weight: 1
- identifier: donate
name: "Support us"
pageRef: /docs/donate/
weight: 2
params:
icon: "heart-red"
- identifier: linters
name: Linters
pageRef: /docs/linters/
weight: 3
- name: Formatters
pageRef: /docs/formatters/
weight: 4
- name: Search
weight: 5
params:
type: search
- name: Theme Toggle
weight: 6
params:
type: theme-toggle
- name: GitHub
weight: 7
url: "https://github.com/golangci/golangci-lint"
params:
icon: github
sidebar:
- identifier: more
name: More
params:
type: separator
weight: 2
- identifier: doc-v1
name: "Documentation v1 ↗"
url: "https://golangci.github.io/legacy-v1-doc/"
weight: 3
params:
description: Golangci-lint is a fast linters runner for Go.
banner:
key: 'banner-2025-001'
message: |
If golangci-lint is useful for you, please consider [supporting us](/docs/donate/)!
You are the only one who can make a difference!
navbar:
displayTitle: true
displayLogo: true
logo:
path: images/logo-circle.svg
dark: images/logo-nocircle.svg
width: wide
theme:
# light | dark | system
default: system
displayToggle: true
footer:
enable: true
displayCopyright: false
displayPoweredBy: true
width: wide
links:
- title: Bluesky
url: "https://bsky.app/profile/golangci-lint.run"
icon: bluesky
- title: Mastodon
url: "https://fosstodon.org/@golangcilint"
icon: mastodon
- title: Twitter
url: "https://twitter.com/golangci"
icon: twitter
- title: Slack
url: "https://gophers.slack.com/archives/CS0TBRKPC"
icon: slack
- title: GitHub
url: "https://github.com/golangci/golangci-lint"
icon: github
# Display the last modification date
displayUpdatedDate: true
dateFormat: "2006-01-02 03:04:05"
# Search
# flexsearch is enabled by default
search:
enable: true
type: flexsearch
flexsearch:
# index page by: content | summary | heading | title
index: content
# full | forward | reverse | strict
# https://github.com/nextapps-de/flexsearch/#tokenizer-prefix-search
tokenize: forward
editURL:
enable: true
base: "https://github.com/golangci/golangci-lint/edit/main/docs/content"
blog:
list:
displayTags: true
# date | lastmod | publishDate | title | weight
sortBy: date
sortOrder: desc # or "asc"
# Pagination
pagerSize: 20
article:
displayPagination: true
toc:
displayTags: true
highlight:
copy:
enable: true
# hover | always
display: hover
page:
# full (100%), wide (90rem), normal (80rem)
width: full
tabs:
sync: false
================================================
FILE: docs/i18n/en.yaml
================================================
copyright: "© 2025 Golangci"
================================================
FILE: docs/layouts/404.html
================================================
{{ define "main" }}
{{ end }}
================================================
FILE: docs/layouts/_partials/custom/head-end.html
================================================
================================================
FILE: docs/layouts/_partials/footer.html
================================================
{{- /* Modified version of https://github.com/imfing/hextra/blob/v0.10.0/layouts/_partials/footer.html */ -}}
{{- /* This file overrides the footer partial of the theme */ -}}
{{- $enableFooterSwitches := .Scratch.Get "enableFooterSwitches" | default false -}}
{{- $displayThemeToggle := site.Params.theme.displayToggle | default true -}}
{{- $footerSwitchesVisible := and $enableFooterSwitches (or hugo.IsMultilingual $displayThemeToggle) -}}
{{- $copyrightSectionVisible := or (.Site.Params.footer.displayPoweredBy | default true) .Site.Params.footer.displayCopyright -}}
{{- $copyright := (T "copyright") | default "© 2024 Hextra." -}}
{{- $poweredBy := (T "poweredBy") | default "Powered by Hextra" -}}
{{- define "theme-credit" -}}
{{- . | markdownify -}}
{{- if strings.Contains . "Hextra" -}}
{{- partial "utils/icon.html" (dict "name" "hextra" "attributes" `height=1em class="hx:inline-block hx:ltr:ml-1 hx:rtl:mr-1 hx:align-[-2.5px]"`) -}}
{{- end -}}
{{- end -}}
================================================
FILE: docs/layouts/_partials/golangci/items/compare-versions.html
================================================
{{- /*
Compares two versions.
@param {string} a Version A
@param {string} b Version B
@returns {boolean}
@example {{ partial "golangci/items/compare-versions" (dict "a" "v1.2.3" "b" "v1.2.4") }}
*/ -}}
{{- $aVersion := path.Dir (replace .a "." "/") -}}
{{- $bVersion := path.Dir (replace .b "." "/") -}}
{{- return (eq $aVersion $bVersion) -}}
================================================
FILE: docs/layouts/_partials/golangci/items/format-description.html
================================================
{{- /*
Formats a item (linter/formatter) description.
@param {string} (positional parameter 0) Description
@returns {string}
@example {{ partial "golangci/items/format-description" "message" }}
*/ -}}
{{- $desc := . -}}
{{- $desc = strings.FirstUpper $desc -}}
{{- if not (hasSuffix $desc ".") -}}
{{- $desc = print $desc "." -}}
{{- end -}}
{{- return $desc -}}
================================================
FILE: docs/layouts/_partials/golangci/items/tag.html
================================================
{{- /*
Creates tag information for an item (linter/formatter).
@param {string} (positional parameter 0) Description
@returns {map[tag: string, tagType: string]}
@example {{ partial "golangci/items/tag" (dict "gcilVersion" "v1.2.3" "item" .) }}
*/ -}}
{{- $gcilVersion := .gcilVersion -}}
{{- $item := .item -}}
{{- $tag := newScratch -}}
{{- if $item.deprecation -}}
{{- $replacement := "" -}}
{{- if $item.deprecation.replacement -}}
{{- $replacement = print " Use `" $item.deprecation.replacement "` instead." -}}
{{- end -}}
{{- $tag.SetInMap "options" "subtitle" (print (strings.FirstUpper $item.deprecation.message) $replacement) -}}
{{- $tag.SetInMap "options" "tag" (print "Deprecated since " $item.deprecation.since) -}}
{{- $tag.SetInMap "options" "tagType" "error" -}}
{{- else if (partial "golangci/items/compare-versions" (dict "a" $gcilVersion "b" $item.since)) -}}
{{- $tag.SetInMap "options" "tag" "New" -}}
{{- $tag.SetInMap "options" "tagType" "warning" -}}
{{- else if $item.canAutoFix -}}
{{- $tag.SetInMap "options" "tag" "Autofix" -}}
{{- $tag.SetInMap "options" "tagType" "info" -}}
{{- end -}}
{{- return ($tag.Get "options") -}}
================================================
FILE: docs/layouts/_partials/shortcodes/badge.html
================================================
{{- /* Modified version of https://github.com/imfing/hextra/blob/v0.11.0/layouts/_partials/shortcodes/badge.html */ -}}
{{- /* This file overrides the badge partial of the theme */ -}}
{{- $content := .content -}}
{{- $color := .color | default .type | default "" -}}{{- /* Compatibility with previous parameter. */ -}}
{{- $class := .class | default "" -}}
{{- $border := .border | default false -}}
{{- $icon := .icon | default "" -}}
{{- /* Compatibility with previous names. */ -}}
{{- $mapping := (dict
"default" "gray"
"tip" "green"
"info" "blue"
"warning" "yellow"
"error" "red"
"important" "purple"
)
-}}
{{- $color = index $mapping $color | default $color | default "gray" -}}
{{- $styleClass := newScratch -}}
{{- $styleClass.Set "gray" "hx:text-gray-600 hx:bg-gray-100 hx:dark:bg-neutral-800 hx:dark:text-neutral-200 hx:border-gray-200 hx:dark:border-neutral-700" -}}
{{- $styleClass.Set "purple" "hx:border-purple-200 hx:bg-purple-100 hx:text-purple-900 hx:dark:border-purple-200/30 hx:dark:bg-purple-900/30 hx:dark:text-purple-200" -}}
{{- $styleClass.Set "indigo" "hx:border-indigo-200 hx:bg-indigo-100 hx:text-indigo-900 hx:dark:border-indigo-200/30 hx:dark:bg-indigo-900/30 hx:dark:text-indigo-200" -}}
{{- $styleClass.Set "blue" "hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200" -}}
{{- $styleClass.Set "green" "hx:border-green-200 hx:bg-green-100 hx:text-green-900 hx:dark:border-green-200/30 hx:dark:bg-green-900/30 hx:dark:text-green-200" -}}
{{- $styleClass.Set "yellow" "hx:border-yellow-100 hx:bg-yellow-50 hx:text-yellow-900 hx:dark:border-yellow-200/30 hx:dark:bg-yellow-700/30 hx:dark:text-yellow-200" -}}
{{- $styleClass.Set "orange" "hx:border-orange-100 hx:bg-orange-50 hx:text-orange-800 hx:dark:border-orange-400/30 hx:dark:bg-orange-400/20 hx:dark:text-orange-300" -}}
{{- $styleClass.Set "amber" "hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200" -}}
{{- $styleClass.Set "red" "hx:border-red-200 hx:bg-red-100 hx:text-red-900 hx:dark:border-red-200/30 hx:dark:bg-red-900/30 hx:dark:text-red-200" -}}
{{- $borderClass := cond (eq $border true) "hx:border" "" -}}
{{- $badgeClass := or ($styleClass.Get $color) ($styleClass.Get "gray") -}}
{{- /* Custom section to handle icon-only badges. */ -}}
{{- $iconOnly := hasPrefix $color "icon-only" -}}
{{- if $iconOnly -}}
{{- $icon = (strings.TrimPrefix "icon-only:" $color) -}}
{{- $borderClass = "" -}}
{{- $badgeClass = "hx:p-2" -}}
{{- end -}}
{{- /* Custom section to set attributes. */ -}}
{{- $data := .data | default "" -}}
{{- $attributes := slice -}}
{{- if $iconOnly -}}
{{- $attributes = $attributes | append (printf `title="%s"` $content) -}}
{{- end -}}
{{- if $data -}}
{{- $attributes = $attributes | append (printf `data-badge="%s"` $data) -}}
{{- end -}}
{{- /* Strip trailing newline. */ -}}
================================================
FILE: docs/layouts/_partials/shortcodes/cards.html
================================================
{{/* Modified version of https://github.com/imfing/hextra/blob/v0.10.0/layouts/_partials/shortcodes/cards.html */}}
{{- /* This file overrides the details shortcode of the theme */ -}}
{{- $cols := .cols | default 3 -}}
{{- $content := .content -}}
{{- $class := .class | default "hextra-cards" -}}
{{- $content -}}
================================================
FILE: docs/layouts/_shortcodes/cards.html
================================================
{{- /* Modified version of https://github.com/imfing/hextra/blob/v0.10.0/layouts/_shortcodes/cards.html */ -}}
{{- /* This file overrides the cards shortcode of the theme */ -}}
{{- /*
A shortcode for creating cards.
@param {string} cols The number of columns.
@param {string} class The class of the cards.
@example {{< cards cols="3" >}}{{< /cards >}}
*/ -}}
{{- $cols := .Get "cols" | default 3 -}}
{{- $class := .Get "class" | default "hextra-cards" -}}
{{- partial "shortcodes/cards" (dict "cols" $cols "class" $class "content" .Inner) -}}
================================================
FILE: docs/layouts/_shortcodes/details.html
================================================
{{- /* Modified version of https://github.com/imfing/hextra/blob/v0.10.0/layouts/_shortcodes/details.html */ -}}
{{- /* This file overrides the details shortcode of the theme */ -}}
{{- $title := .Get "title" | default "" -}}
{{- $closed := eq (.Get "closed") "true" | default false -}}
{{ $title | markdownify }}
{{ .InnerDeindent | markdownify }}
================================================
FILE: docs/layouts/_shortcodes/golangci/authors.html
================================================
{{- /*
Creates a card for each author of a linter/formatter.
@example {{< golangci/authors >}}
*/ -}}
{{- $thanks := index $.Site.Data.thanks -}}
{{- range $thanks }}
{{ $v := slice }}
{{- range .linters -}}
{{- $v = $v | append (printf "%s" .) -}}
{{- end -}}
{{- partial "shortcodes/card" (dict
"page" .Page
"link" .profile
"title" .name
"subtitle" (delimit $v " ")
"image" .avatar
)
-}}
{{- end -}}
================================================
FILE: docs/layouts/_shortcodes/golangci/button.html
================================================
{{- $link := .Get "link" -}}
{{- $text := .Get "text" -}}
{{- $style := .Get "style" -}}
{{- $external := hasPrefix $link "http" -}}
{{- $href := cond (hasPrefix $link "/") ($link | relURL) $link -}}
================================================
FILE: docs/layouts/_shortcodes/golangci/cli-output.html
================================================
{{- /*
Creates a code block with the output of the CLI.
@param {string} cmd The name of the command.
@param {string} section The name of the section inside the data file.
@example {{% golangci/cli-output %}}
@example {{% golangci/cli-output cmd="foo" %}}
@example {{% golangci/cli-output section="sectionName" cmd="foo bar" %}}
*/ -}}
{{- $cmdName := .Get "cmd" -}}
{{- $section := .Get "section" -}}
{{- $cliData := index $.Site.Data.cli_help -}}
```console
{{ if $section -}}
$ golangci-lint {{ $cmdName }}
{{- else -}}
{{- $section = print (or $cmdName "root") "Output" -}}
$ golangci-lint{{ if $cmdName }} {{ $cmdName }}{{ end }} -h
{{- end }}
{{ index $cliData $section | safeHTML }}
```
================================================
FILE: docs/layouts/_shortcodes/golangci/configuration-file-snippet.html
================================================
{{- /*
Creates a code block with the contents of a configuration file section.
@param {string} section The name of the section inside the data file.
@returns {string}
@example {{% golangci/configuration-file-snippet section="sectionName" %}}
*/ -}}
{{- $sectionName := .Get "section" -}}
{{- $file := index $.Site.Data.configuration_file -}}
```yaml
{{ index $file $sectionName | safeHTML }}
```
================================================
FILE: docs/layouts/_shortcodes/golangci/embed.html
================================================
{{- /*
Embeds a file.
@param {string} file The path to the file.
@returns {string}
@example {{% golangci/embed file="path/to/file.txt" %}}
*/ -}}
{{- $file := .Get "file" -}}
{{ readFile $file | safeHTML}}
================================================
FILE: docs/layouts/_shortcodes/golangci/exclusion-preset-tables.html
================================================
{{- /*
Creates a table of exclusion presets.
@example {{% golangci/exclusion-preset-tables %}}
*/ -}}
{{- $presets := index $.Site.Data.exclusion_presets -}}
{{ range $key, $values := $presets }}
### Preset {{ print "`" $key "`" }}
Linter
Issue Text
{{- range $i, $value := $values -}}
{{ index $value "linters" 0 }}
{{ index $value "text" }}
{{- end -}}
{{ end }}
================================================
FILE: docs/layouts/_shortcodes/golangci/exclusion-presets-snippet.html
================================================
{{- /*
Creates an exclusion presets configuration snippet.
@example {{% golangci/exclusion-presets-snippet %}}
*/ -}}
{{- $presets := index $.Site.Data.exclusion_presets -}}
```yaml
linters:
exclusions:
presets:
{{- range $key, $values := $presets }}
- {{ $key }}
{{- end }}
```
================================================
FILE: docs/layouts/_shortcodes/golangci/image-card.html
================================================
{{- /*
Creates a card for an image.
@param {string} src The path to the image.
@param {string} title The title text for the image.
@example {{< golangci/image-card src="path/to/image.png" title="Image description" >}}
*/ -}}
{{- $src := .Get "src" -}}
{{- $title := .Get "title" -}}
================================================
FILE: docs/layouts/_shortcodes/golangci/items/cards.html
================================================
{{- /*
Creates a card for each item (linter/formatter) in a data file.
@param {string} data The name of the data file.
@param {string} path The path to the data file.
@param {string} group The group to filter items by (use the prefix `!` to exclude items from the group).
@returns {string}
@example {{< golangci/items/cards path="formatters" data="formatters_info" >}}
@example {{< golangci/items/cards path="linters" data="linters_info" group="!standard" >}}
*/ -}}
{{- $file := .Get "data" -}}
{{- $path := .Get "path" -}}
{{- $group := .Get "group" | default "" -}}
{{- $info := index $.Site.Data $file -}}
{{- /* Determine if we should exclude items from the group */ -}}
{{- $notInGroup := hasPrefix $group "!" -}}
{{- if $notInGroup -}}
{{- $group = strings.TrimPrefix "!" $group -}}
{{- end -}}
{{- /* Filter items by group */ -}}
{{ $items := slice }}
{{- range sort $info "name" -}}
{{- if $group -}}
{{- if in .groups $group -}}
{{- if not $notInGroup -}}
{{- $items = $items | append . -}}
{{- end -}}
{{- else -}}
{{- if $notInGroup -}}
{{- $items = $items | append . -}}
{{- end -}}
{{- end -}}
{{- else -}}
{{- $items = $items | append . -}}
{{- end -}}
{{- end -}}
{{- $gcilVersion := index $.Site.Data.version.version -}}
{{- /* Create cards */ -}}
{{- range $items -}}
{{- if .internal -}}
{{- continue -}}
{{- end -}}
{{- $s := newScratch -}}
{{- $s.SetInMap "options" "page" .Page -}}
{{- $s.SetInMap "options" "link" (print "/docs/" $path "/configuration/#" .name) -}}
{{- $s.SetInMap "options" "title" .name -}}
{{- $s.SetInMap "options" "subtitle" (partial "golangci/items/format-description" .desc) -}}
{{- /* Create tag information */ -}}
{{- $tagOptions := partial "golangci/items/tag" (dict "gcilVersion" $gcilVersion "item" .) -}}
{{- range $k, $v := $tagOptions -}}
{{- $s.SetInMap "options" $k $v -}}
{{- end -}}
{{- /* CSS classes */ -}}
{{- $class := slice "gl-item" -}}
{{- if .canAutoFix -}}
{{- $class = $class | append "gl-autofix" -}}
{{- end -}}
{{- if .deprecation -}}
{{- $class = $class | append "gl-deprecated" -}}
{{- end -}}
{{- if .isSlow -}}
{{- $class = $class | append "gl-slow" -}}
{{- else -}}
{{- $class = $class | append "gl-fast" -}}
{{- end -}}
{{- if in .groups "standard" -}}
{{- $class = $class | append "gl-default" -}}
{{- end -}}
{{- if (partial "golangci/items/compare-versions" (dict "a" $gcilVersion "b" .since)) -}}
{{- $class = $class | append "gl-new" -}}
{{- end -}}
{{- partial "shortcodes/card" ($s.Get "options") -}}
{{- end -}}
================================================
FILE: docs/layouts/_shortcodes/golangci/items/filter-badge.html
================================================
{{- /* Modified version of https://github.com/imfing/hextra/blob/v0.10.0/layouts/_shortcodes/badge.html */ -}}
{{- /*
Creates a badge with the given "data-filter" value.
@param {string} content The content of the badge.
@param {string} type The type of the badge.
@param {string} data The "data-filter" value for the badge.
@param {string} class The class of the badge.
@param {boolean} border Whether to render a border around the badge.
@param {string} icon The icon of the badge.
@example {{< golangci/items/filter-badge icon="inbox" data="my-data" content="Text" class="my-class" type="info" border=true >}}
*/}}
{{- $content := .Get "content" -}}
{{- $color := .Get "color" | default "" -}}
{{- $data := .Get "data" | default "" -}}
{{- $class := .Get "class" | default "" -}}
{{- $icon := .Get "icon" | default "" -}}
{{- $border := .Get "border" | default false -}}
{{- partial "shortcodes/badge" (dict
"data" $data
"class" (printf "hx:mt-2 hx:mx-1 hx:cursor-pointer %s" $class)
"content" $content
"color" $color
"border" $border
"icon" $icon
)
-}}
================================================
FILE: docs/layouts/_shortcodes/golangci/items/filter.html
================================================
{{- /*
This shortcode is used to create a filter bar.
@example {{< golangci/items/filter >}}{{< golangci/items/filter-badge content="Example">}}{{< golangci/items/filter >}}
*/ -}}
{{- partial "utils/icon" (dict "name" "filter" "attributes" "height=1.2em") -}}
{{ .Inner }}
================================================
FILE: docs/layouts/_shortcodes/golangci/items/settings.html
================================================
{{- /*
Creates a section for each setting of a linter/formatter.
@param {string} info The name of the data file containing the linter/formatter information.
@param {string} settings The name of the data file containing the linter/formatter settings.
@example {{% golangci/items/settings info="formatters_info" settings="formatter_settings" %}}
*/ -}}
{{- $fileInfo := .Get "info" -}}
{{- $fileSettings := .Get "settings" -}}
{{- $gcilVersion := index $.Site.Data.version.version -}}
{{- $info := index $.Site.Data $fileInfo -}}
{{- $settings := index $.Site.Data $fileSettings -}}
{{- range sort $info "name" -}}
{{- if .internal -}}
{{- continue -}}
{{- end -}}
## {{ .name }}
{{/* Description */}}
{{ if .deprecation -}}
{{- $replacement := "" -}}
{{- if .deprecation.replacement -}}
{{- $replacement = print " Use `" .deprecation.replacement "` instead." -}}
{{- end -}}
{{ print (partial "golangci/items/format-description" .deprecation.message) $replacement }}
{{ else }}
{{ partial "golangci/items/format-description" .desc }}
{{ end }}
{{/* Badges */}}
{{ partial "shortcodes/badge" (dict
"border" false
"icon" "calendar"
"class" "hx:mx-1"
"content" (print "Since golangci-lint " .since)
)
}}
{{ if .deprecation -}}
{{ partial "shortcodes/badge" (dict
"border" true
"icon" "sparkles"
"class" "hx:mx-1"
"content" (print "Deprecated since " .deprecation.since)
"color" "red"
)
}}
{{ else }}
{{ if (partial "golangci/items/compare-versions" (dict "a" $gcilVersion "b" .since)) }}
{{ partial "shortcodes/badge" (dict
"border" false
"icon" "sparkles"
"class" "hx:mx-1"
"content" "New"
"color" "yellow"
)
}}
{{ end }}
{{ if .canAutoFix }}
{{ partial "shortcodes/badge" (dict
"border" false
"icon" "sparkles"
"class" "hx:mx-1"
"content" "Autofix"
"color" "blue"
)
}}
{{ end }}
{{ end }}
{{- if .originalURL -}}
{{ partial "shortcodes/badge" (dict
"border" true
"icon" "github"
"class" "hx:mx-1"
"content" "Repository"
"link" .originalURL
)
}}
{{- end -}}
{{/* Settings */}}
{{- $setting := index $settings .name -}}
{{- if $setting -}}
```yaml
{{ $setting | safeHTML}}
```
{{- else -}}
_No settings available._
{{- end }}
{{ end -}}
================================================
FILE: docs/layouts/_shortcodes/golangci/latest-version.html
================================================
{{- /*
Displays the latest version of golangci-lint.
Based on the data file `data/version.json`.
@example {{< golangci/latest-version >}}
*/ -}}
{{- $v := index $.Site.Data.version.version -}}
{{- if $v -}}
{{- $v -}}
{{- else if .Page.GitInfo -}}
{{- .Page.GitInfo.AbbreviatedCommit -}}
{{- else -}}
devel
{{- end -}}
================================================
FILE: docs/layouts/_shortcodes/golangci/starcharts.html
================================================
{{- /*
Displays a starchart for a GitHub repository.
Supports both light and dark mode.
@param {string} repo The name of the GitHub repository.
@example {{< golangci/starcharts repo="golangci/golangci-lint" >}}
*/ -}}
{{- $repo := .Get "repo" -}}
================================================
FILE: docs/static/CNAME
================================================
golangci-lint.run
================================================
FILE: docs/static/site.webmanifest
================================================
{
"name": "golangci-lint",
"short_name": "golangci-lint",
"start_url": "index.html",
"icons": [
{
"src": "android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#000000",
"background_color": "#000000",
"display": "standalone"
}
================================================
FILE: go.mod
================================================
module github.com/golangci/golangci-lint/v2
// The minimum Go version must always be latest-1.
// This version should never be changed outside of the PR to add the support of newer Go version.
// Only golangci-lint maintainers are allowed to change it.
go 1.25.0
ignore (
./docs
./jsonschema
)
require (
4d63.com/gocheckcompilerdirectives v1.3.0
4d63.com/gochecknoglobals v0.2.2
codeberg.org/polyfloyd/go-errorlint v1.9.0
dev.gaijin.team/go/exhaustruct/v4 v4.0.0
github.com/4meepo/tagalign v1.4.3
github.com/Abirdcfly/dupword v0.1.7
github.com/AdminBenni/iota-mixing v1.0.0
github.com/AlwxSin/noinlineerr v1.0.5
github.com/Antonboom/errname v1.1.1
github.com/Antonboom/nilnil v1.1.1
github.com/Antonboom/testifylint v1.6.4
github.com/BurntSushi/toml v1.6.0
github.com/Djarvur/go-err113 v0.1.1
github.com/MirrexOne/unqueryvet v1.5.4
github.com/OpenPeeDeeP/depguard/v2 v2.2.1
github.com/alecthomas/chroma/v2 v2.23.1
github.com/alecthomas/go-check-sumtype v0.3.1
github.com/alexkohler/nakedret/v2 v2.0.6
github.com/alexkohler/prealloc v1.1.0
github.com/alingse/asasalint v0.0.11
github.com/alingse/nilnesserr v0.2.0
github.com/ashanbrown/forbidigo/v2 v2.3.0
github.com/ashanbrown/makezero/v2 v2.1.0
github.com/bkielbasa/cyclop v1.2.3
github.com/blizzy78/varnamelen v0.8.0
github.com/bombsimon/wsl/v4 v4.7.0
github.com/bombsimon/wsl/v5 v5.6.0
github.com/breml/bidichk v0.3.3
github.com/breml/errchkjson v0.4.1
github.com/butuzov/ireturn v0.4.0
github.com/butuzov/mirror v1.3.0
github.com/catenacyber/perfsprint v0.10.1
github.com/charithe/durationcheck v0.0.11
github.com/charmbracelet/lipgloss v1.1.0
github.com/ckaznocha/intrange v0.3.1
github.com/curioswitch/go-reassign v0.3.0
github.com/daixiang0/gci v0.13.7
github.com/denis-tingaikin/go-header v0.5.0
github.com/fatih/color v1.18.0
github.com/firefart/nonamedreturns v1.0.6
github.com/fzipp/gocyclo v0.6.0
github.com/ghostiam/protogetter v0.3.20
github.com/go-critic/go-critic v0.14.3
github.com/go-viper/mapstructure/v2 v2.5.0
github.com/go-xmlfmt/xmlfmt v1.1.3
github.com/godoc-lint/godoc-lint v0.11.2
github.com/gofrs/flock v0.13.0
github.com/golangci/asciicheck v0.5.0
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32
github.com/golangci/go-printf-func-name v0.1.1
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d
github.com/golangci/golines v0.15.0
github.com/golangci/misspell v0.8.0
github.com/golangci/plugin-module-register v0.1.2
github.com/golangci/revgrep v0.8.0
github.com/golangci/sqlclosecheck v0.0.0-20260317152156-1b5fadbb8565
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e
github.com/gordonklaus/ineffassign v0.2.0
github.com/gostaticanalysis/forcetypeassert v0.2.0
github.com/gostaticanalysis/nilerr v0.1.2
github.com/hashicorp/go-version v1.8.0
github.com/jgautheron/goconst v1.8.2
github.com/jingyugao/rowserrcheck v1.1.1
github.com/jjti/go-spancheck v0.6.5
github.com/julz/importas v0.2.0
github.com/karamaru-alpha/copyloopvar v1.2.2
github.com/kisielk/errcheck v1.10.0
github.com/kkHAIKE/contextcheck v1.1.6
github.com/kulti/thelper v0.7.1
github.com/kunwardeep/paralleltest v1.0.15
github.com/lasiar/canonicalheader v1.1.2
github.com/ldez/exptostd v0.4.5
github.com/ldez/gomoddirectives v0.8.0
github.com/ldez/grignotin v0.10.1
github.com/ldez/tagliatelle v0.7.2
github.com/ldez/usetesting v0.5.0
github.com/leonklingele/grouper v1.1.2
github.com/macabu/inamedparam v0.2.0
github.com/manuelarte/embeddedstructfieldcheck v0.4.0
github.com/manuelarte/funcorder v0.5.0
github.com/maratori/testableexamples v1.0.1
github.com/maratori/testpackage v1.1.2
github.com/matoous/godox v1.1.0
github.com/mattn/go-colorable v0.1.14
github.com/mgechev/revive v1.15.0
github.com/mitchellh/go-homedir v1.1.0
github.com/moricho/tparallel v0.3.2
github.com/nakabonne/nestif v0.3.1
github.com/nishanths/exhaustive v0.12.0
github.com/nishanths/predeclared v0.2.2
github.com/nunnatsa/ginkgolinter v0.23.0
github.com/pelletier/go-toml/v2 v2.2.4
github.com/quasilyte/go-ruleguard/dsl v0.3.23
github.com/raeperd/recvcheck v0.2.0
github.com/rogpeppe/go-internal v1.14.1
github.com/ryancurrah/gomodguard v1.4.1
github.com/sanposhiho/wastedassign/v2 v2.1.0
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
github.com/sashamelentyev/interfacebloat v1.1.0
github.com/sashamelentyev/usestdlibvars v1.29.0
github.com/securego/gosec/v2 v2.24.8-0.20260309165252-619ce2117e08
github.com/shirou/gopsutil/v4 v4.26.2
github.com/sirupsen/logrus v1.9.4
github.com/sivchari/containedctx v1.0.3
github.com/sonatard/noctx v0.5.1
github.com/sourcegraph/go-diff v0.7.0
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.12.0
github.com/ssgreg/nlreturn/v2 v2.2.1
github.com/stbenjam/no-sprintf-host-port v0.3.1
github.com/stretchr/testify v1.11.1
github.com/tetafro/godot v1.5.4
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67
github.com/timonwong/loggercheck v0.11.0
github.com/tomarrell/wrapcheck/v2 v2.12.0
github.com/tommy-muehle/go-mnd/v2 v2.5.1
github.com/ultraware/funlen v0.2.0
github.com/ultraware/whitespace v0.2.0
github.com/uudashr/gocognit v1.2.1
github.com/uudashr/iface v1.4.1
github.com/valyala/quicktemplate v1.8.0
github.com/xen0n/gosmopolitan v1.3.0
github.com/yagipy/maintidx v1.0.0
github.com/yeya24/promlinter v0.3.0
github.com/ykadowak/zerologlint v0.1.5
gitlab.com/bosi/decorder v0.4.2
go-simpler.org/musttag v0.14.0
go-simpler.org/sloglint v0.11.1
go.augendre.info/arangolint v0.4.0
go.augendre.info/fatcontext v0.9.0
go.yaml.in/yaml/v3 v3.0.4
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
golang.org/x/mod v0.34.0
golang.org/x/sync v0.20.0
golang.org/x/sys v0.42.0
golang.org/x/tools v0.43.0
honnef.co/go/tools v0.7.0
mvdan.cc/gofumpt v0.9.2
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15
)
require (
codeberg.org/chavacava/garif v0.2.0 // indirect
dev.gaijin.team/go/golib v0.6.0 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/alfatraining/structtag v1.0.0 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/ccojocar/zxcvbn-go v1.0.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/x/ansi v0.10.1 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/dave/dst v0.27.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/ebitengine/purego v0.10.0 // indirect
github.com/ettle/strcase v0.2.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
github.com/go-toolsmith/astcopy v1.1.0 // indirect
github.com/go-toolsmith/astequal v1.2.0 // indirect
github.com/go-toolsmith/astfmt v1.1.0 // indirect
github.com/go-toolsmith/astp v1.1.0 // indirect
github.com/go-toolsmith/strparse v1.1.0 // indirect
github.com/go-toolsmith/typep v1.1.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/ldez/structtags v0.6.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/quasilyte/go-ruleguard v0.4.5 // indirect
github.com/quasilyte/gogrep v0.5.0 // indirect
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/tklauser/go-sysconf v0.3.16 // indirect
github.com/tklauser/numcpus v0.11.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358 // indirect
golang.org/x/text v0.35.0 // indirect
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
google.golang.org/protobuf v1.36.8 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
================================================
FILE: go.sum
================================================
4d63.com/gocheckcompilerdirectives v1.3.0 h1:Ew5y5CtcAAQeTVKUVFrE7EwHMrTO6BggtEj8BZSjZ3A=
4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY=
4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU=
4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
codeberg.org/chavacava/garif v0.2.0 h1:F0tVjhYbuOCnvNcU3YSpO6b3Waw6Bimy4K0mM8y6MfY=
codeberg.org/chavacava/garif v0.2.0/go.mod h1:P2BPbVbT4QcvLZrORc2T29szK3xEOlnl0GiPTJmEqBQ=
codeberg.org/polyfloyd/go-errorlint v1.9.0 h1:VkdEEmA1VBpH6ecQoMR4LdphVI3fA4RrCh2an7YmodI=
codeberg.org/polyfloyd/go-errorlint v1.9.0/go.mod h1:GPRRu2LzVijNn4YkrZYJfatQIdS+TrcK8rL5Xs24qw8=
dev.gaijin.team/go/exhaustruct/v4 v4.0.0 h1:873r7aNneqoBB3IaFIzhvt2RFYTuHgmMjoKfwODoI1Y=
dev.gaijin.team/go/exhaustruct/v4 v4.0.0/go.mod h1:aZ/k2o4Y05aMJtiux15x8iXaumE88YdiB0Ai4fXOzPI=
dev.gaijin.team/go/golib v0.6.0 h1:v6nnznFTs4bppib/NyU1PQxobwDHwCXXl15P7DV5Zgo=
dev.gaijin.team/go/golib v0.6.0/go.mod h1:uY1mShx8Z/aNHWDyAkZTkX+uCi5PdX7KsG1eDQa2AVE=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/4meepo/tagalign v1.4.3 h1:Bnu7jGWwbfpAie2vyl63Zup5KuRv21olsPIha53BJr8=
github.com/4meepo/tagalign v1.4.3/go.mod h1:00WwRjiuSbrRJnSVeGWPLp2epS5Q/l4UEy0apLLS37c=
github.com/Abirdcfly/dupword v0.1.7 h1:2j8sInznrje4I0CMisSL6ipEBkeJUJAmK1/lfoNGWrQ=
github.com/Abirdcfly/dupword v0.1.7/go.mod h1:K0DkBeOebJ4VyOICFdppB23Q0YMOgVafM0zYW0n9lF4=
github.com/AdminBenni/iota-mixing v1.0.0 h1:Os6lpjG2dp/AE5fYBPAA1zfa2qMdCAWwPMCgpwKq7wo=
github.com/AdminBenni/iota-mixing v1.0.0/go.mod h1:i4+tpAaB+qMVIV9OK3m4/DAynOd5bQFaOu+2AhtBCNY=
github.com/AlwxSin/noinlineerr v1.0.5 h1:RUjt63wk1AYWTXtVXbSqemlbVTb23JOSRiNsshj7TbY=
github.com/AlwxSin/noinlineerr v1.0.5/go.mod h1:+QgkkoYrMH7RHvcdxdlI7vYYEdgeoFOVjU9sUhw/rQc=
github.com/Antonboom/errname v1.1.1 h1:bllB7mlIbTVzO9jmSWVWLjxTEbGBVQ1Ff/ClQgtPw9Q=
github.com/Antonboom/errname v1.1.1/go.mod h1:gjhe24xoxXp0ScLtHzjiXp0Exi1RFLKJb0bVBtWKCWQ=
github.com/Antonboom/nilnil v1.1.1 h1:9Mdr6BYd8WHCDngQnNVV0b554xyisFioEKi30sksufQ=
github.com/Antonboom/nilnil v1.1.1/go.mod h1:yCyAmSw3doopbOWhJlVci+HuyNRuHJKIv6V2oYQa8II=
github.com/Antonboom/testifylint v1.6.4 h1:gs9fUEy+egzxkEbq9P4cpcMB6/G0DYdMeiFS87UiqmQ=
github.com/Antonboom/testifylint v1.6.4/go.mod h1:YO33FROXX2OoUfwjz8g+gUxQXio5i9qpVy7nXGbxDD4=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Djarvur/go-err113 v0.1.1 h1:eHfopDqXRwAi+YmCUas75ZE0+hoBHJ2GQNLYRSxao4g=
github.com/Djarvur/go-err113 v0.1.1/go.mod h1:IaWJdYFLg76t2ihfflPZnM1LIQszWOsFDh2hhhAVF6k=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/MirrexOne/unqueryvet v1.5.4 h1:38QOxShO7JmMWT+eCdDMbcUgGCOeJphVkzzRgyLJgsQ=
github.com/MirrexOne/unqueryvet v1.5.4/go.mod h1:fs9Zq6eh1LRIhsDIsxf9PONVUjYdFHdtkHIgZdJnyPU=
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsuj3piCMx4=
github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo=
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/chroma/v2 v2.23.1 h1:nv2AVZdTyClGbVQkIzlDm/rnhk1E9bU9nXwmZ/Vk/iY=
github.com/alecthomas/chroma/v2 v2.23.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o=
github.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsrxJb4Aq31NLkU=
github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E=
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alexkohler/nakedret/v2 v2.0.6 h1:ME3Qef1/KIKr3kWX3nti3hhgNxw6aqN5pZmQiFSsuzQ=
github.com/alexkohler/nakedret/v2 v2.0.6/go.mod h1:l3RKju/IzOMQHmsEvXwkqMDzHHvurNQfAgE1eVmT40Q=
github.com/alexkohler/prealloc v1.1.0 h1:cKGRBqlXw5iyQGLYhrXrDlcHxugXpTq4tQ5c91wkf8M=
github.com/alexkohler/prealloc v1.1.0/go.mod h1:fT39Jge3bQrfA7nPMDngUfvUbQGQeJyGQnR+913SCig=
github.com/alfatraining/structtag v1.0.0 h1:2qmcUqNcCoyVJ0up879K614L9PazjBSFruTB0GOFjCc=
github.com/alfatraining/structtag v1.0.0/go.mod h1:p3Xi5SwzTi+Ryj64DqjLWz7XurHxbGsq6y3ubePJPus=
github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
github.com/alingse/nilnesserr v0.2.0 h1:raLem5KG7EFVb4UIDAXgrv3N2JIaffeKNtcEXkEWd/w=
github.com/alingse/nilnesserr v0.2.0/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg=
github.com/ashanbrown/forbidigo/v2 v2.3.0 h1:OZZDOchCgsX5gvToVtEBoV2UWbFfI6RKQTir2UZzSxo=
github.com/ashanbrown/forbidigo/v2 v2.3.0/go.mod h1:5p6VmsG5/1xx3E785W9fouMxIOkvY2rRV9nMdWadd6c=
github.com/ashanbrown/makezero/v2 v2.1.0 h1:snuKYMbqosNokUKm+R6/+vOPs8yVAi46La7Ck6QYSaE=
github.com/ashanbrown/makezero/v2 v2.1.0/go.mod h1:aEGT/9q3S8DHeE57C88z2a6xydvgx8J5hgXIGWgo0MY=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w=
github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo=
github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=
github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
github.com/bombsimon/wsl/v4 v4.7.0 h1:1Ilm9JBPRczjyUs6hvOPKvd7VL1Q++PL8M0SXBDf+jQ=
github.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg=
github.com/bombsimon/wsl/v5 v5.6.0 h1:4z+/sBqC5vUmSp1O0mS+czxwH9+LKXtCWtHH9rZGQL8=
github.com/bombsimon/wsl/v5 v5.6.0/go.mod h1:Uqt2EfrMj2NV8UGoN1f1Y3m0NpUVCsUdrNCdet+8LvU=
github.com/breml/bidichk v0.3.3 h1:WSM67ztRusf1sMoqH6/c4OBCUlRVTKq+CbSeo0R17sE=
github.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE=
github.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDwg=
github.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s=
github.com/butuzov/ireturn v0.4.0 h1:+s76bF/PfeKEdbG8b54aCocxXmi0wvYdOVsWxVO7n8E=
github.com/butuzov/ireturn v0.4.0/go.mod h1:ghI0FrCmap8pDWZwfPisFD1vEc56VKH4NpQUxDHta70=
github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc=
github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
github.com/catenacyber/perfsprint v0.10.1 h1:u7Riei30bk46XsG8nknMhKLXG9BcXz3+3tl/WpKm0PQ=
github.com/catenacyber/perfsprint v0.10.1/go.mod h1:DJTGsi/Zufpuus6XPGJyKOTMELe347o6akPvWG9Zcsc=
github.com/ccojocar/zxcvbn-go v1.0.4 h1:FWnCIRMXPj43ukfX000kvBZvV6raSxakYr1nzyNrUcc=
github.com/ccojocar/zxcvbn-go v1.0.4/go.mod h1:3GxGX+rHmueTUMvm5ium7irpyjmm7ikxYFOSJB21Das=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charithe/durationcheck v0.0.11 h1:g1/EX1eIiKS57NTWsYtHDZ/APfeXKhye1DidBcABctk=
github.com/charithe/durationcheck v0.0.11/go.mod h1:x5iZaixRNl8ctbM+3B2RrPG5t856TxRyVQEnbIEM2X4=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/ckaznocha/intrange v0.3.1 h1:j1onQyXvHUsPWujDH6WIjhyH26gkRt/txNlV7LspvJs=
github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs=
github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=
github.com/daixiang0/gci v0.13.7 h1:+0bG5eK9vlI08J+J/NWGbWPTNiXPG4WhNLJOkSxWITQ=
github.com/daixiang0/gci v0.13.7/go.mod h1:812WVN6JLFY9S6Tv76twqmNqevN0pa3SX3nih0brVzQ=
github.com/dave/dst v0.27.3 h1:P1HPoMza3cMEquVf9kKy8yXsFirry4zEnWOdYPOoIzY=
github.com/dave/dst v0.27.3/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc=
github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo=
github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8=
github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY=
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q=
github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/firefart/nonamedreturns v1.0.6 h1:vmiBcKV/3EqKY3ZiPxCINmpS431OcE1S47AQUwhrg8E=
github.com/firefart/nonamedreturns v1.0.6/go.mod h1:R8NisJnSIpvPWheCq0mNRXJok6D8h7fagJTF8EMEwCo=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/ghostiam/protogetter v0.3.20 h1:oW7OPFit2FxZOpmMRPP9FffU4uUpfeE/rEdE1f+MzD0=
github.com/ghostiam/protogetter v0.3.20/go.mod h1:FjIu5Yfs6FT391m+Fjp3fbAYJ6rkL/J6ySpZBfnODuI=
github.com/go-critic/go-critic v0.14.3 h1:5R1qH2iFeo4I/RJU8vTezdqs08Egi4u5p6vOESA0pog=
github.com/go-critic/go-critic v0.14.3/go.mod h1:xwntfW6SYAd7h1OqDzmN6hBX/JxsEKl5up/Y2bsxgVQ=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=
github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s=
github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw=
github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=
github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ=
github.com/go-toolsmith/astequal v1.2.0 h1:3Fs3CYZ1k9Vo4FzFhwwewC3CHISHDnVUPC4x0bI2+Cw=
github.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY=
github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco=
github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4=
github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA=
github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA=
github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk=
github.com/go-toolsmith/pkgload v1.2.2/go.mod h1:R2hxLNRKuAsiXCo2i5J6ZQPhnPMOVtU+f0arbFPWCus=
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw=
github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=
github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUWY=
github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/godoc-lint/godoc-lint v0.11.2 h1:Bp0FkJWoSdNsBikdNgIcgtaoo+xz6I/Y9s5WSBQUeeM=
github.com/godoc-lint/godoc-lint v0.11.2/go.mod h1:iVpGdL1JCikNH2gGeAn3Hh+AgN5Gx/I/cxV+91L41jo=
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golangci/asciicheck v0.5.0 h1:jczN/BorERZwK8oiFBOGvlGPknhvq0bjnysTj4nUfo0=
github.com/golangci/asciicheck v0.5.0/go.mod h1:5RMNAInbNFw2krqN6ibBxN/zfRFa9S6tA1nPdM0l8qQ=
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 h1:WUvBfQL6EW/40l6OmeSBYQJNSif4O11+bmWEz+C7FYw=
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E=
github.com/golangci/go-printf-func-name v0.1.1 h1:hIYTFJqAGp1iwoIfsNTpoq1xZAarogrvjO9AfiW3B4U=
github.com/golangci/go-printf-func-name v0.1.1/go.mod h1:Es64MpWEZbh0UBtTAICOZiB+miW53w/K9Or/4QogJss=
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE=
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=
github.com/golangci/golines v0.15.0 h1:Qnph25g8Y1c5fdo1X7GaRDGgnMHgnxh4Gk4VfPTtRx0=
github.com/golangci/golines v0.15.0/go.mod h1:AZjXd23tbHMpowhtnGlj9KCNsysj72aeZVVHnVcZx10=
github.com/golangci/misspell v0.8.0 h1:qvxQhiE2/5z+BVRo1kwYA8yGz+lOlu5Jfvtx2b04Jbg=
github.com/golangci/misspell v0.8.0/go.mod h1:WZyyI2P3hxPY2UVHs3cS8YcllAeyfquQcKfdeE9AFVg=
github.com/golangci/plugin-module-register v0.1.2 h1:e5WM6PO6NIAEcij3B053CohVp3HIYbzSuP53UAYgOpg=
github.com/golangci/plugin-module-register v0.1.2/go.mod h1:1+QGTsKBvAIvPvoY/os+G5eoqxWn70HYDm2uvUyGuVw=
github.com/golangci/revgrep v0.8.0 h1:EZBctwbVd0aMeRnNUsFogoyayvKHyxlV3CdUA46FX2s=
github.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=
github.com/golangci/sqlclosecheck v0.0.0-20260317152156-1b5fadbb8565 h1:fI1TNZdfJwSslKBsHYJ2z3ULc6nm4XEe6+uarzpSJ6Y=
github.com/golangci/sqlclosecheck v0.0.0-20260317152156-1b5fadbb8565/go.mod h1:GfuBfcLE7vrbeKKWP6/9xMO2o4KQJWPNDh4SfnkxYII=
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e h1:ai0EfmVYE2bRA5htgAG9r7s3tHsfjIhN98WshBTJ9jM=
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e/go.mod h1:Vrn4B5oR9qRwM+f54koyeH3yzphlecwERs0el27Fr/s=
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e h1:gD6P7NEo7Eqtt0ssnqSJNNndxe69DOQ24A5h7+i3KpM=
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e/go.mod h1:h+wZwLjUTJnm/P2rwlbJdRPZXOzaT36/FwnPnY2inzc=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gordonklaus/ineffassign v0.2.0 h1:Uths4KnmwxNJNzq87fwQQDDnbNb7De00VOk9Nu0TySs=
github.com/gordonklaus/ineffassign v0.2.0/go.mod h1:TIpymnagPSexySzs7F9FnO1XFTy8IT3a59vmZp5Y9Lw=
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
github.com/gostaticanalysis/comment v1.5.0 h1:X82FLl+TswsUMpMh17srGRuKaaXprTaytmEpgnKIDu8=
github.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc=
github.com/gostaticanalysis/forcetypeassert v0.2.0 h1:uSnWrrUEYDr86OCxWa4/Tp2jeYDlogZiZHzGkWFefTk=
github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY=
github.com/gostaticanalysis/nilerr v0.1.2 h1:S6nk8a9N8g062nsx63kUkF6AzbHGw7zzyHMcpu52xQU=
github.com/gostaticanalysis/nilerr v0.1.2/go.mod h1:A19UHhoY3y8ahoL7YKz6sdjDtduwTSI4CsymaC2htPA=
github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=
github.com/gostaticanalysis/testutil v0.5.0 h1:Dq4wT1DdTwTGCQQv3rl3IvD5Ld0E6HiY+3Zh0sUGqw8=
github.com/gostaticanalysis/testutil v0.5.0/go.mod h1:OLQSbuM6zw2EvCcXTz1lVq5unyoNft372msDY0nY5Hs=
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo=
github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jgautheron/goconst v1.8.2 h1:y0XF7X8CikZ93fSNT6WBTb/NElBu9IjaY7CCYQrCMX4=
github.com/jgautheron/goconst v1.8.2/go.mod h1:A0oxgBCHy55NQn6sYpO7UdnA9p+h7cPtoOZUmvNIako=
github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=
github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
github.com/jjti/go-spancheck v0.6.5 h1:lmi7pKxa37oKYIMScialXUK6hP3iY5F1gu+mLBPgYB8=
github.com/jjti/go-spancheck v0.6.5/go.mod h1:aEogkeatBrbYsyW6y5TgDfihCulDYciL1B7rG2vSsrU=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ=
github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=
github.com/karamaru-alpha/copyloopvar v1.2.2 h1:yfNQvP9YaGQR7VaWLYcfZUlRP2eo2vhExWKxD/fP6q0=
github.com/karamaru-alpha/copyloopvar v1.2.2/go.mod h1:oY4rGZqZ879JkJMtX3RRkcXRkmUvH0x35ykgaKgsgJY=
github.com/kisielk/errcheck v1.10.0 h1:Lvs/YAHP24YKg08LA8oDw2z9fJVme090RAXd90S+rrw=
github.com/kisielk/errcheck v1.10.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE=
github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kulti/thelper v0.7.1 h1:fI8QITAoFVLx+y+vSyuLBP+rcVIB8jKooNSCT2EiI98=
github.com/kulti/thelper v0.7.1/go.mod h1:NsMjfQEy6sd+9Kfw8kCP61W1I0nerGSYSFnGaxQkcbs=
github.com/kunwardeep/paralleltest v1.0.15 h1:ZMk4Qt306tHIgKISHWFJAO1IDQJLc6uDyJMLyncOb6w=
github.com/kunwardeep/paralleltest v1.0.15/go.mod h1:di4moFqtfz3ToSKxhNjhOZL+696QtJGCFe132CbBLGk=
github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4=
github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=
github.com/ldez/exptostd v0.4.5 h1:kv2ZGUVI6VwRfp/+bcQ6Nbx0ghFWcGIKInkG/oFn1aQ=
github.com/ldez/exptostd v0.4.5/go.mod h1:QRjHRMXJrCTIm9WxVNH6VW7oN7KrGSht69bIRwvdFsM=
github.com/ldez/gomoddirectives v0.8.0 h1:JqIuTtgvFC2RdH1s357vrE23WJF2cpDCPFgA/TWDGpk=
github.com/ldez/gomoddirectives v0.8.0/go.mod h1:jutzamvZR4XYJLr0d5Honycp4Gy6GEg2mS9+2YX3F1Q=
github.com/ldez/grignotin v0.10.1 h1:keYi9rYsgbvqAZGI1liek5c+jv9UUjbvdj3Tbn5fn4o=
github.com/ldez/grignotin v0.10.1/go.mod h1:UlDbXFCARrXbWGNGP3S5vsysNXAPhnSuBufpTEbwOas=
github.com/ldez/structtags v0.6.1 h1:bUooFLbXx41tW8SvkfwfFkkjPYvFFs59AAMgVg6DUBk=
github.com/ldez/structtags v0.6.1/go.mod h1:YDxVSgDy/MON6ariaxLF2X09bh19qL7MtGBN5MrvbdY=
github.com/ldez/tagliatelle v0.7.2 h1:KuOlL70/fu9paxuxbeqlicJnCspCRjH0x8FW+NfgYUk=
github.com/ldez/tagliatelle v0.7.2/go.mod h1:PtGgm163ZplJfZMZ2sf5nhUT170rSuPgBimoyYtdaSI=
github.com/ldez/usetesting v0.5.0 h1:3/QtzZObBKLy1F4F8jLuKJiKBjjVFi1IavpoWbmqLwc=
github.com/ldez/usetesting v0.5.0/go.mod h1:Spnb4Qppf8JTuRgblLrEWb7IE6rDmUpGvxY3iRrzvDQ=
github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=
github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE=
github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/manuelarte/embeddedstructfieldcheck v0.4.0 h1:3mAIyaGRtjK6EO9E73JlXLtiy7ha80b2ZVGyacxgfww=
github.com/manuelarte/embeddedstructfieldcheck v0.4.0/go.mod h1:z8dFSyXqp+fC6NLDSljRJeNQJJDWnY7RoWFzV3PC6UM=
github.com/manuelarte/funcorder v0.5.0 h1:llMuHXXbg7tD0i/LNw8vGnkDTHFpTnWqKPI85Rknc+8=
github.com/manuelarte/funcorder v0.5.0/go.mod h1:Yt3CiUQthSBMBxjShjdXMexmzpP8YGvGLjrxJNkO2hA=
github.com/maratori/testableexamples v1.0.1 h1:HfOQXs+XgfeRBJ+Wz0XfH+FHnoY9TVqL6Fcevpzy4q8=
github.com/maratori/testableexamples v1.0.1/go.mod h1:XE2F/nQs7B9N08JgyRmdGjYVGqxWwClLPCGSQhXQSrQ=
github.com/maratori/testpackage v1.1.2 h1:ffDSh+AgqluCLMXhM19f/cpvQAKygKAJXFl9aUjmbqs=
github.com/maratori/testpackage v1.1.2/go.mod h1:8F24GdVDFW5Ew43Et02jamrVMNXLUNaOynhDssITGfc=
github.com/matoous/godox v1.1.0 h1:W5mqwbyWrwZv6OQ5Z1a/DHGMOvXYCBP3+Ht7KMoJhq4=
github.com/matoous/godox v1.1.0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgechev/revive v1.15.0 h1:vJ0HzSBzfNyPbHKolgiFjHxLek9KUijhqh42yGoqZ8Q=
github.com/mgechev/revive v1.15.0/go.mod h1:LlAKO3QQe9OJ0pVZzI2GPa8CbXGZ/9lNpCGvK4T/a8A=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI=
github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U=
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U=
github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=
github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg=
github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
github.com/nunnatsa/ginkgolinter v0.23.0 h1:x3o4DGYOWbBMP/VdNQKgSj+25aJKx2Pe6lHr8gBcgf8=
github.com/nunnatsa/ginkgolinter v0.23.0/go.mod h1:9qN1+0akwXEccwV1CAcCDfcoBlWXHB+ML9884pL4SZ4=
github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI=
github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/quasilyte/go-ruleguard v0.4.5 h1:AGY0tiOT5hJX9BTdx/xBdoCubQUAE2grkqY2lSwvZcA=
github.com/quasilyte/go-ruleguard v0.4.5/go.mod h1:Vl05zJ538vcEEwu16V/Hdu7IYZWyKSwIy4c88Ro1kRE=
github.com/quasilyte/go-ruleguard/dsl v0.3.23 h1:lxjt5B6ZCiBeeNO8/oQsegE6fLeCzuMRoVWSkXC4uvY=
github.com/quasilyte/go-ruleguard/dsl v0.3.23/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo=
github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU=
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs=
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
github.com/raeperd/recvcheck v0.2.0 h1:GnU+NsbiCqdC2XX5+vMZzP+jAJC5fht7rcVTAhX74UI=
github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryancurrah/gomodguard v1.4.1 h1:eWC8eUMNZ/wM/PWuZBv7JxxqT5fiIKSIyTvjb7Elr+g=
github.com/ryancurrah/gomodguard v1.4.1/go.mod h1:qnMJwV1hX9m+YJseXEBhd2s90+1Xn6x9dLz11ualI1I=
github.com/sanposhiho/wastedassign/v2 v2.1.0 h1:crurBF7fJKIORrV85u9UUpePDYGWnwvv3+A96WvwXT0=
github.com/sanposhiho/wastedassign/v2 v2.1.0/go.mod h1:+oSmSC+9bQ+VUAxA66nBb0Z7N8CK7mscKTDYC6aIek4=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw=
github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
github.com/sashamelentyev/usestdlibvars v1.29.0 h1:8J0MoRrw4/NAXtjQqTHrbW9NN+3iMf7Knkq057v4XOQ=
github.com/sashamelentyev/usestdlibvars v1.29.0/go.mod h1:8PpnjHMk5VdeWlVb4wCdrB8PNbLqZ3wBZTZWkrpZZL8=
github.com/securego/gosec/v2 v2.24.8-0.20260309165252-619ce2117e08 h1:AoLtJX4WUtZkhhUUMFy3GgecAALp/Mb4S1iyQOA2s0U=
github.com/securego/gosec/v2 v2.24.8-0.20260309165252-619ce2117e08/go.mod h1:+XLCJiRE95ga77XInNELh2M6zQP+PdqiT9Zpm0D9Wpk=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI=
github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE=
github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4=
github.com/sonatard/noctx v0.5.1 h1:wklWg9c9ZYugOAk7qG4yP4PBrlQsmSLPTvW1K4PRQMs=
github.com/sonatard/noctx v0.5.1/go.mod h1:64XdbzFb18XL4LporKXp8poqZtPKbCrqQ402CV+kJas=
github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0=
github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=
github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
github.com/stbenjam/no-sprintf-host-port v0.3.1 h1:AyX7+dxI4IdLBPtDbsGAyqiTSLpCP9hWRrXQDU4Cm/g=
github.com/stbenjam/no-sprintf-host-port v0.3.1/go.mod h1:ODbZesTCHMVKthBHskvUUexdcNHAQRXk9NpSsL8p/HQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
github.com/tetafro/godot v1.5.4 h1:u1ww+gqpRLiIA16yF2PV1CV1n/X3zhyezbNXC3E14Sg=
github.com/tetafro/godot v1.5.4/go.mod h1:eOkMrVQurDui411nBY2FA05EYH01r14LuWY/NrVDVcU=
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 h1:9LPGD+jzxMlnk5r6+hJnar67cgpDIz/iyD+rfl5r2Vk=
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=
github.com/timonwong/loggercheck v0.11.0 h1:jdaMpYBl+Uq9mWPXv1r8jc5fC3gyXx4/WGwTnnNKn4M=
github.com/timonwong/loggercheck v0.11.0/go.mod h1:HEAWU8djynujaAVX7QI65Myb8qgfcZ1uKbdpg3ZzKl8=
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
github.com/tomarrell/wrapcheck/v2 v2.12.0 h1:H/qQ1aNWz/eeIhxKAFvkfIA+N7YDvq6TWVFL27Of9is=
github.com/tomarrell/wrapcheck/v2 v2.12.0/go.mod h1:AQhQuZd0p7b6rfW+vUwHm5OMCGgp63moQ9Qr/0BpIWo=
github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw=
github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
github.com/ultraware/funlen v0.2.0 h1:gCHmCn+d2/1SemTdYMiKLAHFYxTYz7z9VIDRaTGyLkI=
github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA=
github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g=
github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=
github.com/uudashr/gocognit v1.2.1 h1:CSJynt5txTnORn/DkhiB4mZjwPuifyASC8/6Q0I/QS4=
github.com/uudashr/gocognit v1.2.1/go.mod h1:acaubQc6xYlXFEMb9nWX2dYBzJ/bIjEkc1zzvyIZg5Q=
github.com/uudashr/iface v1.4.1 h1:J16Xl1wyNX9ofhpHmQ9h9gk5rnv2A6lX/2+APLTo0zU=
github.com/uudashr/iface v1.4.1/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/quicktemplate v1.8.0 h1:zU0tjbIqTRgKQzFY1L42zq0qR3eh4WoQQdIdqCysW5k=
github.com/valyala/quicktemplate v1.8.0/go.mod h1:qIqW8/igXt8fdrUln5kOSb+KWMaJ4Y8QUsfd1k6L2jM=
github.com/xen0n/gosmopolitan v1.3.0 h1:zAZI1zefvo7gcpbCOrPSHJZJYA9ZgLfJqtKzZ5pHqQM=
github.com/xen0n/gosmopolitan v1.3.0/go.mod h1:rckfr5T6o4lBtM1ga7mLGKZmLxswUoH1zxHgNXOsEt4=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=
github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=
github.com/yeya24/promlinter v0.3.0 h1:JVDbMp08lVCP7Y6NP3qHroGAO6z2yGKQtS5JsjqtoFs=
github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4=
github.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw=
github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo=
gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8=
go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ=
go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28=
go-simpler.org/musttag v0.14.0 h1:XGySZATqQYSEV3/YTy+iX+aofbZZllJaqwFWs+RTtSo=
go-simpler.org/musttag v0.14.0/go.mod h1:uP8EymctQjJ4Z1kUnjX0u2l60WfUdQxCwSNKzE1JEOE=
go-simpler.org/sloglint v0.11.1 h1:xRbPepLT/MHPTCA6TS/wNfZrDzkGvCCqUv4Bdwc3H7s=
go-simpler.org/sloglint v0.11.1/go.mod h1:2PowwiCOK8mjiF+0KGifVOT8ZsCNiFzvfyJeJOIt8MQ=
go.augendre.info/arangolint v0.4.0 h1:xSCZjRoS93nXazBSg5d0OGCi9APPLNMmmLrC995tR50=
go.augendre.info/arangolint v0.4.0/go.mod h1:l+f/b4plABuFISuKnTGD4RioXiCCgghv2xqst/xOvAA=
go.augendre.info/fatcontext v0.9.0 h1:Gt5jGD4Zcj8CDMVzjOJITlSb9cEch54hjRRlN3qDojE=
go.augendre.info/fatcontext v0.9.0/go.mod h1:L94brOAT1OOUNue6ph/2HnwxoNlds9aXDF2FcUntbNw=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358 h1:qWFG1Dj7TBjOjOvhEOkmyGPVoquqUKnIU0lEVLp8xyk=
golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358/go.mod h1:4Mzdyp/6jzw9auFDJ3OMF5qksa7UvPnzKqTVGcb04ms=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.7.0 h1:w6WUp1VbkqPEgLz4rkBzH/CSU6HkoqNLp6GstyTx3lU=
honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc=
mvdan.cc/gofumpt v0.9.2 h1:zsEMWL8SVKGHNztrx6uZrXdp7AX8r421Vvp23sz7ik4=
mvdan.cc/gofumpt v0.9.2/go.mod h1:iB7Hn+ai8lPvofHd9ZFGVg2GOr8sBUw1QUWjNbmIL/s=
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 h1:ssMzja7PDPJV8FStj7hq9IKiuiKhgz9ErWw+m68e7DI=
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15/go.mod h1:4M5MMXl2kW6fivUT6yRGpLLPNfuGtU2Z0cPvFquGDYU=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
================================================
FILE: install.sh
================================================
#!/bin/sh
set -e
usage() {
this=$1
cat <] [-d] []
-b sets bindir or installation directory, Defaults to ./bin
-d turns on debug logging
is a tag from
https://github.com/golangci/golangci-lint/releases
If tag is missing, then the latest will be used.
EOF
exit 2
}
parse_args() {
# BINDIR is ./bin unless set be ENV
# overridden by flag below
BINDIR=${BINDIR:-./bin}
while getopts "b:dh?x" arg; do
case "$arg" in
b) BINDIR="$OPTARG" ;;
d) log_set_priority 10 ;;
h | \?) usage "$0" ;;
x) set -x ;;
esac
done
shift $((OPTIND - 1))
TAG=$1
}
# this function wraps all the destructive operations
# if a curl|bash cuts off the end of the script due to
# network, either nothing will happen or will syntax error
# out preventing half-done work
execute() {
tmpdir=$(mktemp -d)
log_debug "downloading files into ${tmpdir}"
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
srcdir="${tmpdir}/${NAME}"
rm -rf "${srcdir}"
(cd "${tmpdir}" && untar "${TARBALL}")
test ! -d "${BINDIR}" && install -d "${BINDIR}"
for binexe in $BINARIES; do
if [ "$OS" = "windows" ]; then
binexe="${binexe}.exe"
fi
install "${srcdir}/${binexe}" "${BINDIR}/"
log_info "installed ${BINDIR}/${binexe}"
done
rm -rf "${tmpdir}"
}
get_binaries() {
case "$PLATFORM" in
darwin/amd64) BINARIES="golangci-lint" ;;
darwin/arm64) BINARIES="golangci-lint" ;;
darwin/armv6) BINARIES="golangci-lint" ;;
darwin/armv7) BINARIES="golangci-lint" ;;
darwin/mips64) BINARIES="golangci-lint" ;;
darwin/mips64le) BINARIES="golangci-lint" ;;
darwin/ppc64le) BINARIES="golangci-lint" ;;
darwin/s390x) BINARIES="golangci-lint" ;;
freebsd/386) BINARIES="golangci-lint" ;;
freebsd/amd64) BINARIES="golangci-lint" ;;
freebsd/arm64) BINARIES="golangci-lint" ;;
freebsd/armv6) BINARIES="golangci-lint" ;;
freebsd/armv7) BINARIES="golangci-lint" ;;
freebsd/mips64) BINARIES="golangci-lint" ;;
freebsd/mips64le) BINARIES="golangci-lint" ;;
freebsd/ppc64le) BINARIES="golangci-lint" ;;
freebsd/s390x) BINARIES="golangci-lint" ;;
illumos/amd64) BINARIES="golangci-lint" ;;
linux/386) BINARIES="golangci-lint" ;;
linux/amd64) BINARIES="golangci-lint" ;;
linux/arm64) BINARIES="golangci-lint" ;;
linux/armv6) BINARIES="golangci-lint" ;;
linux/armv7) BINARIES="golangci-lint" ;;
linux/mips64) BINARIES="golangci-lint" ;;
linux/mips64le) BINARIES="golangci-lint" ;;
linux/ppc64le) BINARIES="golangci-lint" ;;
linux/s390x) BINARIES="golangci-lint" ;;
linux/riscv64) BINARIES="golangci-lint" ;;
linux/loong64) BINARIES="golangci-lint" ;;
netbsd/386) BINARIES="golangci-lint" ;;
netbsd/amd64) BINARIES="golangci-lint" ;;
netbsd/armv6) BINARIES="golangci-lint" ;;
netbsd/armv7) BINARIES="golangci-lint" ;;
windows/386) BINARIES="golangci-lint" ;;
windows/amd64) BINARIES="golangci-lint" ;;
windows/arm64) BINARIES="golangci-lint" ;;
windows/armv6) BINARIES="golangci-lint" ;;
windows/armv7) BINARIES="golangci-lint" ;;
windows/mips64) BINARIES="golangci-lint" ;;
windows/mips64le) BINARIES="golangci-lint" ;;
windows/ppc64le) BINARIES="golangci-lint" ;;
windows/s390x) BINARIES="golangci-lint" ;;
*)
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
exit 1
;;
esac
}
tag_to_version() {
if [ -z "${TAG}" ]; then
log_info "checking GitHub for latest tag"
else
log_info "checking GitHub for tag '${TAG}'"
fi
REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
if test -z "$REALTAG"; then
log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
exit 1
fi
# if version starts with 'v', remove it
TAG="$REALTAG"
VERSION=${TAG#v}
}
adjust_format() {
# change format (tar.gz or zip) based on OS
case ${OS} in
windows) FORMAT=zip ;;
esac
true
}
adjust_os() {
# adjust archive name based on OS
true
}
adjust_arch() {
# adjust archive name based on ARCH
true
}
cat /dev/null </dev/null
}
echoerr() {
echo "$@" 1>&2
}
_logp=6
log_set_priority() {
_logp="$1"
}
log_priority() {
if test -z "$1"; then
echo "$_logp"
return
fi
[ "$1" -le "$_logp" ]
}
log_tag() {
case $1 in
0) echo "emerg" ;;
1) echo "alert" ;;
2) echo "crit" ;;
3) echo "err" ;;
4) echo "warning" ;;
5) echo "notice" ;;
6) echo "info" ;;
7) echo "debug" ;;
*) echo "$1" ;;
esac
}
log_debug() {
log_priority 7 || return 0
echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
}
log_info() {
log_priority 6 || return 0
echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
}
log_err() {
log_priority 3 || return 0
echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
}
log_crit() {
log_priority 2 || return 0
echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
}
uname_os() {
os=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$os" in
msys*) os="windows" ;;
mingw*) os="windows" ;;
cygwin*) os="windows" ;;
win*) os="windows" ;;
sunos) [ "$(uname -o)" = "illumos" ] && os=illumos ;;
esac
echo "$os"
}
uname_arch() {
arch=$(uname -m)
case $arch in
x86_64) arch="amd64" ;;
x86) arch="386" ;;
i686) arch="386" ;;
i386) arch="386" ;;
i86pc) arch="amd64" ;;
aarch64) arch="arm64" ;;
armv5*) arch="armv5" ;;
armv6*) arch="armv6" ;;
armv7*) arch="armv7" ;;
loongarch64) arch="loong64" ;;
esac
echo "${arch}"
}
uname_os_check() {
os=$(uname_os)
case "$os" in
darwin) return 0 ;;
dragonfly) return 0 ;;
freebsd) return 0 ;;
illumos) return 0;;
linux) return 0 ;;
android) return 0 ;;
nacl) return 0 ;;
netbsd) return 0 ;;
openbsd) return 0 ;;
plan9) return 0 ;;
solaris) return 0 ;;
windows) return 0 ;;
esac
log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value."
return 1
}
uname_arch_check() {
arch=$(uname_arch)
case "$arch" in
386) return 0 ;;
amd64) return 0 ;;
arm64) return 0 ;;
armv5) return 0 ;;
armv6) return 0 ;;
armv7) return 0 ;;
ppc64) return 0 ;;
ppc64le) return 0 ;;
mips) return 0 ;;
mipsle) return 0 ;;
mips64) return 0 ;;
mips64le) return 0 ;;
s390x) return 0 ;;
riscv64) return 0 ;;
amd64p32) return 0 ;;
loong64) return 0 ;;
esac
log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value."
return 1
}
untar() {
tarball=$1
case "${tarball}" in
*.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;;
*.tar) tar --no-same-owner -xf "${tarball}" ;;
*.zip) unzip "${tarball}" ;;
*)
log_err "untar unknown archive format for ${tarball}"
return 1
;;
esac
}
http_download_curl() {
local_file=$1
source_url=$2
header=$3
# workaround https://github.com/curl/curl/issues/13845
curl_version=$(curl --version | head -n 1 | awk '{ print $2 }')
if [ "$curl_version" = "8.8.0" ]; then
log_debug "http_download_curl curl $curl_version detected"
if [ -z "$header" ]; then
curl -sL -o "$local_file" "$source_url"
else
curl -sL -H "$header" -o "$local_file" "$source_url"
nf=$(cat "$local_file" | jq -r '.error // ""')
if [ ! -z "$nf" ]; then
log_debug "http_download_curl received an error: $nf"
return 1
fi
fi
return 0
fi
if [ -z "$header" ]; then
code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
else
code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
fi
if [ "$code" != "200" ]; then
log_err "http_download_curl received HTTP status $code"
return 1
fi
return 0
}
http_download_wget() {
local_file=$1
source_url=$2
header=$3
local wget_output
local code
if [ -z "$header" ]; then
wget_output=$(wget --server-response --quiet -O "$local_file" "$source_url" 2>&1)
else
wget_output=$(wget --server-response --quiet --header "$header" -O "$local_file" "$source_url" 2>&1)
fi
local wget_exit=$?
if [ $wget_exit -ne 0 ]; then
log_err "http_download_wget failed: wget exited with status $wget_exit"
return 1
fi
code=$(echo "$wget_output" | awk '/^ HTTP/{print $2}' | tail -n1)
if [ "$code" != "200" ]; then
log_err "http_download_wget received HTTP status $code"
return 1
fi
return 0
}
http_download() {
log_debug "http_download $2"
if is_command curl; then
http_download_curl "$@"
return
elif is_command wget; then
http_download_wget "$@"
return
fi
log_crit "http_download unable to find wget or curl"
return 1
}
http_copy() {
tmp=$(mktemp)
http_download "${tmp}" "$1" "$2" || return 1
body=$(cat "$tmp")
rm -f "${tmp}"
echo "$body"
}
github_release() {
owner_repo=$1
version=$2
test -z "$version" && version="latest"
giturl="https://github.com/${owner_repo}/releases/${version}"
json=$(http_copy "$giturl" "Accept:application/json")
test -z "$json" && return 1
version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
test -z "$version" && return 1
echo "$version"
}
hash_sha256() {
TARGET=${1:-/dev/stdin}
if is_command gsha256sum; then
hash=$(gsha256sum "$TARGET") || return 1
echo "$hash" | cut -d ' ' -f 1
elif is_command sha256sum; then
hash=$(sha256sum "$TARGET") || return 1
echo "$hash" | cut -d ' ' -f 1
elif is_command shasum; then
hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
echo "$hash" | cut -d ' ' -f 1
elif is_command openssl; then
hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
echo "$hash" | cut -d ' ' -f a
else
log_crit "hash_sha256 unable to find command to compute sha-256 hash"
return 1
fi
}
hash_sha256_verify() {
TARGET=$1
checksums=$2
if [ -z "$checksums" ]; then
log_err "hash_sha256_verify checksum file not specified in arg2"
return 1
fi
BASENAME=${TARGET##*/}
want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
if [ -z "$want" ]; then
log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
return 1
fi
got=$(hash_sha256 "$TARGET")
if [ "$want" != "$got" ]; then
log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
return 1
fi
}
cat /dev/null < \n"
hexSize = HashSize * 2
entrySize = 2 + 1 + hexSize + 1 + hexSize + 1 + 20 + 1 + 20 + 1
)
// verify controls whether to run the cache in verify mode.
// In verify mode, the cache always returns errMissing from Get
// but then double-checks in Put that the data being written
// exactly matches any existing entry. This provides an easy
// way to detect program behavior that would have been different
// had the cache entry been returned from Get.
//
// verify is enabled by setting the environment variable
// GODEBUG=gocacheverify=1.
var verify = false
var errVerifyMode = errors.New("gocacheverify=1")
// DebugTest is set when GODEBUG=gocachetest=1 is in the environment.
var DebugTest = false
// func init() { initEnv() }
//
// var (
// gocacheverify = godebug.New("gocacheverify")
// gocachehash = godebug.New("gocachehash")
// gocachetest = godebug.New("gocachetest")
// )
//
// func initEnv() {
// if gocacheverify.Value() == "1" {
// gocacheverify.IncNonDefault()
// verify = true
// }
// if gocachehash.Value() == "1" {
// gocachehash.IncNonDefault()
// debugHash = true
// }
// if gocachetest.Value() == "1" {
// gocachetest.IncNonDefault()
// DebugTest = true
// }
// }
// Get looks up the action ID in the cache,
// returning the corresponding output ID and file size, if any.
// Note that finding an output ID does not guarantee that the
// saved file for that output ID is still available.
func (c *DiskCache) Get(id ActionID) (Entry, error) {
if verify {
return Entry{}, &entryNotFoundError{Err: errVerifyMode}
}
return c.get(id)
}
type Entry struct {
OutputID OutputID
Size int64
Time time.Time // when added to cache
}
// get is Get but does not respect verify mode, so that Put can use it.
func (c *DiskCache) get(id ActionID) (Entry, error) {
missing := func(reason error) (Entry, error) {
return Entry{}, &entryNotFoundError{Err: reason}
}
f, err := os.Open(c.fileName(id, "a"))
if err != nil {
return missing(err)
}
defer f.Close()
entry := make([]byte, entrySize+1) // +1 to detect whether f is too long
if n, err := io.ReadFull(f, entry); n > entrySize {
return missing(errors.New("too long"))
} else if err != io.ErrUnexpectedEOF {
if err == io.EOF {
return missing(errors.New("file is empty"))
}
return missing(err)
} else if n < entrySize {
return missing(errors.New("entry file incomplete"))
}
if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' {
return missing(errors.New("invalid header"))
}
eid, entry := entry[3:3+hexSize], entry[3+hexSize:]
eout, entry := entry[1:1+hexSize], entry[1+hexSize:]
esize, entry := entry[1:1+20], entry[1+20:]
etime, entry := entry[1:1+20], entry[1+20:]
var buf [HashSize]byte
if _, err := hex.Decode(buf[:], eid); err != nil {
return missing(fmt.Errorf("decoding ID: %v", err))
} else if buf != id {
return missing(errors.New("mismatched ID"))
}
if _, err := hex.Decode(buf[:], eout); err != nil {
return missing(fmt.Errorf("decoding output ID: %v", err))
}
i := 0
for i < len(esize) && esize[i] == ' ' {
i++
}
size, err := strconv.ParseInt(string(esize[i:]), 10, 64)
if err != nil {
return missing(fmt.Errorf("parsing size: %v", err))
} else if size < 0 {
return missing(errors.New("negative size"))
}
i = 0
for i < len(etime) && etime[i] == ' ' {
i++
}
tm, err := strconv.ParseInt(string(etime[i:]), 10, 64)
if err != nil {
return missing(fmt.Errorf("parsing timestamp: %v", err))
} else if tm < 0 {
return missing(errors.New("negative timestamp"))
}
c.markUsed(c.fileName(id, "a"))
return Entry{buf, size, time.Unix(0, tm)}, nil
}
// GetFile looks up the action ID in the cache and returns
// the name of the corresponding data file.
func GetFile(c Cache, id ActionID) (file string, entry Entry, err error) {
entry, err = c.Get(id)
if err != nil {
return "", Entry{}, err
}
file = c.OutputFile(entry.OutputID)
info, err := os.Stat(file)
if err != nil {
return "", Entry{}, &entryNotFoundError{Err: err}
}
if info.Size() != entry.Size {
return "", Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")}
}
return file, entry, nil
}
// GetBytes looks up the action ID in the cache and returns
// the corresponding output bytes.
// GetBytes should only be used for data that can be expected to fit in memory.
func GetBytes(c Cache, id ActionID) ([]byte, Entry, error) {
entry, err := c.Get(id)
if err != nil {
return nil, entry, err
}
data, err := robustio.ReadFile(c.OutputFile(entry.OutputID))
if err != nil {
return nil, entry, &entryNotFoundError{Err: err}
}
if sha256.Sum256(data) != entry.OutputID {
return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")}
}
return data, entry, nil
}
// GetMmap looks up the action ID in the cache and returns
// the corresponding output bytes.
// GetMmap should only be used for data that can be expected to fit in memory.
func GetMmap(c Cache, id ActionID) ([]byte, Entry, bool, error) {
entry, err := c.Get(id)
if err != nil {
return nil, entry, false, err
}
md, opened, err := mmap.Mmap(c.OutputFile(entry.OutputID))
if err != nil {
return nil, Entry{}, opened, err
}
if int64(len(md.Data)) != entry.Size {
return nil, Entry{}, true, &entryNotFoundError{Err: errors.New("file incomplete")}
}
return md.Data, entry, true, nil
}
// OutputFile returns the name of the cache file storing output with the given OutputID.
func (c *DiskCache) OutputFile(out OutputID) string {
file := c.fileName(out, "d")
isDir := c.markUsed(file)
if isDir { // => cached executable
entries, err := os.ReadDir(file)
if err != nil {
return fmt.Sprintf("DO NOT USE - missing binary cache entry: %v", err)
}
if len(entries) != 1 {
return "DO NOT USE - invalid binary cache entry"
}
return filepath.Join(file, entries[0].Name())
}
return file
}
// Time constants for cache expiration.
//
// We set the mtime on a cache file on each use, but at most one per mtimeInterval (1 hour),
// to avoid causing many unnecessary inode updates. The mtimes therefore
// roughly reflect "time of last use" but may in fact be older by at most an hour.
//
// We scan the cache for entries to delete at most once per trimInterval (1 day).
//
// When we do scan the cache, we delete entries that have not been used for
// at least trimLimit (5 days). Statistics gathered from a month of usage by
// Go developers found that essentially all reuse of cached entries happened
// within 5 days of the previous reuse. See golang.org/issue/22990.
const (
mtimeInterval = 1 * time.Hour
trimInterval = 24 * time.Hour
trimLimit = 5 * 24 * time.Hour
)
// markUsed makes a best-effort attempt to update mtime on file,
// so that mtime reflects cache access time.
//
// Because the reflection only needs to be approximate,
// and to reduce the amount of disk activity caused by using
// cache entries, used only updates the mtime if the current
// mtime is more than an hour old. This heuristic eliminates
// nearly all of the mtime updates that would otherwise happen,
// while still keeping the mtimes useful for cache trimming.
//
// markUsed reports whether the file is a directory (an executable cache entry).
func (c *DiskCache) markUsed(file string) (isDir bool) {
info, err := os.Stat(file)
if err != nil {
return false
}
if now := c.now(); now.Sub(info.ModTime()) >= mtimeInterval {
os.Chtimes(file, now, now)
}
return info.IsDir()
}
func (c *DiskCache) Close() error { return c.Trim() }
// Trim removes old cache entries that are likely not to be reused.
func (c *DiskCache) Trim() error {
now := c.now()
// We maintain in dir/trim.txt the time of the last completed cache trim.
// If the cache has been trimmed recently enough, do nothing.
// This is the common case.
// If the trim file is corrupt, detected if the file can't be parsed, or the
// trim time is too far in the future, attempt the trim anyway. It's possible that
// the cache was full when the corruption happened. Attempting a trim on
// an empty cache is cheap, so there wouldn't be a big performance hit in that case.
if data, err := lockedfile.Read(filepath.Join(c.dir, "trim.txt")); err == nil {
if t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64); err == nil {
lastTrim := time.Unix(t, 0)
if d := now.Sub(lastTrim); d < trimInterval && d > -mtimeInterval {
return nil
}
}
}
// Trim each of the 256 subdirectories.
// We subtract an additional mtimeInterval
// to account for the imprecision of our "last used" mtimes.
cutoff := now.Add(-trimLimit - mtimeInterval)
for i := 0; i < 256; i++ {
subdir := filepath.Join(c.dir, fmt.Sprintf("%02x", i))
c.trimSubdir(subdir, cutoff)
}
// Ignore errors from here: if we don't write the complete timestamp, the
// cache will appear older than it is, and we'll trim it again next time.
var b bytes.Buffer
fmt.Fprintf(&b, "%d", now.Unix())
if err := lockedfile.Write(filepath.Join(c.dir, "trim.txt"), &b, 0o666); err != nil {
return err
}
return nil
}
// trimSubdir trims a single cache subdirectory.
func (c *DiskCache) trimSubdir(subdir string, cutoff time.Time) {
// Read all directory entries from subdir before removing
// any files, in case removing files invalidates the file offset
// in the directory scan. Also, ignore error from f.Readdirnames,
// because we don't care about reporting the error and we still
// want to process any entries found before the error.
f, err := os.Open(subdir)
if err != nil {
return
}
names, _ := f.Readdirnames(-1)
f.Close()
for _, name := range names {
// Remove only cache entries (xxxx-a and xxxx-d).
if !strings.HasSuffix(name, "-a") && !strings.HasSuffix(name, "-d") {
continue
}
entry := filepath.Join(subdir, name)
info, err := os.Stat(entry)
if err == nil && info.ModTime().Before(cutoff) {
if info.IsDir() { // executable cache entry
os.RemoveAll(entry)
continue
}
os.Remove(entry)
}
}
}
// putIndexEntry adds an entry to the cache recording that executing the action
// with the given id produces an output with the given output id (hash) and size.
func (c *DiskCache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error {
// Note: We expect that for one reason or another it may happen
// that repeating an action produces a different output hash
// (for example, if the output contains a time stamp or temp dir name).
// While not ideal, this is also not a correctness problem, so we
// don't make a big deal about it. In particular, we leave the action
// cache entries writable specifically so that they can be overwritten.
//
// Setting GODEBUG=gocacheverify=1 does make a big deal:
// in verify mode we are double-checking that the cache entries
// are entirely reproducible. As just noted, this may be unrealistic
// in some cases but the check is also useful for shaking out real bugs.
entry := fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano())
if verify && allowVerify {
old, err := c.get(id)
if err == nil && (old.OutputID != out || old.Size != size) {
// panic to show stack trace, so we can see what code is generating this cache entry.
msg := fmt.Sprintf("go: internal cache error: cache verify failed: id=%x changed:<<<\n%s\n>>>\nold: %x %d\nnew: %x %d", id, reverseHash(id), out, size, old.OutputID, old.Size)
panic(msg)
}
}
file := c.fileName(id, "a")
// Copy file to cache directory.
mode := os.O_WRONLY | os.O_CREATE
f, err := os.OpenFile(file, mode, 0o666)
if err != nil {
return err
}
_, err = f.WriteString(entry)
if err == nil {
// Truncate the file only *after* writing it.
// (This should be a no-op, but truncate just in case of previous corruption.)
//
// This differs from os.WriteFile, which truncates to 0 *before* writing
// via os.O_TRUNC. Truncating only after writing ensures that a second write
// of the same content to the same file is idempotent, and does not — even
// temporarily! — undo the effect of the first write.
err = f.Truncate(int64(len(entry)))
}
if closeErr := f.Close(); err == nil {
err = closeErr
}
if err != nil {
// TODO(bcmills): This Remove potentially races with another go command writing to file.
// Can we eliminate it?
os.Remove(file)
return err
}
err = os.Chtimes(file, c.now(), c.now()) // mainly for tests
if err != nil {
return fmt.Errorf("failed to change time of file %s: %w", file, err)
}
return nil
}
// noVerifyReadSeeker is an io.ReadSeeker wrapper sentinel type
// that says that Cache.Put should skip the verify check
// (from GODEBUG=goverifycache=1).
type noVerifyReadSeeker struct {
io.ReadSeeker
}
// Put stores the given output in the cache as the output for the action ID.
// It may read file twice. The content of file must not change between the two passes.
func (c *DiskCache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
wrapper, isNoVerify := file.(noVerifyReadSeeker)
if isNoVerify {
file = wrapper.ReadSeeker
}
return c.put(id, "", file, !isNoVerify)
}
// PutExecutable is used to store the output as the output for the action ID into a
// file with the given base name, with the executable mode bit set.
// It may read file twice. The content of file must not change between the two passes.
func (c *DiskCache) PutExecutable(id ActionID, name string, file io.ReadSeeker) (OutputID, int64, error) {
if name == "" {
panic("PutExecutable called without a name")
}
wrapper, isNoVerify := file.(noVerifyReadSeeker)
if isNoVerify {
file = wrapper.ReadSeeker
}
return c.put(id, name, file, !isNoVerify)
}
// PutNoVerify is like Put but disables the verify check
// when GODEBUG=goverifycache=1 is set.
// It is meant for data that is OK to cache but that we expect to vary slightly from run to run,
// like test output containing times and the like.
func PutNoVerify(c Cache, id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
return c.Put(id, noVerifyReadSeeker{file})
}
func (c *DiskCache) put(id ActionID, executableName string, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) {
// Compute output ID.
h := sha256.New()
if _, err := file.Seek(0, 0); err != nil {
return OutputID{}, 0, err
}
size, err := io.Copy(h, file)
if err != nil {
return OutputID{}, 0, err
}
var out OutputID
h.Sum(out[:0])
// Copy to cached output file (if not already present).
fileMode := fs.FileMode(0o666)
if executableName != "" {
fileMode = 0o777
}
if err := c.copyFile(file, executableName, out, size, fileMode); err != nil {
return out, size, err
}
// Add to cache index.
return out, size, c.putIndexEntry(id, out, size, allowVerify)
}
// PutBytes stores the given bytes in the cache as the output for the action ID.
func PutBytes(c Cache, id ActionID, data []byte) error {
_, _, err := c.Put(id, bytes.NewReader(data))
return err
}
// copyFile copies file into the cache, expecting it to have the given
// output ID and size, if that file is not present already.
func (c *DiskCache) copyFile(file io.ReadSeeker, executableName string, out OutputID, size int64, perm os.FileMode) error {
name := c.fileName(out, "d") // TODO(matloob): use a different suffix for the executable cache?
info, err := os.Stat(name)
if executableName != "" {
// This is an executable file. The file at name won't hold the output itself, but will
// be a directory that holds the output, named according to executableName. Check to see
// if the directory already exists, and if it does not, create it. Then reset name
// to the name we want the output written to.
if err != nil {
if !os.IsNotExist(err) {
return err
}
if err := os.Mkdir(name, 0o777); err != nil {
return err
}
if info, err = os.Stat(name); err != nil {
return err
}
}
if !info.IsDir() {
return errors.New("internal error: invalid binary cache entry: not a directory")
}
// directory exists. now set name to the inner file
name = filepath.Join(name, executableName)
info, err = os.Stat(name)
}
if err == nil && info.Size() == size {
// Check hash.
if f, err := os.Open(name); err == nil {
h := sha256.New()
_, copyErr := io.Copy(h, f)
if copyErr != nil {
return fmt.Errorf("failed to copy to sha256: %w", copyErr)
}
f.Close()
var out2 OutputID
h.Sum(out2[:0])
if out == out2 {
return nil
}
}
// Hash did not match. Fall through and rewrite file.
}
// Copy file to cache directory.
mode := os.O_RDWR | os.O_CREATE
if err == nil && info.Size() > size { // shouldn't happen but fix in case
mode |= os.O_TRUNC
}
f, err := os.OpenFile(name, mode, perm)
if err != nil {
if base.IsETXTBSY(err) {
// This file is being used by an executable. It must have
// already been written by another go process and then run.
// return without an error.
return nil
}
return err
}
defer f.Close()
if size == 0 {
// File now exists with correct size.
// Only one possible zero-length file, so contents are OK too.
// Early return here makes sure there's a "last byte" for code below.
return nil
}
// From here on, if any of the I/O writing the file fails,
// we make a best-effort attempt to truncate the file f
// before returning, to avoid leaving bad bytes in the file.
// Copy file to f, but also into h to double-check hash.
if _, err := file.Seek(0, 0); err != nil {
f.Truncate(0)
return err
}
h := sha256.New()
w := io.MultiWriter(f, h)
if _, err := io.CopyN(w, file, size-1); err != nil {
f.Truncate(0)
return err
}
// Check last byte before writing it; writing it will make the size match
// what other processes expect to find and might cause them to start
// using the file.
buf := make([]byte, 1)
if _, err := file.Read(buf); err != nil {
f.Truncate(0)
return err
}
n, wErr := h.Write(buf)
if n != len(buf) {
return fmt.Errorf("wrote to hash %d/%d bytes with error %w", n, len(buf), wErr)
}
sum := h.Sum(nil)
if !bytes.Equal(sum, out[:]) {
f.Truncate(0)
return fmt.Errorf("file content changed underfoot")
}
// Commit cache file entry.
if _, err := f.Write(buf); err != nil {
f.Truncate(0)
return err
}
if err := f.Close(); err != nil {
// Data might not have been written,
// but file may look like it is the right size.
// To be extra careful, remove cached file.
os.Remove(name)
return err
}
err = os.Chtimes(name, c.now(), c.now()) // mainly for tests
if err != nil {
return fmt.Errorf("failed to change time of file %s: %w", name, err)
}
return nil
}
// FuzzDir returns a subdirectory within the cache for storing fuzzing data.
// The subdirectory may not exist.
//
// This directory is managed by the internal/fuzz package. Files in this
// directory aren't removed by the 'go clean -cache' command or by Trim.
// They may be removed with 'go clean -fuzzcache'.
//
// TODO(#48526): make Trim remove unused files from this directory.
func (c *DiskCache) FuzzDir() string {
return filepath.Join(c.dir, "fuzz")
}
================================================
FILE: internal/go/cache/cache_gcil.go
================================================
package cache
import (
"errors"
)
// IsErrMissing allows to access to the internal error.
// TODO(ldez) the handling of this error inside runner_action.go should be refactored.
func IsErrMissing(err error) bool {
var errENF *entryNotFoundError
return errors.As(err, &errENF)
}
================================================
FILE: internal/go/cache/cache_test.go
================================================
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cache
import (
"bytes"
"encoding/binary"
"fmt"
"os"
"path/filepath"
"testing"
"time"
"github.com/golangci/golangci-lint/v2/internal/go/testenv"
)
func init() {
verify = false // even if GODEBUG is set
}
func TestBasic(t *testing.T) {
dir := t.TempDir()
_, err := Open(filepath.Join(dir, "notexist"))
if err == nil {
t.Fatal(`Open("tmp/notexist") succeeded, want failure`)
}
cdir := filepath.Join(dir, "c1")
if err := os.Mkdir(cdir, 0777); err != nil {
t.Fatal(err)
}
c1, err := Open(cdir)
if err != nil {
t.Fatalf("Open(c1) (create): %v", err)
}
if err := c1.putIndexEntry(dummyID(1), dummyID(12), 13, true); err != nil {
t.Fatalf("addIndexEntry: %v", err)
}
if err := c1.putIndexEntry(dummyID(1), dummyID(2), 3, true); err != nil { // overwrite entry
t.Fatalf("addIndexEntry: %v", err)
}
if entry, err := c1.Get(dummyID(1)); err != nil || entry.OutputID != dummyID(2) || entry.Size != 3 {
t.Fatalf("c1.Get(1) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(2), 3)
}
c2, err := Open(cdir)
if err != nil {
t.Fatalf("Open(c2) (reuse): %v", err)
}
if entry, err := c2.Get(dummyID(1)); err != nil || entry.OutputID != dummyID(2) || entry.Size != 3 {
t.Fatalf("c2.Get(1) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(2), 3)
}
if err := c2.putIndexEntry(dummyID(2), dummyID(3), 4, true); err != nil {
t.Fatalf("addIndexEntry: %v", err)
}
if entry, err := c1.Get(dummyID(2)); err != nil || entry.OutputID != dummyID(3) || entry.Size != 4 {
t.Fatalf("c1.Get(2) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(3), 4)
}
}
func TestGrowth(t *testing.T) {
c, err := Open(t.TempDir())
if err != nil {
t.Fatalf("Open: %v", err)
}
n := 10000
if testing.Short() {
n = 10
}
for i := 0; i < n; i++ {
if err := c.putIndexEntry(dummyID(i), dummyID(i*99), int64(i)*101, true); err != nil {
t.Fatalf("addIndexEntry: %v", err)
}
id := ActionID(dummyID(i))
entry, err := c.Get(id)
if err != nil {
t.Fatalf("Get(%x): %v", id, err)
}
if entry.OutputID != dummyID(i*99) || entry.Size != int64(i)*101 {
t.Errorf("Get(%x) = %x, %d, want %x, %d", id, entry.OutputID, entry.Size, dummyID(i*99), int64(i)*101)
}
}
for i := 0; i < n; i++ {
id := ActionID(dummyID(i))
entry, err := c.Get(id)
if err != nil {
t.Fatalf("Get2(%x): %v", id, err)
}
if entry.OutputID != dummyID(i*99) || entry.Size != int64(i)*101 {
t.Errorf("Get2(%x) = %x, %d, want %x, %d", id, entry.OutputID, entry.Size, dummyID(i*99), int64(i)*101)
}
}
}
// func TestVerifyPanic(t *testing.T) {
// os.Setenv("GODEBUG", "gocacheverify=1")
// initEnv()
// defer func() {
// os.Unsetenv("GODEBUG")
// verify = false
// }()
//
// if !verify {
// t.Fatal("initEnv did not set verify")
// }
//
// c, err := Open(t.TempDir())
// if err != nil {
// t.Fatalf("Open: %v", err)
// }
//
// id := ActionID(dummyID(1))
// if err := PutBytes(c, id, []byte("abc")); err != nil {
// t.Fatal(err)
// }
//
// defer func() {
// if err := recover(); err != nil {
// t.Log(err)
// return
// }
// }()
// PutBytes(c, id, []byte("def"))
// t.Fatal("mismatched Put did not panic in verify mode")
// }
func dummyID(x int) [HashSize]byte {
var out [HashSize]byte
binary.LittleEndian.PutUint64(out[:], uint64(x))
return out
}
func TestCacheTrim(t *testing.T) {
dir := t.TempDir()
c, err := Open(dir)
if err != nil {
t.Fatalf("Open: %v", err)
}
const start = 1000000000
now := int64(start)
c.now = func() time.Time { return time.Unix(now, 0) }
checkTime := func(name string, mtime int64) {
t.Helper()
file := filepath.Join(c.dir, name[:2], name)
info, err := os.Stat(file)
if err != nil {
t.Fatal(err)
}
if info.ModTime().Unix() != mtime {
t.Fatalf("%s mtime = %d, want %d", name, info.ModTime().Unix(), mtime)
}
}
id := ActionID(dummyID(1))
PutBytes(c, id, []byte("abc"))
entry, _ := c.Get(id)
PutBytes(c, ActionID(dummyID(2)), []byte("def"))
mtime := now
checkTime(fmt.Sprintf("%x-a", id), mtime)
checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime)
// Get should not change recent mtimes.
now = start + 10
c.Get(id)
checkTime(fmt.Sprintf("%x-a", id), mtime)
checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime)
// Get should change distant mtimes.
now = start + 5000
mtime2 := now
if _, err := c.Get(id); err != nil {
t.Fatal(err)
}
c.OutputFile(entry.OutputID)
checkTime(fmt.Sprintf("%x-a", id), mtime2)
checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime2)
// Trim should leave everything alone: it's all too new.
if err := c.Trim(); err != nil {
if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: Trim is unsupported (%v)", err)
}
t.Fatal(err)
}
if _, err := c.Get(id); err != nil {
t.Fatal(err)
}
c.OutputFile(entry.OutputID)
data, err := os.ReadFile(filepath.Join(dir, "trim.txt"))
if err != nil {
t.Fatal(err)
}
checkTime(fmt.Sprintf("%x-a", dummyID(2)), start)
// Trim less than a day later should not do any work at all.
now = start + 80000
if err := c.Trim(); err != nil {
t.Fatal(err)
}
if _, err := c.Get(id); err != nil {
t.Fatal(err)
}
c.OutputFile(entry.OutputID)
data2, err := os.ReadFile(filepath.Join(dir, "trim.txt"))
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(data, data2) {
t.Fatalf("second trim did work: %q -> %q", data, data2)
}
// Fast forward and do another trim just before the 5 day cutoff.
// Note that because of usedQuantum the cutoff is actually 5 days + 1 hour.
// We used c.Get(id) just now, so 5 days later it should still be kept.
// On the other hand almost a full day has gone by since we wrote dummyID(2)
// and we haven't looked at it since, so 5 days later it should be gone.
now += 5 * 86400
checkTime(fmt.Sprintf("%x-a", dummyID(2)), start)
if err := c.Trim(); err != nil {
t.Fatal(err)
}
if _, err := c.Get(id); err != nil {
t.Fatal(err)
}
c.OutputFile(entry.OutputID)
mtime3 := now
if _, err := c.Get(dummyID(2)); err == nil { // haven't done a Get for this since original write above
t.Fatalf("Trim did not remove dummyID(2)")
}
// The c.Get(id) refreshed id's mtime again.
// Check that another 5 days later it is still not gone,
// but check by using checkTime, which doesn't bring mtime forward.
now += 5 * 86400
if err := c.Trim(); err != nil {
t.Fatal(err)
}
checkTime(fmt.Sprintf("%x-a", id), mtime3)
checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime3)
// Half a day later Trim should still be a no-op, because there was a Trim recently.
// Even though the entry for id is now old enough to be trimmed,
// it gets a reprieve until the time comes for a new Trim scan.
now += 86400 / 2
if err := c.Trim(); err != nil {
t.Fatal(err)
}
checkTime(fmt.Sprintf("%x-a", id), mtime3)
checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime3)
// Another half a day later, Trim should actually run, and it should remove id.
now += 86400/2 + 1
if err := c.Trim(); err != nil {
t.Fatal(err)
}
if _, err := c.Get(dummyID(1)); err == nil {
t.Fatal("Trim did not remove dummyID(1)")
}
}
================================================
FILE: internal/go/cache/default.go
================================================
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cache
import (
"fmt"
base "log"
"os"
"path/filepath"
"sync"
)
// Default returns the default cache to use.
// It never returns nil.
func Default() Cache {
return initDefaultCacheOnce()
}
var initDefaultCacheOnce = sync.OnceValue(initDefaultCache)
// cacheREADME is a message stored in a README in the cache directory.
// Because the cache lives outside the normal Go trees, we leave the
// README as a courtesy to explain where it came from.
const cacheREADME = `This directory holds cached build artifacts from golangci-lint.
`
// initDefaultCache does the work of finding the default cache
// the first time Default is called.
func initDefaultCache() Cache {
dir, _ := DefaultDir()
if dir == "off" {
if defaultDirErr != nil {
base.Fatalf("build cache is required, but could not be located: %v", defaultDirErr)
}
base.Fatalf("build cache is disabled by %s=off, but required as of Go 1.12", envGolangciLintCache)
}
if err := os.MkdirAll(dir, 0o777); err != nil {
base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err)
}
if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
// Best effort.
os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666)
}
diskCache, err := Open(dir)
if err != nil {
base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err)
}
if v := os.Getenv(envGolangciLintCacheProg); v != "" {
return startCacheProg(v, diskCache)
}
return diskCache
}
var (
defaultDirOnce sync.Once
defaultDir string
defaultDirChanged bool // effective value differs from $GOLANGCI_LINT_CACHE
defaultDirErr error
)
// DefaultDir returns the effective GOLANGCI_LINT_CACHE setting.
// It returns "off" if the cache is disabled,
// and reports whether the effective value differs from GOLANGCI_LINT_CACHE.
func DefaultDir() (string, bool) {
// Save the result of the first call to DefaultDir for later use in
// initDefaultCache. cmd/go/main.go explicitly sets GOLANGCI_LINT_CACHE so that
// subprocesses will inherit it, but that means initDefaultCache can't
// otherwise distinguish between an explicit "off" and a UserCacheDir error.
defaultDirOnce.Do(func() {
defaultDir = os.Getenv(envGolangciLintCache)
if defaultDir != "" {
defaultDirChanged = true
if filepath.IsAbs(defaultDir) || defaultDir == "off" {
return
}
defaultDir = "off"
defaultDirErr = fmt.Errorf("%s is not an absolute path", envGolangciLintCache)
return
}
// Compute default location.
dir, err := os.UserCacheDir()
if err != nil {
defaultDir = "off"
defaultDirChanged = true
defaultDirErr = fmt.Errorf("%s is not defined and %w", envGolangciLintCache, err)
return
}
defaultDir = filepath.Join(dir, "golangci-lint")
})
return defaultDir, defaultDirChanged
}
================================================
FILE: internal/go/cache/default_gcil.go
================================================
package cache
const (
envGolangciLintCache = "GOLANGCI_LINT_CACHE"
envGolangciLintCacheProg = "GOLANGCI_LINT_CACHEPROG"
)
================================================
FILE: internal/go/cache/hash.go
================================================
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cache
import (
"bytes"
"crypto/sha256"
"fmt"
"hash"
"io"
"os"
"strings"
"sync"
)
var debugHash = false // set when GODEBUG=gocachehash=1
// HashSize is the number of bytes in a hash.
const HashSize = 32
// A Hash provides access to the canonical hash function used to index the cache.
// The current implementation uses salted SHA256, but clients must not assume this.
type Hash struct {
h hash.Hash
name string // for debugging
buf *bytes.Buffer // for verify
}
// hashSalt is a salt string added to the beginning of every hash
// created by NewHash. Using the golangci-lint version makes sure that different
// versions of the command do not address the same cache
// entries, so that a bug in one version does not affect the execution
// of other versions. This salt will result in additional ActionID files
// in the cache, but not additional copies of the large output files,
// which are still addressed by unsalted SHA256.
var hashSalt []byte
// stripExperiment strips any GOEXPERIMENT configuration from the Go
// version string.
func stripExperiment(version string) string {
if i := strings.Index(version, " X:"); i >= 0 {
return version[:i]
}
return version
}
// Subkey returns an action ID corresponding to mixing a parent
// action ID with a string description of the subkey.
func Subkey(parent ActionID, desc string) (ActionID, error) {
h := sha256.New()
h.Write([]byte("subkey:"))
n, err := h.Write(parent[:])
if n != len(parent) {
return ActionID{}, fmt.Errorf("wrote %d/%d bytes of parent with error %s", n, len(parent), err)
}
n, err = h.Write([]byte(desc))
if n != len(desc) {
return ActionID{}, fmt.Errorf("wrote %d/%d bytes of desc with error %s", n, len(desc), err)
}
var out ActionID
h.Sum(out[:0])
if debugHash {
fmt.Fprintf(os.Stderr, "HASH subkey %x %q = %x\n", parent, desc, out)
}
if verify {
hashDebug.Lock()
hashDebug.m[out] = fmt.Sprintf("subkey %x %q", parent, desc)
hashDebug.Unlock()
}
return out, nil
}
// NewHash returns a new Hash.
// The caller is expected to Write data to it and then call Sum.
func NewHash(name string) (*Hash, error) {
h := &Hash{h: sha256.New(), name: name}
if debugHash {
fmt.Fprintf(os.Stderr, "HASH[%s]\n", h.name)
}
n, err := h.Write(hashSalt)
if n != len(hashSalt) {
return nil, fmt.Errorf("wrote %d/%d bytes of hash salt with error %s", n, len(hashSalt), err)
}
if verify {
h.buf = new(bytes.Buffer)
}
return h, nil
}
// Write writes data to the running hash.
func (h *Hash) Write(b []byte) (int, error) {
if debugHash {
fmt.Fprintf(os.Stderr, "HASH[%s]: %q\n", h.name, b)
}
if h.buf != nil {
h.buf.Write(b)
}
return h.h.Write(b)
}
// Sum returns the hash of the data written previously.
func (h *Hash) Sum() [HashSize]byte {
var out [HashSize]byte
h.h.Sum(out[:0])
if debugHash {
fmt.Fprintf(os.Stderr, "HASH[%s]: %x\n", h.name, out)
}
if h.buf != nil {
hashDebug.Lock()
if hashDebug.m == nil {
hashDebug.m = make(map[[HashSize]byte]string)
}
hashDebug.m[out] = h.buf.String()
hashDebug.Unlock()
}
return out
}
// In GODEBUG=gocacheverify=1 mode,
// hashDebug holds the input to every computed hash ID,
// so that we can work backward from the ID involved in a
// cache entry mismatch to a description of what should be there.
var hashDebug struct {
sync.Mutex
m map[[HashSize]byte]string
}
// reverseHash returns the input used to compute the hash id.
func reverseHash(id [HashSize]byte) string {
hashDebug.Lock()
s := hashDebug.m[id]
hashDebug.Unlock()
return s
}
var hashFileCache struct {
sync.Mutex
m map[string][HashSize]byte
}
// FileHash returns the hash of the named file.
// It caches repeated lookups for a given file,
// and the cache entry for a file can be initialized
// using SetFileHash.
// The hash used by FileHash is not the same as
// the hash used by NewHash.
func FileHash(file string) ([HashSize]byte, error) {
hashFileCache.Lock()
out, ok := hashFileCache.m[file]
hashFileCache.Unlock()
if ok {
return out, nil
}
h := sha256.New()
f, err := os.Open(file)
if err != nil {
if debugHash {
fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err)
}
return [HashSize]byte{}, err
}
_, err = io.Copy(h, f)
f.Close()
if err != nil {
if debugHash {
fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err)
}
return [HashSize]byte{}, err
}
h.Sum(out[:0])
if debugHash {
fmt.Fprintf(os.Stderr, "HASH %s: %x\n", file, out)
}
SetFileHash(file, out)
return out, nil
}
// SetFileHash sets the hash returned by FileHash for file.
func SetFileHash(file string, sum [HashSize]byte) {
hashFileCache.Lock()
if hashFileCache.m == nil {
hashFileCache.m = make(map[string][HashSize]byte)
}
hashFileCache.m[file] = sum
hashFileCache.Unlock()
}
================================================
FILE: internal/go/cache/hash_gcil.go
================================================
package cache
func SetSalt(b []byte) {
hashSalt = b
}
================================================
FILE: internal/go/cache/hash_test.go
================================================
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cache
import (
"fmt"
"os"
"testing"
)
func TestHash(t *testing.T) {
oldSalt := hashSalt
hashSalt = nil
defer func() {
hashSalt = oldSalt
}()
h, _ := NewHash("alice")
h.Write([]byte("hello world"))
sum := fmt.Sprintf("%x", h.Sum())
want := "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
if sum != want {
t.Errorf("hash(hello world) = %v, want %v", sum, want)
}
}
func TestHashFile(t *testing.T) {
f, err := os.CreateTemp("", "cmd-go-test-")
if err != nil {
t.Fatal(err)
}
name := f.Name()
fmt.Fprintf(f, "hello world")
defer os.Remove(name)
if err := f.Close(); err != nil {
t.Fatal(err)
}
var h ActionID // make sure hash result is assignable to ActionID
h, err = FileHash(name)
if err != nil {
t.Fatal(err)
}
sum := fmt.Sprintf("%x", h)
want := "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
if sum != want {
t.Errorf("hash(hello world) = %v, want %v", sum, want)
}
}
================================================
FILE: internal/go/cache/prog.go
================================================
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cache
import (
"bufio"
"context"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"log"
base "log"
"os"
"os/exec"
"sync"
"sync/atomic"
"time"
"github.com/golangci/golangci-lint/v2/internal/go/cacheprog"
"github.com/golangci/golangci-lint/v2/internal/go/quoted"
)
// ProgCache implements Cache via JSON messages over stdin/stdout to a child
// helper process which can then implement whatever caching policy/mechanism it
// wants.
//
// See https://github.com/golang/go/issues/59719
type ProgCache struct {
cmd *exec.Cmd
stdout io.ReadCloser // from the child process
stdin io.WriteCloser // to the child process
bw *bufio.Writer // to stdin
jenc *json.Encoder // to bw
// can are the commands that the child process declared that it supports.
// This is effectively the versioning mechanism.
can map[cacheprog.Cmd]bool
// fuzzDirCache is another Cache implementation to use for the FuzzDir
// method. In practice this is the default GOCACHE disk-based
// implementation.
//
// TODO(bradfitz): maybe this isn't ideal. But we'd need to extend the Cache
// interface and the fuzzing callers to be less disk-y to do more here.
fuzzDirCache Cache
closing atomic.Bool
ctx context.Context // valid until Close via ctxClose
ctxCancel context.CancelFunc // called on Close
readLoopDone chan struct{} // closed when readLoop returns
mu sync.Mutex // guards following fields
nextID int64
inFlight map[int64]chan<- *cacheprog.Response
outputFile map[OutputID]string // object => abs path on disk
// writeMu serializes writing to the child process.
// It must never be held at the same time as mu.
writeMu sync.Mutex
}
// startCacheProg starts the prog binary (with optional space-separated flags)
// and returns a Cache implementation that talks to it.
//
// It blocks a few seconds to wait for the child process to successfully start
// and advertise its capabilities.
func startCacheProg(progAndArgs string, fuzzDirCache Cache) Cache {
if fuzzDirCache == nil {
panic("missing fuzzDirCache")
}
args, err := quoted.Split(progAndArgs)
if err != nil {
base.Fatalf("%s args: %v", envGolangciLintCacheProg, err)
}
var prog string
if len(args) > 0 {
prog = args[0]
args = args[1:]
}
ctx, ctxCancel := context.WithCancel(context.Background())
cmd := exec.CommandContext(ctx, prog, args...)
out, err := cmd.StdoutPipe()
if err != nil {
base.Fatalf("StdoutPipe to %s: envGolangciLintCacheProg, %v", envGolangciLintCacheProg, err)
}
in, err := cmd.StdinPipe()
if err != nil {
base.Fatalf("StdinPipe to %s: envGolangciLintCacheProg, %v", envGolangciLintCacheProg, err)
}
cmd.Stderr = os.Stderr
// On close, we cancel the context. Rather than killing the helper,
// close its stdin.
cmd.Cancel = in.Close
if err := cmd.Start(); err != nil {
base.Fatalf("error starting %s program %q: %v", envGolangciLintCacheProg, prog, err)
}
pc := &ProgCache{
ctx: ctx,
ctxCancel: ctxCancel,
fuzzDirCache: fuzzDirCache,
cmd: cmd,
stdout: out,
stdin: in,
bw: bufio.NewWriter(in),
inFlight: make(map[int64]chan<- *cacheprog.Response),
outputFile: make(map[OutputID]string),
readLoopDone: make(chan struct{}),
}
// Register our interest in the initial protocol message from the child to
// us, saying what it can do.
capResc := make(chan *cacheprog.Response, 1)
pc.inFlight[0] = capResc
pc.jenc = json.NewEncoder(pc.bw)
go pc.readLoop(pc.readLoopDone)
// Give the child process a few seconds to report its capabilities. This
// should be instant and not require any slow work by the program.
timer := time.NewTicker(5 * time.Second)
defer timer.Stop()
for {
select {
case <-timer.C:
log.Printf("# still waiting for %s %v ...", envGolangciLintCacheProg, prog)
case capRes := <-capResc:
can := map[cacheprog.Cmd]bool{}
for _, cmd := range capRes.KnownCommands {
can[cmd] = true
}
if len(can) == 0 {
base.Fatalf("%s %v declared no supported commands", envGolangciLintCacheProg, prog)
}
pc.can = can
return pc
}
}
}
func (c *ProgCache) readLoop(readLoopDone chan<- struct{}) {
defer close(readLoopDone)
jd := json.NewDecoder(c.stdout)
for {
res := new(cacheprog.Response)
if err := jd.Decode(res); err != nil {
if c.closing.Load() {
c.mu.Lock()
for _, ch := range c.inFlight {
close(ch)
}
c.inFlight = nil
c.mu.Unlock()
return // quietly
}
if err == io.EOF {
c.mu.Lock()
inFlight := len(c.inFlight)
c.mu.Unlock()
base.Fatalf("%s exited pre-Close with %v pending requests", envGolangciLintCacheProg, inFlight)
}
base.Fatalf("error reading JSON from %s: %v", envGolangciLintCacheProg, err)
}
c.mu.Lock()
ch, ok := c.inFlight[res.ID]
delete(c.inFlight, res.ID)
c.mu.Unlock()
if ok {
ch <- res
} else {
base.Fatalf("%s sent response for unknown request ID %v", envGolangciLintCacheProg, res.ID)
}
}
}
var errCacheprogClosed = fmt.Errorf("%s program closed unexpectedly", envGolangciLintCacheProg)
func (c *ProgCache) send(ctx context.Context, req *cacheprog.Request) (*cacheprog.Response, error) {
resc := make(chan *cacheprog.Response, 1)
if err := c.writeToChild(req, resc); err != nil {
return nil, err
}
select {
case res := <-resc:
if res == nil {
return nil, errCacheprogClosed
}
if res.Err != "" {
return nil, errors.New(res.Err)
}
return res, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (c *ProgCache) writeToChild(req *cacheprog.Request, resc chan<- *cacheprog.Response) (err error) {
c.mu.Lock()
if c.inFlight == nil {
return errCacheprogClosed
}
c.nextID++
req.ID = c.nextID
c.inFlight[req.ID] = resc
c.mu.Unlock()
defer func() {
if err != nil {
c.mu.Lock()
if c.inFlight != nil {
delete(c.inFlight, req.ID)
}
c.mu.Unlock()
}
}()
c.writeMu.Lock()
defer c.writeMu.Unlock()
if err := c.jenc.Encode(req); err != nil {
return err
}
if err := c.bw.WriteByte('\n'); err != nil {
return err
}
if req.Body != nil && req.BodySize > 0 {
if err := c.bw.WriteByte('"'); err != nil {
return err
}
e := base64.NewEncoder(base64.StdEncoding, c.bw)
wrote, err := io.Copy(e, req.Body)
if err != nil {
return err
}
if err := e.Close(); err != nil {
return nil
}
if wrote != req.BodySize {
return fmt.Errorf("short write writing body to %s for action %x, output %x: wrote %v; expected %v",
envGolangciLintCacheProg, req.ActionID, req.OutputID, wrote, req.BodySize)
}
if _, err := c.bw.WriteString("\"\n"); err != nil {
return err
}
}
if err := c.bw.Flush(); err != nil {
return err
}
return nil
}
func (c *ProgCache) Get(a ActionID) (Entry, error) {
if !c.can[cacheprog.CmdGet] {
// They can't do a "get". Maybe they're a write-only cache.
//
// TODO(bradfitz,bcmills): figure out the proper error type here. Maybe
// errors.ErrUnsupported? Is entryNotFoundError even appropriate? There
// might be places where we rely on the fact that a recent Put can be
// read through a corresponding Get. Audit callers and check, and document
// error types on the Cache interface.
return Entry{}, &entryNotFoundError{}
}
res, err := c.send(c.ctx, &cacheprog.Request{
Command: cacheprog.CmdGet,
ActionID: a[:],
})
if err != nil {
return Entry{}, err // TODO(bradfitz): or entryNotFoundError? Audit callers.
}
if res.Miss {
return Entry{}, &entryNotFoundError{}
}
e := Entry{
Size: res.Size,
}
if res.Time != nil {
e.Time = *res.Time
} else {
e.Time = time.Now()
}
if res.DiskPath == "" {
return Entry{}, &entryNotFoundError{fmt.Errorf("%s didn't populate DiskPath on get hit", envGolangciLintCacheProg)}
}
if copy(e.OutputID[:], res.OutputID) != len(res.OutputID) {
return Entry{}, &entryNotFoundError{errors.New("incomplete ProgResponse OutputID")}
}
c.noteOutputFile(e.OutputID, res.DiskPath)
return e, nil
}
func (c *ProgCache) noteOutputFile(o OutputID, diskPath string) {
c.mu.Lock()
defer c.mu.Unlock()
c.outputFile[o] = diskPath
}
func (c *ProgCache) OutputFile(o OutputID) string {
c.mu.Lock()
defer c.mu.Unlock()
return c.outputFile[o]
}
func (c *ProgCache) Put(a ActionID, file io.ReadSeeker) (_ OutputID, size int64, _ error) {
// Compute output ID.
h := sha256.New()
if _, err := file.Seek(0, 0); err != nil {
return OutputID{}, 0, err
}
size, err := io.Copy(h, file)
if err != nil {
return OutputID{}, 0, err
}
var out OutputID
h.Sum(out[:0])
if _, err := file.Seek(0, 0); err != nil {
return OutputID{}, 0, err
}
if !c.can[cacheprog.CmdPut] {
// Child is a read-only cache. Do nothing.
return out, size, nil
}
res, err := c.send(c.ctx, &cacheprog.Request{
Command: cacheprog.CmdPut,
ActionID: a[:],
OutputID: out[:],
Body: file,
BodySize: size,
})
if err != nil {
return OutputID{}, 0, err
}
if res.DiskPath == "" {
return OutputID{}, 0, fmt.Errorf("%s didn't return DiskPath in put response", envGolangciLintCacheProg)
}
c.noteOutputFile(out, res.DiskPath)
return out, size, err
}
func (c *ProgCache) Close() error {
c.closing.Store(true)
var err error
// First write a "close" message to the child so it can exit nicely
// and clean up if it wants. Only after that exchange do we cancel
// the context that kills the process.
if c.can[cacheprog.CmdClose] {
_, err = c.send(c.ctx, &cacheprog.Request{Command: cacheprog.CmdClose})
if errors.Is(err, errCacheprogClosed) {
// Allow the child to quit without responding to close.
err = nil
}
}
// Cancel the context, which will close the helper's stdin.
c.ctxCancel()
// Wait until the helper closes its stdout.
<-c.readLoopDone
return err
}
func (c *ProgCache) FuzzDir() string {
// TODO(bradfitz): figure out what to do here. For now just use the
// disk-based default.
return c.fuzzDirCache.FuzzDir()
}
================================================
FILE: internal/go/cache/readme.md
================================================
# cache
Extracted from `go/src/cmd/go/internal/cache/`.
The main modifications are:
- The errors management
- Some methods return error.
- Some errors are returned instead of being ignored.
- The name of the env vars:
- `GOCACHE` -> `GOLANGCI_LINT_CACHE`
- `GOCACHEPROG` -> `GOLANGCI_LINT_CACHEPROG`
## History
- https://github.com/golangci/golangci-lint/pull/5576
- sync go1.24.1
- https://github.com/golangci/golangci-lint/pull/5100
- Move package from `internal/cache` to `internal/go/cache`
- https://github.com/golangci/golangci-lint/pull/5098
- sync with go1.23.2
- sync with go1.22.8
- sync with go1.21.13
- sync with go1.20.14
- sync with go1.19.13
- sync with go1.18.10
- sync with go1.17.13
- sync with go1.16.15
- sync with go1.15.15
- sync with go1.14.15
## Previous History
Based on the initial PR/commit the based in a mix between go1.12 and go1.13:
- cache.go (go1.13)
- cache_test.go (go1.12?)
- default.go (go1.12?)
- hash.go (go1.13 and go1.12 are identical)
- hash_test.go -> (go1.12?)
Adapted for golangci-lint:
- https://github.com/golangci/golangci-lint/pull/699: initial code (contains modifications of the files)
- https://github.com/golangci/golangci-lint/pull/779: just a nolint (`cache.go`)
- https://github.com/golangci/golangci-lint/pull/788: only directory permissions changes (0777 -> 0744) (`cache.go`, `cache_test.go`, `default.go`)
- https://github.com/golangci/golangci-lint/pull/808: mainly related to logs and errors (`cache.go`, `default.go`, `hash.go`, `hash_test.go`)
- https://github.com/golangci/golangci-lint/pull/1063: `ioutil` -> `robustio` (`cache.go`)
- https://github.com/golangci/golangci-lint/pull/1070: add `t.Parallel()` inside `cache_test.go`
- https://github.com/golangci/golangci-lint/pull/1162: errors inside `cache.go`
- https://github.com/golangci/golangci-lint/pull/2318: `ioutil` -> `os` (`cache.go`, `cache_test.go`, `default.go`, `hash_test.go`)
- https://github.com/golangci/golangci-lint/pull/2352: Go doc typos
- https://github.com/golangci/golangci-lint/pull/3012: errors inside `cache.go` (`cache.go`, `default.go`)
- https://github.com/golangci/golangci-lint/pull/3196: constant for `GOLANGCI_LINT_CACHE` (`cache.go`)
- https://github.com/golangci/golangci-lint/pull/3204: add this file and `%w` in `fmt.Errorf` (`cache.go`)
- https://github.com/golangci/golangci-lint/pull/3604: remove `github.com/pkg/errors` (`cache.go`)
================================================
FILE: internal/go/cacheprog/cacheprog.go
================================================
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package cacheprog defines the protocol for a GOCACHEPROG program.
//
// By default, the go command manages a build cache stored in the file system
// itself. GOCACHEPROG can be set to the name of a command (with optional
// space-separated flags) that implements the go command build cache externally.
// This permits defining a different cache policy.
//
// The go command will start the GOCACHEPROG as a subprocess and communicate
// with it via JSON messages over stdin/stdout. The subprocess's stderr will be
// connected to the go command's stderr.
//
// The subprocess should immediately send a [Response] with its capabilities.
// After that, the go command will send a stream of [Request] messages and the
// subprocess should reply to each [Request] with a [Response] message.
package cacheprog
import (
"io"
"time"
)
// Cmd is a command that can be issued to a child process.
//
// If the interface needs to grow, the go command can add new commands or new
// versioned commands like "get2" in the future. The initial [Response] from
// the child process indicates which commands it supports.
type Cmd string
const (
// CmdPut tells the cache program to store an object in the cache.
//
// [Request.ActionID] is the cache key of this object. The cache should
// store [Request.OutputID] and [Request.Body] under this key for a
// later "get" request. It must also store the Body in a file in the local
// file system and return the path to that file in [Response.DiskPath],
// which must exist at least until a "close" request.
CmdPut = Cmd("put")
// CmdGet tells the cache program to retrieve an object from the cache.
//
// [Request.ActionID] specifies the key of the object to get. If the
// cache does not contain this object, it should set [Response.Miss] to
// true. Otherwise, it should populate the fields of [Response],
// including setting [Response.OutputID] to the OutputID of the original
// "put" request and [Response.DiskPath] to the path of a local file
// containing the Body of the original "put" request. That file must
// continue to exist at least until a "close" request.
CmdGet = Cmd("get")
// CmdClose requests that the cache program exit gracefully.
//
// The cache program should reply to this request and then exit
// (thus closing its stdout).
CmdClose = Cmd("close")
)
// Request is the JSON-encoded message that's sent from the go command to
// the GOCACHEPROG child process over stdin. Each JSON object is on its own
// line. A ProgRequest of Type "put" with BodySize > 0 will be followed by a
// line containing a base64-encoded JSON string literal of the body.
type Request struct {
// ID is a unique number per process across all requests.
// It must be echoed in the Response from the child.
ID int64
// Command is the type of request.
// The go command will only send commands that were declared
// as supported by the child.
Command Cmd
// ActionID is the cache key for "put" and "get" requests.
ActionID []byte `json:",omitempty"` // or nil if not used
// OutputID is stored with the body for "put" requests.
//
// Prior to Go 1.24, when GOCACHEPROG was still an experiment, this was
// accidentally named ObjectID. It was renamed to OutputID in Go 1.24.
OutputID []byte `json:",omitempty"` // or nil if not used
// Body is the body for "put" requests. It's sent after the JSON object
// as a base64-encoded JSON string when BodySize is non-zero.
// It's sent as a separate JSON value instead of being a struct field
// send in this JSON object so large values can be streamed in both directions.
// The base64 string body of a Request will always be written
// immediately after the JSON object and a newline.
Body io.Reader `json:"-"`
// BodySize is the number of bytes of Body. If zero, the body isn't written.
BodySize int64 `json:",omitempty"`
// ObjectID is the accidental spelling of OutputID that was used prior to Go
// 1.24.
//
// Deprecated: use OutputID. This field is only populated temporarily for
// backwards compatibility with Go 1.23 and earlier when
// GOEXPERIMENT=gocacheprog is set. It will be removed in Go 1.25.
ObjectID []byte `json:",omitempty"`
}
// Response is the JSON response from the child process to the go command.
//
// With the exception of the first protocol message that the child writes to its
// stdout with ID==0 and KnownCommands populated, these are only sent in
// response to a Request from the go command.
//
// Responses can be sent in any order. The ID must match the request they're
// replying to.
type Response struct {
ID int64 // that corresponds to Request; they can be answered out of order
Err string `json:",omitempty"` // if non-empty, the error
// KnownCommands is included in the first message that cache helper program
// writes to stdout on startup (with ID==0). It includes the
// Request.Command types that are supported by the program.
//
// This lets the go command extend the protocol gracefully over time (adding
// "get2", etc), or fail gracefully when needed. It also lets the go command
// verify the program wants to be a cache helper.
KnownCommands []Cmd `json:",omitempty"`
// For "get" requests.
Miss bool `json:",omitempty"` // cache miss
OutputID []byte `json:",omitempty"` // the ObjectID stored with the body
Size int64 `json:",omitempty"` // body size in bytes
Time *time.Time `json:",omitempty"` // when the object was put in the cache (optional; used for cache expiration)
// For "get" and "put" requests.
// DiskPath is the absolute path on disk of the body corresponding to a
// "get" (on cache hit) or "put" request's ActionID.
DiskPath string `json:",omitempty"`
}
================================================
FILE: internal/go/cacheprog/readme.md
================================================
# quoted
Extracted from `go/src/cmd/go/internal/cacheprog/` (related to `cache`).
This is just a copy of the Go code without any changes.
## History
- https://github.com/golangci/golangci-lint/pull/5576
- sync go1.24.1
================================================
FILE: internal/go/mmap/mmap.go
================================================
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This package is a lightly modified version of the mmap code
// in github.com/google/codesearch/index.
// The mmap package provides an abstraction for memory mapping files
// on different platforms.
package mmap
import (
"os"
)
// Data is mmap'ed read-only data from a file.
// The backing file is never closed, so Data
// remains valid for the lifetime of the process.
type Data struct {
f *os.File
Data []byte
}
// Mmap maps the given file into memory.
func Mmap(file string) (Data, bool, error) {
f, err := os.Open(file)
if err != nil {
return Data{}, false, err
}
data, err := mmapFile(f)
return data, true, err
}
================================================
FILE: internal/go/mmap/mmap_other.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (js && wasm) || wasip1 || plan9
package mmap
import (
"io"
"os"
)
// mmapFile on other systems doesn't mmap the file. It just reads everything.
func mmapFile(f *os.File) (Data, error) {
b, err := io.ReadAll(f)
if err != nil {
return Data{}, err
}
return Data{f, b}, nil
}
================================================
FILE: internal/go/mmap/mmap_unix.go
================================================
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build unix
package mmap
import (
"fmt"
"io/fs"
"os"
"syscall"
)
func mmapFile(f *os.File) (Data, error) {
st, err := f.Stat()
if err != nil {
return Data{}, err
}
size := st.Size()
pagesize := int64(os.Getpagesize())
if int64(int(size+(pagesize-1))) != size+(pagesize-1) {
return Data{}, fmt.Errorf("%s: too large for mmap", f.Name())
}
n := int(size)
if n == 0 {
return Data{f, nil}, nil
}
mmapLength := int(((size + pagesize - 1) / pagesize) * pagesize) // round up to page size
data, err := syscall.Mmap(int(f.Fd()), 0, mmapLength, syscall.PROT_READ, syscall.MAP_SHARED)
if err != nil {
return Data{}, &fs.PathError{Op: "mmap", Path: f.Name(), Err: err}
}
return Data{f, data[:n]}, nil
}
================================================
FILE: internal/go/mmap/mmap_windows.go
================================================
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mmap
import (
"fmt"
"os"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
func mmapFile(f *os.File) (Data, error) {
st, err := f.Stat()
if err != nil {
return Data{}, err
}
size := st.Size()
if size == 0 {
return Data{f, nil}, nil
}
h, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, 0, 0, nil)
if err != nil {
return Data{}, fmt.Errorf("CreateFileMapping %s: %w", f.Name(), err)
}
addr, err := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, 0)
if err != nil {
return Data{}, fmt.Errorf("MapViewOfFile %s: %w", f.Name(), err)
}
var info windows.MemoryBasicInformation
err = windows.VirtualQuery(addr, &info, unsafe.Sizeof(info))
if err != nil {
return Data{}, fmt.Errorf("VirtualQuery %s: %w", f.Name(), err)
}
data := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.RegionSize))
if len(data) < int(size) {
// In some cases, especially on 386, we may not receive a in incomplete mapping:
// one that is shorter than the file itself. Return an error in those cases because
// incomplete mappings are not useful.
return Data{}, fmt.Errorf("mmapFile: received incomplete mapping of file")
}
return Data{f, data[:int(size)]}, nil
}
================================================
FILE: internal/go/mmap/readme.md
================================================
# mmap
Extracted from `go/src/cmd/go/internal/mmap/` (related to `cache`).
This is just a copy of the Go code without any changes.
## History
- https://github.com/golangci/golangci-lint/pull/5576
- sync go1.24.1
- https://github.com/golangci/golangci-lint/pull/5100
- Move package from `internal/mmap` to `internal/go/mmap`
- https://github.com/golangci/golangci-lint/pull/5098
- sync with go1.23.2
- sync with go1.22.8
- sync with go1.21.13
- sync with go1.20.14
- sync with go1.19.13
================================================
FILE: internal/go/quoted/quoted.go
================================================
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package quoted provides string manipulation utilities.
package quoted
import (
"flag"
"fmt"
"strings"
"unicode"
)
func isSpaceByte(c byte) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
}
// Split splits s into a list of fields,
// allowing single or double quotes around elements.
// There is no unescaping or other processing within
// quoted fields.
//
// Keep in sync with cmd/dist/quoted.go
func Split(s string) ([]string, error) {
// Split fields allowing '' or "" around elements.
// Quotes further inside the string do not count.
var f []string
for len(s) > 0 {
for len(s) > 0 && isSpaceByte(s[0]) {
s = s[1:]
}
if len(s) == 0 {
break
}
// Accepted quoted string. No unescaping inside.
if s[0] == '"' || s[0] == '\'' {
quote := s[0]
s = s[1:]
i := 0
for i < len(s) && s[i] != quote {
i++
}
if i >= len(s) {
return nil, fmt.Errorf("unterminated %c string", quote)
}
f = append(f, s[:i])
s = s[i+1:]
continue
}
i := 0
for i < len(s) && !isSpaceByte(s[i]) {
i++
}
f = append(f, s[:i])
s = s[i:]
}
return f, nil
}
// Join joins a list of arguments into a string that can be parsed
// with Split. Arguments are quoted only if necessary; arguments
// without spaces or quotes are kept as-is. No argument may contain both
// single and double quotes.
func Join(args []string) (string, error) {
var buf []byte
for i, arg := range args {
if i > 0 {
buf = append(buf, ' ')
}
var sawSpace, sawSingleQuote, sawDoubleQuote bool
for _, c := range arg {
switch {
case c > unicode.MaxASCII:
continue
case isSpaceByte(byte(c)):
sawSpace = true
case c == '\'':
sawSingleQuote = true
case c == '"':
sawDoubleQuote = true
}
}
switch {
case !sawSpace && !sawSingleQuote && !sawDoubleQuote:
buf = append(buf, arg...)
case !sawSingleQuote:
buf = append(buf, '\'')
buf = append(buf, arg...)
buf = append(buf, '\'')
case !sawDoubleQuote:
buf = append(buf, '"')
buf = append(buf, arg...)
buf = append(buf, '"')
default:
return "", fmt.Errorf("argument %q contains both single and double quotes and cannot be quoted", arg)
}
}
return string(buf), nil
}
// A Flag parses a list of string arguments encoded with Join.
// It is useful for flags like cmd/link's -extldflags.
type Flag []string
var _ flag.Value = (*Flag)(nil)
func (f *Flag) Set(v string) error {
fs, err := Split(v)
if err != nil {
return err
}
*f = fs[:len(fs):len(fs)]
return nil
}
func (f *Flag) String() string {
if f == nil {
return ""
}
s, err := Join(*f)
if err != nil {
return strings.Join(*f, " ")
}
return s
}
================================================
FILE: internal/go/quoted/quoted_test.go
================================================
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package quoted
import (
"reflect"
"strings"
"testing"
)
func TestSplit(t *testing.T) {
for _, test := range []struct {
name string
value string
want []string
wantErr string
}{
{name: "empty", value: "", want: nil},
{name: "space", value: " ", want: nil},
{name: "one", value: "a", want: []string{"a"}},
{name: "leading_space", value: " a", want: []string{"a"}},
{name: "trailing_space", value: "a ", want: []string{"a"}},
{name: "two", value: "a b", want: []string{"a", "b"}},
{name: "two_multi_space", value: "a b", want: []string{"a", "b"}},
{name: "two_tab", value: "a\tb", want: []string{"a", "b"}},
{name: "two_newline", value: "a\nb", want: []string{"a", "b"}},
{name: "quote_single", value: `'a b'`, want: []string{"a b"}},
{name: "quote_double", value: `"a b"`, want: []string{"a b"}},
{name: "quote_both", value: `'a '"b "`, want: []string{"a ", "b "}},
{name: "quote_contains", value: `'a "'"'b"`, want: []string{`a "`, `'b`}},
{name: "escape", value: `\'`, want: []string{`\'`}},
{name: "quote_unclosed", value: `'a`, wantErr: "unterminated ' string"},
} {
t.Run(test.name, func(t *testing.T) {
got, err := Split(test.value)
if err != nil {
if test.wantErr == "" {
t.Fatalf("unexpected error: %v", err)
} else if errMsg := err.Error(); !strings.Contains(errMsg, test.wantErr) {
t.Fatalf("error %q does not contain %q", errMsg, test.wantErr)
}
return
}
if test.wantErr != "" {
t.Fatalf("unexpected success; wanted error containing %q", test.wantErr)
}
if !reflect.DeepEqual(got, test.want) {
t.Errorf("got %q; want %q", got, test.want)
}
})
}
}
func TestJoin(t *testing.T) {
for _, test := range []struct {
name string
args []string
want, wantErr string
}{
{name: "empty", args: nil, want: ""},
{name: "one", args: []string{"a"}, want: "a"},
{name: "two", args: []string{"a", "b"}, want: "a b"},
{name: "space", args: []string{"a ", "b"}, want: "'a ' b"},
{name: "newline", args: []string{"a\n", "b"}, want: "'a\n' b"},
{name: "quote", args: []string{`'a `, "b"}, want: `"'a " b`},
{name: "unquoteable", args: []string{`'"`}, wantErr: "contains both single and double quotes and cannot be quoted"},
} {
t.Run(test.name, func(t *testing.T) {
got, err := Join(test.args)
if err != nil {
if test.wantErr == "" {
t.Fatalf("unexpected error: %v", err)
} else if errMsg := err.Error(); !strings.Contains(errMsg, test.wantErr) {
t.Fatalf("error %q does not contain %q", errMsg, test.wantErr)
}
return
}
if test.wantErr != "" {
t.Fatalf("unexpected success; wanted error containing %q", test.wantErr)
}
if got != test.want {
t.Errorf("got %s; want %s", got, test.want)
}
})
}
}
================================================
FILE: internal/go/quoted/readme.md
================================================
# quoted
Extracted from `go/src/cmd/internal/quoted/` (related to `cache`).
This is just a copy of the Go code without any changes.
## History
- https://github.com/golangci/golangci-lint/pull/5576
- sync go1.24.1 (no change)
- https://github.com/golangci/golangci-lint/pull/5100
- Move package from `internal/quoted` to `internal/go/quoted`
- https://github.com/golangci/golangci-lint/pull/5098
- sync go1.23.2
- sync go1.22.8
- sync go1.21.13
================================================
FILE: internal/go/testenv/readme.md
================================================
# testenv
Extracted from `go/src/internal/testenv/`.
Only the function `SyscallIsNotSupported` is extracted (related to `cache`).
## History
- https://github.com/golangci/golangci-lint/pull/5576
- sync go1.24.1
- https://github.com/golangci/golangci-lint/pull/5100
- Move package from `internal/testenv` to `internal/go/testenv`
- https://github.com/golangci/golangci-lint/pull/5098
- sync with go1.23.2
- sync with go1.22.8
- sync with go1.21.13
================================================
FILE: internal/go/testenv/testenv.go
================================================
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package testenv provides information about what functionality
// is available in different testing environments run by the Go team.
//
// It is an internal package because these details are specific
// to the Go team's test setup (on build.golang.org) and not
// fundamental to tests in general.
package testenv
// SyscallIsNotSupported reports whether err may indicate that a system call is
// not supported by the current platform or execution environment.
func SyscallIsNotSupported(err error) bool {
return syscallIsNotSupported(err)
}
================================================
FILE: internal/go/testenv/testenv_notunix.go
================================================
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build windows || plan9 || (js && wasm) || wasip1
package testenv
import (
"errors"
"io/fs"
"os"
)
// Sigquit is the signal to send to kill a hanging subprocess.
// On Unix we send SIGQUIT, but on non-Unix we only have os.Kill.
var Sigquit = os.Kill
func syscallIsNotSupported(err error) bool {
return errors.Is(err, fs.ErrPermission) || errors.Is(err, errors.ErrUnsupported)
}
================================================
FILE: internal/go/testenv/testenv_notwin.go
================================================
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !windows
package testenv
import (
"fmt"
"os"
"path/filepath"
"runtime"
"sync"
)
var hasSymlink = sync.OnceValues(func() (ok bool, reason string) {
switch runtime.GOOS {
case "plan9":
return false, ""
case "android", "wasip1":
// For wasip1, some runtimes forbid absolute symlinks,
// or symlinks that escape the current working directory.
// Perform a simple test to see whether the runtime
// supports symlinks or not. If we get a permission
// error, the runtime does not support symlinks.
dir, err := os.MkdirTemp("", "")
if err != nil {
return false, ""
}
defer func() {
_ = os.RemoveAll(dir)
}()
fpath := filepath.Join(dir, "testfile.txt")
if err := os.WriteFile(fpath, nil, 0644); err != nil {
return false, ""
}
if err := os.Symlink(fpath, filepath.Join(dir, "testlink")); err != nil {
if SyscallIsNotSupported(err) {
return false, fmt.Sprintf("symlinks unsupported: %s", err.Error())
}
return false, ""
}
}
return true, ""
})
================================================
FILE: internal/go/testenv/testenv_unix.go
================================================
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build unix
package testenv
import (
"errors"
"io/fs"
"syscall"
)
// Sigquit is the signal to send to kill a hanging subprocess.
// Send SIGQUIT to get a stack trace.
var Sigquit = syscall.SIGQUIT
func syscallIsNotSupported(err error) bool {
if err == nil {
return false
}
var errno syscall.Errno
if errors.As(err, &errno) {
switch errno {
case syscall.EPERM, syscall.EROFS:
// User lacks permission: either the call requires root permission and the
// user is not root, or the call is denied by a container security policy.
return true
case syscall.EINVAL:
// Some containers return EINVAL instead of EPERM if a system call is
// denied by security policy.
return true
}
}
if errors.Is(err, fs.ErrPermission) || errors.Is(err, errors.ErrUnsupported) {
return true
}
return false
}
================================================
FILE: internal/go/testenv/testenv_windows.go
================================================
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package testenv
import (
"errors"
"os"
"path/filepath"
"sync"
"syscall"
)
var hasSymlink = sync.OnceValues(func() (bool, string) {
tmpdir, err := os.MkdirTemp("", "symtest")
if err != nil {
panic("failed to create temp directory: " + err.Error())
}
defer os.RemoveAll(tmpdir)
err = os.Symlink("target", filepath.Join(tmpdir, "symlink"))
switch {
case err == nil:
return true, ""
case errors.Is(err, syscall.EWINDOWS):
return false, ": symlinks are not supported on your version of Windows"
case errors.Is(err, syscall.ERROR_PRIVILEGE_NOT_HELD):
return false, ": you don't have enough privileges to create symlinks"
}
return false, ""
})
================================================
FILE: internal/x/LICENSE
================================================
Copyright 2009 The Go Authors.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google LLC nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: internal/x/tools/diff/diff.go
================================================
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package diff computes differences between text files or strings.
package diff
import (
"fmt"
"slices"
"sort"
"strings"
)
// An Edit describes the replacement of a portion of a text file.
type Edit struct {
Start, End int // byte offsets of the region to replace
New string // the replacement
}
func (e Edit) String() string {
return fmt.Sprintf("{Start:%d,End:%d,New:%q}", e.Start, e.End, e.New)
}
// Apply applies a sequence of edits to the src buffer and returns the
// result. Edits are applied in order of start offset; edits with the
// same start offset are applied in they order they were provided.
//
// Apply returns an error if any edit is out of bounds,
// or if any pair of edits is overlapping.
func Apply(src string, edits []Edit) (string, error) {
edits, size, err := validate(src, edits)
if err != nil {
return "", err
}
// Apply edits.
out := make([]byte, 0, size)
lastEnd := 0
for _, edit := range edits {
if lastEnd < edit.Start {
out = append(out, src[lastEnd:edit.Start]...)
}
out = append(out, edit.New...)
lastEnd = edit.End
}
out = append(out, src[lastEnd:]...)
if len(out) != size {
panic("wrong size")
}
return string(out), nil
}
// ApplyBytes is like Apply, but it accepts a byte slice.
// The result is always a new array.
func ApplyBytes(src []byte, edits []Edit) ([]byte, error) {
res, err := Apply(string(src), edits)
return []byte(res), err
}
// validate checks that edits are consistent with src,
// and returns the size of the patched output.
// It may return a different slice.
func validate(src string, edits []Edit) ([]Edit, int, error) {
if !sort.IsSorted(editsSort(edits)) {
edits = slices.Clone(edits)
SortEdits(edits)
}
// Check validity of edits and compute final size.
size := len(src)
lastEnd := 0
for _, edit := range edits {
if !(0 <= edit.Start && edit.Start <= edit.End && edit.End <= len(src)) {
return nil, 0, fmt.Errorf("diff has out-of-bounds edits")
}
if edit.Start < lastEnd {
return nil, 0, fmt.Errorf("diff has overlapping edits")
}
size += len(edit.New) + edit.Start - edit.End
lastEnd = edit.End
}
return edits, size, nil
}
// SortEdits orders a slice of Edits by (start, end) offset.
// This ordering puts insertions (end = start) before deletions
// (end > start) at the same point, but uses a stable sort to preserve
// the order of multiple insertions at the same point.
// (Apply detects multiple deletions at the same point as an error.)
func SortEdits(edits []Edit) {
sort.Stable(editsSort(edits))
}
type editsSort []Edit
func (a editsSort) Len() int { return len(a) }
func (a editsSort) Less(i, j int) bool {
if cmp := a[i].Start - a[j].Start; cmp != 0 {
return cmp < 0
}
return a[i].End < a[j].End
}
func (a editsSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// lineEdits expands and merges a sequence of edits so that each
// resulting edit replaces one or more complete lines.
// See ApplyEdits for preconditions.
func lineEdits(src string, edits []Edit) ([]Edit, error) {
edits, _, err := validate(src, edits)
if err != nil {
return nil, err
}
// Do all deletions begin and end at the start of a line,
// and all insertions end with a newline?
// (This is merely a fast path.)
for _, edit := range edits {
if edit.Start >= len(src) || // insertion at EOF
edit.Start > 0 && src[edit.Start-1] != '\n' || // not at line start
edit.End > 0 && src[edit.End-1] != '\n' || // not at line start
edit.New != "" && edit.New[len(edit.New)-1] != '\n' { // partial insert
goto expand // slow path
}
}
return edits, nil // aligned
expand:
if len(edits) == 0 {
return edits, nil // no edits (unreachable due to fast path)
}
expanded := make([]Edit, 0, len(edits)) // a guess
prev := edits[0]
// TODO(adonovan): opt: start from the first misaligned edit.
// TODO(adonovan): opt: avoid quadratic cost of string += string.
for _, edit := range edits[1:] {
between := src[prev.End:edit.Start]
if !strings.Contains(between, "\n") {
// overlapping lines: combine with previous edit.
prev.New += between + edit.New
prev.End = edit.End
} else {
// non-overlapping lines: flush previous edit.
expanded = append(expanded, expandEdit(prev, src))
prev = edit
}
}
return append(expanded, expandEdit(prev, src)), nil // flush final edit
}
// expandEdit returns edit expanded to complete whole lines.
func expandEdit(edit Edit, src string) Edit {
// Expand start left to start of line.
// (delta is the zero-based column number of start.)
start := edit.Start
if delta := start - 1 - strings.LastIndex(src[:start], "\n"); delta > 0 {
edit.Start -= delta
edit.New = src[start-delta:start] + edit.New
}
// Expand end right to end of line.
end := edit.End
if end > 0 && src[end-1] != '\n' ||
edit.New != "" && edit.New[len(edit.New)-1] != '\n' {
if nl := strings.IndexByte(src[end:], '\n'); nl < 0 {
edit.End = len(src) // extend to EOF
} else {
edit.End = end + nl + 1 // extend beyond \n
}
}
edit.New += src[end:edit.End]
return edit
}
================================================
FILE: internal/x/tools/diff/lcs/common.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lcs
import (
"log"
"sort"
)
// lcs is a longest common sequence
type lcs []diag
// A diag is a piece of the edit graph where A[X+i] == B[Y+i], for 0<=i l[j].Len
})
return l
}
// validate that the elements of the lcs do not overlap
// (can only happen when the two-sided algorithm ends early)
// expects the lcs to be sorted
func (l lcs) valid() bool {
for i := 1; i < len(l); i++ {
if l[i-1].X+l[i-1].Len > l[i].X {
return false
}
if l[i-1].Y+l[i-1].Len > l[i].Y {
return false
}
}
return true
}
// repair overlapping lcs
// only called if two-sided stops early
func (l lcs) fix() lcs {
// from the set of diagonals in l, find a maximal non-conflicting set
// this problem may be NP-complete, but we use a greedy heuristic,
// which is quadratic, but with a better data structure, could be D log D.
// independent is not enough: {0,3,1} and {3,0,2} can't both occur in an lcs
// which has to have monotone x and y
if len(l) == 0 {
return nil
}
sort.Slice(l, func(i, j int) bool { return l[i].Len > l[j].Len })
tmp := make(lcs, 0, len(l))
tmp = append(tmp, l[0])
for i := 1; i < len(l); i++ {
var dir direction
nxt := l[i]
for _, in := range tmp {
if dir, nxt = overlap(in, nxt); dir == empty || dir == bad {
break
}
}
if nxt.Len > 0 && dir != bad {
tmp = append(tmp, nxt)
}
}
tmp.sort()
if false && !tmp.valid() { // debug checking
log.Fatalf("here %d", len(tmp))
}
return tmp
}
type direction int
const (
empty direction = iota // diag is empty (so not in lcs)
leftdown // proposed acceptably to the left and below
rightup // proposed diag is acceptably to the right and above
bad // proposed diag is inconsistent with the lcs so far
)
// overlap trims the proposed diag prop so it doesn't overlap with
// the existing diag that has already been added to the lcs.
func overlap(exist, prop diag) (direction, diag) {
if prop.X <= exist.X && exist.X < prop.X+prop.Len {
// remove the end of prop where it overlaps with the X end of exist
delta := prop.X + prop.Len - exist.X
prop.Len -= delta
if prop.Len <= 0 {
return empty, prop
}
}
if exist.X <= prop.X && prop.X < exist.X+exist.Len {
// remove the beginning of prop where overlaps with exist
delta := exist.X + exist.Len - prop.X
prop.Len -= delta
if prop.Len <= 0 {
return empty, prop
}
prop.X += delta
prop.Y += delta
}
if prop.Y <= exist.Y && exist.Y < prop.Y+prop.Len {
// remove the end of prop that overlaps (in Y) with exist
delta := prop.Y + prop.Len - exist.Y
prop.Len -= delta
if prop.Len <= 0 {
return empty, prop
}
}
if exist.Y <= prop.Y && prop.Y < exist.Y+exist.Len {
// remove the beginning of peop that overlaps with exist
delta := exist.Y + exist.Len - prop.Y
prop.Len -= delta
if prop.Len <= 0 {
return empty, prop
}
prop.X += delta // no test reaches this code
prop.Y += delta
}
if prop.X+prop.Len <= exist.X && prop.Y+prop.Len <= exist.Y {
return leftdown, prop
}
if exist.X+exist.Len <= prop.X && exist.Y+exist.Len <= prop.Y {
return rightup, prop
}
// prop can't be in an lcs that contains exist
return bad, prop
}
// manipulating Diag and lcs
// prepend a diagonal (x,y)-(x+1,y+1) segment either to an empty lcs
// or to its first Diag. prepend is only called to extend diagonals
// the backward direction.
func (lcs lcs) prepend(x, y int) lcs {
if len(lcs) > 0 {
d := &lcs[0]
if int(d.X) == x+1 && int(d.Y) == y+1 {
// extend the diagonal down and to the left
d.X, d.Y = int(x), int(y)
d.Len++
return lcs
}
}
r := diag{X: int(x), Y: int(y), Len: 1}
lcs = append([]diag{r}, lcs...)
return lcs
}
// append appends a diagonal, or extends the existing one.
// by adding the edge (x,y)-(x+1.y+1). append is only called
// to extend diagonals in the forward direction.
func (lcs lcs) append(x, y int) lcs {
if len(lcs) > 0 {
last := &lcs[len(lcs)-1]
// Expand last element if adjoining.
if last.X+last.Len == x && last.Y+last.Len == y {
last.Len++
return lcs
}
}
return append(lcs, diag{X: x, Y: y, Len: 1})
}
// enforce constraint on d, k
func ok(d, k int) bool {
return d >= 0 && -d <= k && k <= d
}
================================================
FILE: internal/x/tools/diff/lcs/common_test.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lcs
import (
"log"
"math/rand/v2"
"slices"
"strings"
"testing"
)
type Btest struct {
a, b string
lcs []string
}
var Btests = []Btest{
{"aaabab", "abaab", []string{"abab", "aaab"}},
{"aabbba", "baaba", []string{"aaba"}},
{"cabbx", "cbabx", []string{"cabx", "cbbx"}},
{"c", "cb", []string{"c"}},
{"aaba", "bbb", []string{"b"}},
{"bbaabb", "b", []string{"b"}},
{"baaabb", "bbaba", []string{"bbb", "baa", "bab"}},
{"baaabb", "abbab", []string{"abb", "bab", "aab"}},
{"baaba", "aaabba", []string{"aaba"}},
{"ca", "cba", []string{"ca"}},
{"ccbcbc", "abba", []string{"bb"}},
{"ccbcbc", "aabba", []string{"bb"}},
{"ccb", "cba", []string{"cb"}},
{"caef", "axe", []string{"ae"}},
{"bbaabb", "baabb", []string{"baabb"}},
// Example from Myers:
{"abcabba", "cbabac", []string{"caba", "baba", "cbba"}},
{"3456aaa", "aaa", []string{"aaa"}},
{"aaa", "aaa123", []string{"aaa"}},
{"aabaa", "aacaa", []string{"aaaa"}},
{"1a", "a", []string{"a"}},
{"abab", "bb", []string{"bb"}},
{"123", "ab", []string{""}},
{"a", "b", []string{""}},
{"abc", "123", []string{""}},
{"aa", "aa", []string{"aa"}},
{"abcde", "12345", []string{""}},
{"aaa3456", "aaa", []string{"aaa"}},
{"abcde", "12345a", []string{"a"}},
{"ab", "123", []string{""}},
{"1a2", "a", []string{"a"}},
// for two-sided
{"babaab", "cccaba", []string{"aba"}},
{"aabbab", "cbcabc", []string{"bab"}},
{"abaabb", "bcacab", []string{"baab"}},
{"abaabb", "abaaaa", []string{"abaa"}},
{"bababb", "baaabb", []string{"baabb"}},
{"abbbaa", "cabacc", []string{"aba"}},
{"aabbaa", "aacaba", []string{"aaaa", "aaba"}},
}
func init() {
log.SetFlags(log.Lshortfile)
}
func check(t *testing.T, str string, lcs lcs, want []string) {
t.Helper()
if !lcs.valid() {
t.Errorf("bad lcs %v", lcs)
}
var got strings.Builder
for _, dd := range lcs {
got.WriteString(str[dd.X : dd.X+dd.Len])
}
ans := got.String()
if slices.Contains(want, ans) {
return
}
t.Fatalf("str=%q lcs=%v want=%q got=%q", str, lcs, want, ans)
}
func checkDiffs(t *testing.T, before string, diffs []Diff, after string) {
t.Helper()
var ans strings.Builder
sofar := 0 // index of position in before
for _, d := range diffs {
if sofar < d.Start {
ans.WriteString(before[sofar:d.Start])
}
ans.WriteString(after[d.ReplStart:d.ReplEnd])
sofar = d.End
}
ans.WriteString(before[sofar:])
if ans.String() != after {
t.Fatalf("diff %v took %q to %q, not to %q", diffs, before, ans.String(), after)
}
}
func lcslen(l lcs) int {
ans := 0
for _, d := range l {
ans += int(d.Len)
}
return ans
}
// return a random string of length n made of characters from s
func randstr(rng *rand.Rand, s string, n int) string {
src := []rune(s)
x := make([]rune, n)
for i := range n {
x[i] = src[rng.Int64N(int64(len(src)))]
}
return string(x)
}
func TestLcsFix(t *testing.T) {
tests := []struct{ before, after lcs }{
{lcs{diag{0, 0, 3}, diag{2, 2, 5}, diag{3, 4, 5}, diag{8, 9, 4}}, lcs{diag{0, 0, 2}, diag{2, 2, 1}, diag{3, 4, 5}, diag{8, 9, 4}}},
{lcs{diag{1, 1, 6}, diag{6, 12, 3}}, lcs{diag{1, 1, 5}, diag{6, 12, 3}}},
{lcs{diag{0, 0, 4}, diag{3, 5, 4}}, lcs{diag{0, 0, 3}, diag{3, 5, 4}}},
{lcs{diag{0, 20, 1}, diag{0, 0, 3}, diag{1, 20, 4}}, lcs{diag{0, 0, 3}, diag{3, 22, 2}}},
{lcs{diag{0, 0, 4}, diag{1, 1, 2}}, lcs{diag{0, 0, 4}}},
{lcs{diag{0, 0, 4}}, lcs{diag{0, 0, 4}}},
{lcs{}, lcs{}},
{lcs{diag{0, 0, 4}, diag{1, 1, 6}, diag{3, 3, 2}}, lcs{diag{0, 0, 1}, diag{1, 1, 6}}},
}
for n, x := range tests {
got := x.before.fix()
if len(got) != len(x.after) {
t.Errorf("got %v, expected %v, for %v", got, x.after, x.before)
}
olen := lcslen(x.after)
glen := lcslen(got)
if olen != glen {
t.Errorf("%d: lens(%d,%d) differ, %v, %v, %v", n, glen, olen, got, x.after, x.before)
}
}
}
================================================
FILE: internal/x/tools/diff/lcs/doc.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// package lcs contains code to find longest-common-subsequences
// (and diffs)
package lcs
/*
Compute longest-common-subsequences of two slices A, B using
algorithms from Myers' paper. A longest-common-subsequence
(LCS from now on) of A and B is a maximal set of lexically increasing
pairs of subscripts (x,y) with A[x]==B[y]. There may be many LCS, but
they all have the same length. An LCS determines a sequence of edits
that changes A into B.
The key concept is the edit graph of A and B.
If A has length N and B has length M, then the edit graph has
vertices v[i][j] for 0 <= i <= N, 0 <= j <= M. There is a
horizontal edge from v[i][j] to v[i+1][j] whenever both are in
the graph, and a vertical edge from v[i][j] to f[i][j+1] similarly.
When A[i] == B[j] there is a diagonal edge from v[i][j] to v[i+1][j+1].
A path between in the graph between (0,0) and (N,M) determines a sequence
of edits converting A into B: each horizontal edge corresponds to removing
an element of A, and each vertical edge corresponds to inserting an
element of B.
A vertex (x,y) is on (forward) diagonal k if x-y=k. A path in the graph
is of length D if it has D non-diagonal edges. The algorithms generate
forward paths (in which at least one of x,y increases at each edge),
or backward paths (in which at least one of x,y decreases at each edge),
or a combination. (Note that the orientation is the traditional mathematical one,
with the origin in the lower-left corner.)
Here is the edit graph for A:"aabbaa", B:"aacaba". (I know the diagonals look weird.)
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
b | | | ___/‾‾‾ | ___/‾‾‾ | | |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
c | | | | | | |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
a a b b a a
The algorithm labels a vertex (x,y) with D,k if it is on diagonal k and at
the end of a maximal path of length D. (Because x-y=k it suffices to remember
only the x coordinate of the vertex.)
The forward algorithm: Find the longest diagonal starting at (0,0) and
label its end with D=0,k=0. From that vertex take a vertical step and
then follow the longest diagonal (up and to the right), and label that vertex
with D=1,k=-1. From the D=0,k=0 point take a horizontal step and the follow
the longest diagonal (up and to the right) and label that vertex
D=1,k=1. In the same way, having labelled all the D vertices,
from a vertex labelled D,k find two vertices
tentatively labelled D+1,k-1 and D+1,k+1. There may be two on the same
diagonal, in which case take the one with the larger x.
Eventually the path gets to (N,M), and the diagonals on it are the LCS.
Here is the edit graph with the ends of D-paths labelled. (So, for instance,
0/2,2 indicates that x=2,y=2 is labelled with 0, as it should be, since the first
step is to go up the longest diagonal from (0,0).)
A:"aabbaa", B:"aacaba"
⊙ ------- ⊙ ------- ⊙ -------(3/3,6)------- ⊙ -------(3/5,6)-------(4/6,6)
a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ |
⊙ ------- ⊙ ------- ⊙ -------(2/3,5)------- ⊙ ------- ⊙ ------- ⊙
b | | | ___/‾‾‾ | ___/‾‾‾ | | |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ -------(3/5,4)------- ⊙
a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ |
⊙ ------- ⊙ -------(1/2,3)-------(2/3,3)------- ⊙ ------- ⊙ ------- ⊙
c | | | | | | |
⊙ ------- ⊙ -------(0/2,2)-------(1/3,2)-------(2/4,2)-------(3/5,2)-------(4/6,2)
a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ |
⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙
a a b b a a
The 4-path is reconstructed starting at (4/6,6), horizontal to (3/5,6), diagonal to (3,4), vertical
to (2/3,3), horizontal to (1/2,3), vertical to (0/2,2), and diagonal to (0,0). As expected,
there are 4 non-diagonal steps, and the diagonals form an LCS.
There is a symmetric backward algorithm, which gives (backwards labels are prefixed with a colon):
A:"aabbaa", B:"aacaba"
⊙ -------- ⊙ -------- ⊙ -------- ⊙ -------- ⊙ -------- ⊙ -------- ⊙
a | ____/‾‾‾ | ____/‾‾‾ | | | ____/‾‾‾ | ____/‾‾‾ |
⊙ -------- ⊙ -------- ⊙ -------- ⊙ -------- ⊙ --------(:0/5,5)-------- ⊙
b | | | ____/‾‾‾ | ____/‾‾‾ | | |
⊙ -------- ⊙ -------- ⊙ --------(:1/3,4)-------- ⊙ -------- ⊙ -------- ⊙
a | ____/‾‾‾ | ____/‾‾‾ | | | ____/‾‾‾ | ____/‾‾‾ |
(:3/0,3)--------(:2/1,3)-------- ⊙ --------(:2/3,3)--------(:1/4,3)-------- ⊙ -------- ⊙
c | | | | | | |
⊙ -------- ⊙ -------- ⊙ --------(:3/3,2)--------(:2/4,2)-------- ⊙ -------- ⊙
a | ____/‾‾‾ | ____/‾‾‾ | | | ____/‾‾‾ | ____/‾‾‾ |
(:3/0,1)-------- ⊙ -------- ⊙ -------- ⊙ --------(:3/4,1)-------- ⊙ -------- ⊙
a | ____/‾‾‾ | ____/‾‾‾ | | | ____/‾‾‾ | ____/‾‾‾ |
(:4/0,0)-------- ⊙ -------- ⊙ -------- ⊙ --------(:4/4,0)-------- ⊙ -------- ⊙
a a b b a a
Neither of these is ideal for use in an editor, where it is undesirable to send very long diffs to the
front end. It's tricky to decide exactly what 'very long diffs' means, as "replace A by B" is very short.
We want to control how big D can be, by stopping when it gets too large. The forward algorithm then
privileges common prefixes, and the backward algorithm privileges common suffixes. Either is an undesirable
asymmetry.
Fortunately there is a two-sided algorithm, implied by results in Myers' paper. Here's what the labels in
the edit graph look like.
A:"aabbaa", B:"aacaba"
⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙
a | ____/‾‾‾‾ | ____/‾‾‾‾ | | | ____/‾‾‾‾ | ____/‾‾‾‾ |
⊙ --------- ⊙ --------- ⊙ --------- (2/3,5) --------- ⊙ --------- (:0/5,5)--------- ⊙
b | | | ____/‾‾‾‾ | ____/‾‾‾‾ | | |
⊙ --------- ⊙ --------- ⊙ --------- (:1/3,4)--------- ⊙ --------- ⊙ --------- ⊙
a | ____/‾‾‾‾ | ____/‾‾‾‾ | | | ____/‾‾‾‾ | ____/‾‾‾‾ |
⊙ --------- (:2/1,3)--------- (1/2,3) ---------(2:2/3,3)--------- (:1/4,3)--------- ⊙ --------- ⊙
c | | | | | | |
⊙ --------- ⊙ --------- (0/2,2) --------- (1/3,2) ---------(2:2/4,2)--------- ⊙ --------- ⊙
a | ____/‾‾‾‾ | ____/‾‾‾‾ | | | ____/‾‾‾‾ | ____/‾‾‾‾ |
⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙
a | ____/‾‾‾‾ | ____/‾‾‾‾ | | | ____/‾‾‾‾ | ____/‾‾‾‾ |
⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙
a a b b a a
The algorithm stopped when it saw the backwards 2-path ending at (1,3) and the forwards 2-path ending at (3,5). The criterion
is a backwards path ending at (u,v) and a forward path ending at (x,y), where u <= x and the two points are on the same
diagonal. (Here the edgegraph has a diagonal, but the criterion is x-y=u-v.) Myers proves there is a forward
2-path from (0,0) to (1,3), and that together with the backwards 2-path ending at (1,3) gives the expected 4-path.
Unfortunately the forward path has to be constructed by another run of the forward algorithm; it can't be found from the
computed labels. That is the worst case. Had the code noticed (x,y)=(u,v)=(3,3) the whole path could be reconstructed
from the edgegraph. The implementation looks for a number of special cases to try to avoid computing an extra forward path.
If the two-sided algorithm has stop early (because D has become too large) it will have found a forward LCS and a
backwards LCS. Ideally these go with disjoint prefixes and suffixes of A and B, but disjointedness may fail and the two
computed LCS may conflict. (An easy example is where A is a suffix of B, and shares a short prefix. The backwards LCS
is all of A, and the forward LCS is a prefix of A.) The algorithm combines the two
to form a best-effort LCS. In the worst case the forward partial LCS may have to
be recomputed.
*/
/* Eugene Myers paper is titled
"An O(ND) Difference Algorithm and Its Variations"
and can be found at
http://www.xmailserver.org/diff2.pdf
(There is a generic implementation of the algorithm the repository with git hash
b9ad7e4ade3a686d608e44475390ad428e60e7fc)
*/
================================================
FILE: internal/x/tools/diff/lcs/git.sh
================================================
#!/bin/bash
#
# Copyright 2022 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
#
# Creates a zip file containing all numbered versions
# of the commit history of a large source file, for use
# as input data for the tests of the diff algorithm.
#
# Run script from root of the x/tools repo.
set -eu
# WARNING: This script will install the latest version of $file
# The largest real source file in the x/tools repo.
# file=internal/golang/completion/completion.go
# file=internal/golang/diagnostics.go
file=internal/protocol/tsprotocol.go
tmp=$(mktemp -d)
git log $file |
awk '/^commit / {print $2}' |
nl -ba -nrz |
while read n hash; do
git checkout --quiet $hash $file
cp -f $file $tmp/$n
done
(cd $tmp && zip -q - *) > testdata.zip
rm -fr $tmp
git restore --staged $file
git restore $file
echo "Created testdata.zip"
================================================
FILE: internal/x/tools/diff/lcs/labels.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lcs
import (
"fmt"
)
// For each D, vec[D] has length D+1,
// and the label for (D, k) is stored in vec[D][(D+k)/2].
type label struct {
vec [][]int
}
// Temporary checking DO NOT COMMIT true TO PRODUCTION CODE
const debug = false
// debugging. check that the (d,k) pair is valid
// (that is, -d<=k<=d and d+k even)
func checkDK(D, k int) {
if k >= -D && k <= D && (D+k)%2 == 0 {
return
}
panic(fmt.Sprintf("out of range, d=%d,k=%d", D, k))
}
func (t *label) set(D, k, x int) {
if debug {
checkDK(D, k)
}
for len(t.vec) <= D {
t.vec = append(t.vec, nil)
}
if t.vec[D] == nil {
t.vec[D] = make([]int, D+1)
}
t.vec[D][(D+k)/2] = x // known that D+k is even
}
func (t *label) get(d, k int) int {
if debug {
checkDK(d, k)
}
return int(t.vec[d][(d+k)/2])
}
func newtriang(limit int) label {
if limit < 100 {
// Preallocate if limit is not large.
return label{vec: make([][]int, limit)}
}
return label{}
}
================================================
FILE: internal/x/tools/diff/lcs/old.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lcs
// TODO(adonovan): remove unclear references to "old" in this package.
import (
"fmt"
)
// A Diff is a replacement of a portion of A by a portion of B.
type Diff struct {
Start, End int // offsets of portion to delete in A
ReplStart, ReplEnd int // offset of replacement text in B
}
// DiffStrings returns the differences between two strings.
// It does not respect rune boundaries.
func DiffStrings(a, b string) []Diff { return diff(stringSeqs{a, b}) }
// DiffBytes returns the differences between two byte sequences.
// It does not respect rune boundaries.
func DiffBytes(a, b []byte) []Diff { return diff(bytesSeqs{a, b}) }
// DiffRunes returns the differences between two rune sequences.
func DiffRunes(a, b []rune) []Diff { return diff(runesSeqs{a, b}) }
func diff(seqs sequences) []Diff {
// A limit on how deeply the LCS algorithm should search. The value is just a guess.
const maxDiffs = 100
diff, _ := compute(seqs, twosided, maxDiffs/2)
return diff
}
// compute computes the list of differences between two sequences,
// along with the LCS. It is exercised directly by tests.
// The algorithm is one of {forward, backward, twosided}.
func compute(seqs sequences, algo func(*editGraph) lcs, limit int) ([]Diff, lcs) {
if limit <= 0 {
limit = 1 << 25 // effectively infinity
}
alen, blen := seqs.lengths()
g := &editGraph{
seqs: seqs,
vf: newtriang(limit),
vb: newtriang(limit),
limit: limit,
ux: alen,
uy: blen,
delta: alen - blen,
}
lcs := algo(g)
diffs := lcs.toDiffs(alen, blen)
return diffs, lcs
}
// editGraph carries the information for computing the lcs of two sequences.
type editGraph struct {
seqs sequences
vf, vb label // forward and backward labels
limit int // maximal value of D
// the bounding rectangle of the current edit graph
lx, ly, ux, uy int
delta int // common subexpression: (ux-lx)-(uy-ly)
}
// toDiffs converts an LCS to a list of edits.
func (lcs lcs) toDiffs(alen, blen int) []Diff {
var diffs []Diff
var pa, pb int // offsets in a, b
for _, l := range lcs {
if pa < l.X || pb < l.Y {
diffs = append(diffs, Diff{pa, l.X, pb, l.Y})
}
pa = l.X + l.Len
pb = l.Y + l.Len
}
if pa < alen || pb < blen {
diffs = append(diffs, Diff{pa, alen, pb, blen})
}
return diffs
}
// --- FORWARD ---
// fdone decides if the forward path has reached the upper right
// corner of the rectangle. If so, it also returns the computed lcs.
func (e *editGraph) fdone(D, k int) (bool, lcs) {
// x, y, k are relative to the rectangle
x := e.vf.get(D, k)
y := x - k
if x == e.ux && y == e.uy {
return true, e.forwardlcs(D, k)
}
return false, nil
}
// run the forward algorithm, until success or up to the limit on D.
func forward(e *editGraph) lcs {
e.setForward(0, 0, e.lx)
if ok, ans := e.fdone(0, 0); ok {
return ans
}
// from D to D+1
for D := range e.limit {
e.setForward(D+1, -(D + 1), e.getForward(D, -D))
if ok, ans := e.fdone(D+1, -(D + 1)); ok {
return ans
}
e.setForward(D+1, D+1, e.getForward(D, D)+1)
if ok, ans := e.fdone(D+1, D+1); ok {
return ans
}
for k := -D + 1; k <= D-1; k += 2 {
// these are tricky and easy to get backwards
lookv := e.lookForward(k, e.getForward(D, k-1)+1)
lookh := e.lookForward(k, e.getForward(D, k+1))
if lookv > lookh {
e.setForward(D+1, k, lookv)
} else {
e.setForward(D+1, k, lookh)
}
if ok, ans := e.fdone(D+1, k); ok {
return ans
}
}
}
// D is too large
// find the D path with maximal x+y inside the rectangle and
// use that to compute the found part of the lcs
kmax := -e.limit - 1
diagmax := -1
for k := -e.limit; k <= e.limit; k += 2 {
x := e.getForward(e.limit, k)
y := x - k
if x+y > diagmax && x <= e.ux && y <= e.uy {
diagmax, kmax = x+y, k
}
}
return e.forwardlcs(e.limit, kmax)
}
// recover the lcs by backtracking from the farthest point reached
func (e *editGraph) forwardlcs(D, k int) lcs {
var ans lcs
for x := e.getForward(D, k); x != 0 || x-k != 0; {
if ok(D-1, k-1) && x-1 == e.getForward(D-1, k-1) {
// if (x-1,y) is labelled D-1, x--,D--,k--,continue
D, k, x = D-1, k-1, x-1
continue
} else if ok(D-1, k+1) && x == e.getForward(D-1, k+1) {
// if (x,y-1) is labelled D-1, x, D--,k++, continue
D, k = D-1, k+1
continue
}
// if (x-1,y-1)--(x,y) is a diagonal, prepend,x--,y--, continue
y := x - k
ans = ans.prepend(x+e.lx-1, y+e.ly-1)
x--
}
return ans
}
// start at (x,y), go up the diagonal as far as possible,
// and label the result with d
func (e *editGraph) lookForward(k, relx int) int {
rely := relx - k
x, y := relx+e.lx, rely+e.ly
if x < e.ux && y < e.uy {
x += e.seqs.commonPrefixLen(x, e.ux, y, e.uy)
}
return x
}
func (e *editGraph) setForward(d, k, relx int) {
x := e.lookForward(k, relx)
e.vf.set(d, k, x-e.lx)
}
func (e *editGraph) getForward(d, k int) int {
x := e.vf.get(d, k)
return x
}
// --- BACKWARD ---
// bdone decides if the backward path has reached the lower left corner
func (e *editGraph) bdone(D, k int) (bool, lcs) {
// x, y, k are relative to the rectangle
x := e.vb.get(D, k)
y := x - (k + e.delta)
if x == 0 && y == 0 {
return true, e.backwardlcs(D, k)
}
return false, nil
}
// run the backward algorithm, until success or up to the limit on D.
// (used only by tests)
func backward(e *editGraph) lcs {
e.setBackward(0, 0, e.ux)
if ok, ans := e.bdone(0, 0); ok {
return ans
}
// from D to D+1
for D := range e.limit {
e.setBackward(D+1, -(D + 1), e.getBackward(D, -D)-1)
if ok, ans := e.bdone(D+1, -(D + 1)); ok {
return ans
}
e.setBackward(D+1, D+1, e.getBackward(D, D))
if ok, ans := e.bdone(D+1, D+1); ok {
return ans
}
for k := -D + 1; k <= D-1; k += 2 {
// these are tricky and easy to get wrong
lookv := e.lookBackward(k, e.getBackward(D, k-1))
lookh := e.lookBackward(k, e.getBackward(D, k+1)-1)
if lookv < lookh {
e.setBackward(D+1, k, lookv)
} else {
e.setBackward(D+1, k, lookh)
}
if ok, ans := e.bdone(D+1, k); ok {
return ans
}
}
}
// D is too large
// find the D path with minimal x+y inside the rectangle and
// use that to compute the part of the lcs found
kmax := -e.limit - 1
diagmin := 1 << 25
for k := -e.limit; k <= e.limit; k += 2 {
x := e.getBackward(e.limit, k)
y := x - (k + e.delta)
if x+y < diagmin && x >= 0 && y >= 0 {
diagmin, kmax = x+y, k
}
}
if kmax < -e.limit {
panic(fmt.Sprintf("no paths when limit=%d?", e.limit))
}
return e.backwardlcs(e.limit, kmax)
}
// recover the lcs by backtracking
func (e *editGraph) backwardlcs(D, k int) lcs {
var ans lcs
for x := e.getBackward(D, k); x != e.ux || x-(k+e.delta) != e.uy; {
if ok(D-1, k-1) && x == e.getBackward(D-1, k-1) {
// D--, k--, x unchanged
D, k = D-1, k-1
continue
} else if ok(D-1, k+1) && x+1 == e.getBackward(D-1, k+1) {
// D--, k++, x++
D, k, x = D-1, k+1, x+1
continue
}
y := x - (k + e.delta)
ans = ans.append(x+e.lx, y+e.ly)
x++
}
return ans
}
// start at (x,y), go down the diagonal as far as possible,
func (e *editGraph) lookBackward(k, relx int) int {
rely := relx - (k + e.delta) // forward k = k + e.delta
x, y := relx+e.lx, rely+e.ly
if x > 0 && y > 0 {
x -= e.seqs.commonSuffixLen(0, x, 0, y)
}
return x
}
// convert to rectangle, and label the result with d
func (e *editGraph) setBackward(d, k, relx int) {
x := e.lookBackward(k, relx)
e.vb.set(d, k, x-e.lx)
}
func (e *editGraph) getBackward(d, k int) int {
x := e.vb.get(d, k)
return x
}
// -- TWOSIDED ---
func twosided(e *editGraph) lcs {
// The termination condition could be improved, as either the forward
// or backward pass could succeed before Myers' Lemma applies.
// Aside from questions of efficiency (is the extra testing cost-effective)
// this is more likely to matter when e.limit is reached.
e.setForward(0, 0, e.lx)
e.setBackward(0, 0, e.ux)
// from D to D+1
for D := range e.limit {
// just finished a backwards pass, so check
if got, ok := e.twoDone(D, D); ok {
return e.twolcs(D, D, got)
}
// do a forwards pass (D to D+1)
e.setForward(D+1, -(D + 1), e.getForward(D, -D))
e.setForward(D+1, D+1, e.getForward(D, D)+1)
for k := -D + 1; k <= D-1; k += 2 {
// these are tricky and easy to get backwards
lookv := e.lookForward(k, e.getForward(D, k-1)+1)
lookh := e.lookForward(k, e.getForward(D, k+1))
if lookv > lookh {
e.setForward(D+1, k, lookv)
} else {
e.setForward(D+1, k, lookh)
}
}
// just did a forward pass, so check
if got, ok := e.twoDone(D+1, D); ok {
return e.twolcs(D+1, D, got)
}
// do a backward pass, D to D+1
e.setBackward(D+1, -(D + 1), e.getBackward(D, -D)-1)
e.setBackward(D+1, D+1, e.getBackward(D, D))
for k := -D + 1; k <= D-1; k += 2 {
// these are tricky and easy to get wrong
lookv := e.lookBackward(k, e.getBackward(D, k-1))
lookh := e.lookBackward(k, e.getBackward(D, k+1)-1)
if lookv < lookh {
e.setBackward(D+1, k, lookv)
} else {
e.setBackward(D+1, k, lookh)
}
}
}
// D too large. combine a forward and backward partial lcs
// first, a forward one
kmax := -e.limit - 1
diagmax := -1
for k := -e.limit; k <= e.limit; k += 2 {
x := e.getForward(e.limit, k)
y := x - k
if x+y > diagmax && x <= e.ux && y <= e.uy {
diagmax, kmax = x+y, k
}
}
if kmax < -e.limit {
panic(fmt.Sprintf("no forward paths when limit=%d?", e.limit))
}
lcs := e.forwardlcs(e.limit, kmax)
// now a backward one
// find the D path with minimal x+y inside the rectangle and
// use that to compute the lcs
diagmin := 1 << 25 // infinity
for k := -e.limit; k <= e.limit; k += 2 {
x := e.getBackward(e.limit, k)
y := x - (k + e.delta)
if x+y < diagmin && x >= 0 && y >= 0 {
diagmin, kmax = x+y, k
}
}
if kmax < -e.limit {
panic(fmt.Sprintf("no backward paths when limit=%d?", e.limit))
}
lcs = append(lcs, e.backwardlcs(e.limit, kmax)...)
// These may overlap (e.forwardlcs and e.backwardlcs return sorted lcs)
ans := lcs.fix()
return ans
}
// Does Myers' Lemma apply?
func (e *editGraph) twoDone(df, db int) (int, bool) {
if (df+db+e.delta)%2 != 0 {
return 0, false // diagonals cannot overlap
}
kmin := max(-df, -db+e.delta)
kmax := db + e.delta
if df < kmax {
kmax = df
}
for k := kmin; k <= kmax; k += 2 {
x := e.vf.get(df, k)
u := e.vb.get(db, k-e.delta)
if u <= x {
// is it worth looking at all the other k?
for l := k; l <= kmax; l += 2 {
x := e.vf.get(df, l)
y := x - l
u := e.vb.get(db, l-e.delta)
v := u - l
if x == u || u == 0 || v == 0 || y == e.uy || x == e.ux {
return l, true
}
}
return k, true
}
}
return 0, false
}
func (e *editGraph) twolcs(df, db, kf int) lcs {
// db==df || db+1==df
x := e.vf.get(df, kf)
y := x - kf
kb := kf - e.delta
u := e.vb.get(db, kb)
v := u - kf
// Myers proved there is a df-path from (0,0) to (u,v)
// and a db-path from (x,y) to (N,M).
// In the first case the overall path is the forward path
// to (u,v) followed by the backward path to (N,M).
// In the second case the path is the backward path to (x,y)
// followed by the forward path to (x,y) from (0,0).
// Look for some special cases to avoid computing either of these paths.
if x == u {
// "babaab" "cccaba"
// already patched together
lcs := e.forwardlcs(df, kf)
lcs = append(lcs, e.backwardlcs(db, kb)...)
return lcs.sort()
}
// is (u-1,v) or (u,v-1) labelled df-1?
// if so, that forward df-1-path plus a horizontal or vertical edge
// is the df-path to (u,v), then plus the db-path to (N,M)
if u > 0 && ok(df-1, u-1-v) && e.vf.get(df-1, u-1-v) == u-1 {
// "aabbab" "cbcabc"
lcs := e.forwardlcs(df-1, u-1-v)
lcs = append(lcs, e.backwardlcs(db, kb)...)
return lcs.sort()
}
if v > 0 && ok(df-1, (u-(v-1))) && e.vf.get(df-1, u-(v-1)) == u {
// "abaabb" "bcacab"
lcs := e.forwardlcs(df-1, u-(v-1))
lcs = append(lcs, e.backwardlcs(db, kb)...)
return lcs.sort()
}
// The path can't possibly contribute to the lcs because it
// is all horizontal or vertical edges
if u == 0 || v == 0 || x == e.ux || y == e.uy {
// "abaabb" "abaaaa"
if u == 0 || v == 0 {
return e.backwardlcs(db, kb)
}
return e.forwardlcs(df, kf)
}
// is (x+1,y) or (x,y+1) labelled db-1?
if x+1 <= e.ux && ok(db-1, x+1-y-e.delta) && e.vb.get(db-1, x+1-y-e.delta) == x+1 {
// "bababb" "baaabb"
lcs := e.backwardlcs(db-1, kb+1)
lcs = append(lcs, e.forwardlcs(df, kf)...)
return lcs.sort()
}
if y+1 <= e.uy && ok(db-1, x-(y+1)-e.delta) && e.vb.get(db-1, x-(y+1)-e.delta) == x {
// "abbbaa" "cabacc"
lcs := e.backwardlcs(db-1, kb-1)
lcs = append(lcs, e.forwardlcs(df, kf)...)
return lcs.sort()
}
// need to compute another path
// "aabbaa" "aacaba"
lcs := e.backwardlcs(db, kb)
oldx, oldy := e.ux, e.uy
e.ux = u
e.uy = v
lcs = append(lcs, forward(e)...)
e.ux, e.uy = oldx, oldy
return lcs.sort()
}
================================================
FILE: internal/x/tools/diff/lcs/old_test.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lcs
import (
"fmt"
"log"
"math/rand/v2"
"os"
"strings"
"testing"
)
func TestAlgosOld(t *testing.T) {
for i, algo := range []func(*editGraph) lcs{forward, backward, twosided} {
t.Run(strings.Fields("forward backward twosided")[i], func(t *testing.T) {
for _, tx := range Btests {
lim := len(tx.a) + len(tx.b)
diffs, lcs := compute(stringSeqs{tx.a, tx.b}, algo, lim)
check(t, tx.a, lcs, tx.lcs)
checkDiffs(t, tx.a, diffs, tx.b)
diffs, lcs = compute(stringSeqs{tx.b, tx.a}, algo, lim)
check(t, tx.b, lcs, tx.lcs)
checkDiffs(t, tx.b, diffs, tx.a)
}
})
}
}
func TestIntOld(t *testing.T) {
// need to avoid any characters in btests
lfill, rfill := "AAAAAAAAAAAA", "BBBBBBBBBBBB"
for _, tx := range Btests {
if len(tx.a) < 2 || len(tx.b) < 2 {
continue
}
left := tx.a + lfill
right := tx.b + rfill
lim := len(tx.a) + len(tx.b)
diffs, lcs := compute(stringSeqs{left, right}, twosided, lim)
check(t, left, lcs, tx.lcs)
checkDiffs(t, left, diffs, right)
diffs, lcs = compute(stringSeqs{right, left}, twosided, lim)
check(t, right, lcs, tx.lcs)
checkDiffs(t, right, diffs, left)
left = lfill + tx.a
right = rfill + tx.b
diffs, lcs = compute(stringSeqs{left, right}, twosided, lim)
check(t, left, lcs, tx.lcs)
checkDiffs(t, left, diffs, right)
diffs, lcs = compute(stringSeqs{right, left}, twosided, lim)
check(t, right, lcs, tx.lcs)
checkDiffs(t, right, diffs, left)
}
}
func TestSpecialOld(t *testing.T) { // exercises lcs.fix
a := "golang.org/x/tools/intern"
b := "github.com/google/safehtml/template\"\n\t\"golang.org/x/tools/intern"
diffs, lcs := compute(stringSeqs{a, b}, twosided, 4)
if !lcs.valid() {
t.Errorf("%d,%v", len(diffs), lcs)
}
}
func TestRegressionOld001(t *testing.T) {
a := "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage diff_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"golang.org/x/tools/gopls/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/diff/difftest\"\n\t\"golang.org/x/tools/gopls/internal/span\"\n)\n"
b := "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage diff_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/safehtml/template\"\n\t\"golang.org/x/tools/gopls/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/diff/difftest\"\n\t\"golang.org/x/tools/gopls/internal/span\"\n)\n"
for i := 1; i < len(b); i++ {
diffs, lcs := compute(stringSeqs{a, b}, twosided, i) // 14 from gopls
if !lcs.valid() {
t.Errorf("%d,%v", len(diffs), lcs)
}
checkDiffs(t, a, diffs, b)
}
}
func TestRegressionOld002(t *testing.T) {
a := "n\"\n)\n"
b := "n\"\n\t\"golang.org/x//nnal/stack\"\n)\n"
for i := 1; i <= len(b); i++ {
diffs, lcs := compute(stringSeqs{a, b}, twosided, i)
if !lcs.valid() {
t.Errorf("%d,%v", len(diffs), lcs)
}
checkDiffs(t, a, diffs, b)
}
}
func TestRegressionOld003(t *testing.T) {
a := "golang.org/x/hello v1.0.0\nrequire golang.org/x/unused v1"
b := "golang.org/x/hello v1"
for i := 1; i <= len(a); i++ {
diffs, lcs := compute(stringSeqs{a, b}, twosided, i)
if !lcs.valid() {
t.Errorf("%d,%v", len(diffs), lcs)
}
checkDiffs(t, a, diffs, b)
}
}
func TestRandOld(t *testing.T) {
rng := rng(t)
for i := range 1000 {
// TODO(adonovan): use ASCII and bytesSeqs here? The use of
// non-ASCII isn't relevant to the property exercised by the test.
a := []rune(randstr(rng, "abω", 16))
b := []rune(randstr(rng, "abωc", 16))
seq := runesSeqs{a, b}
const lim = 0 // make sure we get the lcs (24 was too small)
_, forw := compute(seq, forward, lim)
_, back := compute(seq, backward, lim)
_, two := compute(seq, twosided, lim)
if lcslen(two) != lcslen(forw) || lcslen(forw) != lcslen(back) {
t.Logf("\n%v\n%v\n%v", forw, back, two)
t.Fatalf("%d forw:%d back:%d two:%d", i, lcslen(forw), lcslen(back), lcslen(two))
}
if !two.valid() || !forw.valid() || !back.valid() {
t.Errorf("check failure")
}
}
}
// TestDiffAPI tests the public API functions (Diff{Bytes,Strings,Runes})
// to ensure at least minimal parity of the three representations.
func TestDiffAPI(t *testing.T) {
for _, test := range []struct {
a, b string
wantStrings, wantBytes, wantRunes string
}{
{"abcXdef", "abcxdef", "[{3 4 3 4}]", "[{3 4 3 4}]", "[{3 4 3 4}]"}, // ASCII
{"abcωdef", "abcΩdef", "[{3 5 3 5}]", "[{3 5 3 5}]", "[{3 4 3 4}]"}, // non-ASCII
} {
gotStrings := fmt.Sprint(DiffStrings(test.a, test.b))
if gotStrings != test.wantStrings {
t.Errorf("DiffStrings(%q, %q) = %v, want %v",
test.a, test.b, gotStrings, test.wantStrings)
}
gotBytes := fmt.Sprint(DiffBytes([]byte(test.a), []byte(test.b)))
if gotBytes != test.wantBytes {
t.Errorf("DiffBytes(%q, %q) = %v, want %v",
test.a, test.b, gotBytes, test.wantBytes)
}
gotRunes := fmt.Sprint(DiffRunes([]rune(test.a), []rune(test.b)))
if gotRunes != test.wantRunes {
t.Errorf("DiffRunes(%q, %q) = %v, want %v",
test.a, test.b, gotRunes, test.wantRunes)
}
}
}
func BenchmarkTwoOld(b *testing.B) {
tests := genBench(rng(b), "abc", 96)
for i := 0; i < b.N; i++ {
for _, tt := range tests {
_, two := compute(stringSeqs{tt.before, tt.after}, twosided, 100)
if !two.valid() {
b.Error("check failed")
}
}
}
}
func BenchmarkForwOld(b *testing.B) {
tests := genBench(rng(b), "abc", 96)
for i := 0; i < b.N; i++ {
for _, tt := range tests {
_, two := compute(stringSeqs{tt.before, tt.after}, forward, 100)
if !two.valid() {
b.Error("check failed")
}
}
}
}
// rng returns a randomly initialized PRNG whose seeds are logged so
// that occasional test failures can be deterministically replayed.
func rng(tb testing.TB) *rand.Rand {
seed1, seed2 := rand.Uint64(), rand.Uint64()
tb.Logf("PRNG seeds: %d, %d", seed1, seed2)
return rand.New(rand.NewPCG(seed1, seed2))
}
func genBench(rng *rand.Rand, set string, n int) []struct{ before, after string } {
// before and after for benchmarks. 24 strings of length n with
// before and after differing at least once, and about 5%
var ans []struct{ before, after string }
for range 24 {
// maybe b should have an approximately known number of diffs
a := randstr(rng, set, n)
cnt := 0
bb := make([]rune, 0, n)
for _, r := range a {
if rand.Float64() < .05 {
cnt++
r = 'N'
}
bb = append(bb, r)
}
if cnt == 0 {
// avoid == shortcut
bb[n/2] = 'N'
}
ans = append(ans, struct{ before, after string }{a, string(bb)})
}
return ans
}
// This benchmark represents a common case for a diff command:
// large file with a single relatively small diff in the middle.
// (It's not clear whether this is representative of gopls workloads
// or whether it is important to gopls diff performance.)
//
// TODO(adonovan) opt: it could be much faster. For example,
// comparing a file against itself is about 10x faster than with the
// small deletion in the middle. Strangely, comparing a file against
// itself minus the last byte is faster still; I don't know why.
// There is much low-hanging fruit here for further improvement.
func BenchmarkLargeFileSmallDiff(b *testing.B) {
data, err := os.ReadFile("old.go") // large file
if err != nil {
log.Fatal(err)
}
n := len(data)
src := string(data)
dst := src[:n*49/100] + src[n*51/100:] // remove 2% from the middle
b.Run("string", func(b *testing.B) {
for i := 0; i < b.N; i++ {
compute(stringSeqs{src, dst}, twosided, len(src)+len(dst))
}
})
srcBytes := []byte(src)
dstBytes := []byte(dst)
b.Run("bytes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
compute(bytesSeqs{srcBytes, dstBytes}, twosided, len(srcBytes)+len(dstBytes))
}
})
srcRunes := []rune(src)
dstRunes := []rune(dst)
b.Run("runes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
compute(runesSeqs{srcRunes, dstRunes}, twosided, len(srcRunes)+len(dstRunes))
}
})
}
================================================
FILE: internal/x/tools/diff/lcs/sequence.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lcs
// This file defines the abstract sequence over which the LCS algorithm operates.
// sequences abstracts a pair of sequences, A and B.
type sequences interface {
lengths() (int, int) // len(A), len(B)
commonPrefixLen(ai, aj, bi, bj int) int // len(commonPrefix(A[ai:aj], B[bi:bj]))
commonSuffixLen(ai, aj, bi, bj int) int // len(commonSuffix(A[ai:aj], B[bi:bj]))
}
type stringSeqs struct{ a, b string }
func (s stringSeqs) lengths() (int, int) { return len(s.a), len(s.b) }
func (s stringSeqs) commonPrefixLen(ai, aj, bi, bj int) int {
return commonPrefixLenString(s.a[ai:aj], s.b[bi:bj])
}
func (s stringSeqs) commonSuffixLen(ai, aj, bi, bj int) int {
return commonSuffixLenString(s.a[ai:aj], s.b[bi:bj])
}
// The explicit capacity in s[i:j:j] leads to more efficient code.
type bytesSeqs struct{ a, b []byte }
func (s bytesSeqs) lengths() (int, int) { return len(s.a), len(s.b) }
func (s bytesSeqs) commonPrefixLen(ai, aj, bi, bj int) int {
return commonPrefixLenBytes(s.a[ai:aj:aj], s.b[bi:bj:bj])
}
func (s bytesSeqs) commonSuffixLen(ai, aj, bi, bj int) int {
return commonSuffixLenBytes(s.a[ai:aj:aj], s.b[bi:bj:bj])
}
type runesSeqs struct{ a, b []rune }
func (s runesSeqs) lengths() (int, int) { return len(s.a), len(s.b) }
func (s runesSeqs) commonPrefixLen(ai, aj, bi, bj int) int {
return commonPrefixLenRunes(s.a[ai:aj:aj], s.b[bi:bj:bj])
}
func (s runesSeqs) commonSuffixLen(ai, aj, bi, bj int) int {
return commonSuffixLenRunes(s.a[ai:aj:aj], s.b[bi:bj:bj])
}
// TODO(adonovan): optimize these functions using ideas from:
// - https://go.dev/cl/408116 common.go
// - https://go.dev/cl/421435 xor_generic.go
// TODO(adonovan): factor using generics when available,
// but measure performance impact.
// commonPrefixLen* returns the length of the common prefix of a[ai:aj] and b[bi:bj].
func commonPrefixLenBytes(a, b []byte) int {
n := min(len(a), len(b))
i := 0
for i < n && a[i] == b[i] {
i++
}
return i
}
func commonPrefixLenRunes(a, b []rune) int {
n := min(len(a), len(b))
i := 0
for i < n && a[i] == b[i] {
i++
}
return i
}
func commonPrefixLenString(a, b string) int {
n := min(len(a), len(b))
i := 0
for i < n && a[i] == b[i] {
i++
}
return i
}
// commonSuffixLen* returns the length of the common suffix of a[ai:aj] and b[bi:bj].
func commonSuffixLenBytes(a, b []byte) int {
n := min(len(a), len(b))
i := 0
for i < n && a[len(a)-1-i] == b[len(b)-1-i] {
i++
}
return i
}
func commonSuffixLenRunes(a, b []rune) int {
n := min(len(a), len(b))
i := 0
for i < n && a[len(a)-1-i] == b[len(b)-1-i] {
i++
}
return i
}
func commonSuffixLenString(a, b string) int {
n := min(len(a), len(b))
i := 0
for i < n && a[len(a)-1-i] == b[len(b)-1-i] {
i++
}
return i
}
func min(x, y int) int {
if x < y {
return x
} else {
return y
}
}
================================================
FILE: internal/x/tools/diff/myers/diff.go
================================================
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package myers implements the Myers diff algorithm.
package myers
import (
"strings"
"github.com/golangci/golangci-lint/v2/internal/x/tools/diff"
)
// Sources:
// https://blog.jcoglan.com/2017/02/17/the-myers-diff-algorithm-part-3/
// https://www.codeproject.com/Articles/42279/%2FArticles%2F42279%2FInvestigating-Myers-diff-algorithm-Part-1-of-2
// ComputeEdits returns the diffs of two strings using a simple
// line-based implementation, like [diff.Strings].
//
// Deprecated: this implementation is moribund. However, when diffs
// appear in marker test expectations, they are the particular diffs
// produced by this implementation. The marker test framework
// asserts diff(orig, got)==wantDiff, but ideally it would compute
// got==apply(orig, wantDiff) so that the notation of the diff
// is immaterial.
func ComputeEdits(before, after string) []diff.Edit {
beforeLines := splitLines(before)
ops := operations(beforeLines, splitLines(after))
// Build a table mapping line number to offset.
lineOffsets := make([]int, 0, len(beforeLines)+1)
total := 0
for i := range beforeLines {
lineOffsets = append(lineOffsets, total)
total += len(beforeLines[i])
}
lineOffsets = append(lineOffsets, total) // EOF
edits := make([]diff.Edit, 0, len(ops))
for _, op := range ops {
start, end := lineOffsets[op.I1], lineOffsets[op.I2]
switch op.Kind {
case opDelete:
// Delete: before[I1:I2] is deleted.
edits = append(edits, diff.Edit{Start: start, End: end})
case opInsert:
// Insert: after[J1:J2] is inserted at before[I1:I1].
if content := strings.Join(op.Content, ""); content != "" {
edits = append(edits, diff.Edit{Start: start, End: end, New: content})
}
}
}
return edits
}
// opKind is used to denote the type of operation a line represents.
type opKind int
const (
opDelete opKind = iota // line deleted from input (-)
opInsert // line inserted into output (+)
opEqual // line present in input and output
)
func (kind opKind) String() string {
switch kind {
case opDelete:
return "delete"
case opInsert:
return "insert"
case opEqual:
return "equal"
default:
panic("unknown opKind")
}
}
type operation struct {
Kind opKind
Content []string // content from b
I1, I2 int // indices of the line in a
J1 int // indices of the line in b, J2 implied by len(Content)
}
// operations returns the list of operations to convert a into b, consolidating
// operations for multiple lines and not including equal lines.
func operations(a, b []string) []*operation {
if len(a) == 0 && len(b) == 0 {
return nil
}
trace, offset := shortestEditSequence(a, b)
snakes := backtrack(trace, len(a), len(b), offset)
M, N := len(a), len(b)
var i int
solution := make([]*operation, len(a)+len(b))
add := func(op *operation, i2, j2 int) {
if op == nil {
return
}
op.I2 = i2
if op.Kind == opInsert {
op.Content = b[op.J1:j2]
}
solution[i] = op
i++
}
x, y := 0, 0
for _, snake := range snakes {
if len(snake) < 2 {
continue
}
var op *operation
// delete (horizontal)
for snake[0]-snake[1] > x-y {
if op == nil {
op = &operation{
Kind: opDelete,
I1: x,
J1: y,
}
}
x++
if x == M {
break
}
}
add(op, x, y)
op = nil
// insert (vertical)
for snake[0]-snake[1] < x-y {
if op == nil {
op = &operation{
Kind: opInsert,
I1: x,
J1: y,
}
}
y++
}
add(op, x, y)
op = nil
// equal (diagonal)
for x < snake[0] {
x++
y++
}
if x >= M && y >= N {
break
}
}
return solution[:i]
}
// backtrack uses the trace for the edit sequence computation and returns the
// "snakes" that make up the solution. A "snake" is a single deletion or
// insertion followed by zero or diagonals.
func backtrack(trace [][]int, x, y, offset int) [][]int {
snakes := make([][]int, len(trace))
d := len(trace) - 1
for ; x > 0 && y > 0 && d > 0; d-- {
V := trace[d]
if len(V) == 0 {
continue
}
snakes[d] = []int{x, y}
k := x - y
var kPrev int
if k == -d || (k != d && V[k-1+offset] < V[k+1+offset]) {
kPrev = k + 1
} else {
kPrev = k - 1
}
x = V[kPrev+offset]
y = x - kPrev
}
if x < 0 || y < 0 {
return snakes
}
snakes[d] = []int{x, y}
return snakes
}
// shortestEditSequence returns the shortest edit sequence that converts a into b.
func shortestEditSequence(a, b []string) ([][]int, int) {
M, N := len(a), len(b)
V := make([]int, 2*(N+M)+1)
offset := N + M
trace := make([][]int, N+M+1)
// Iterate through the maximum possible length of the SES (N+M).
for d := 0; d <= N+M; d++ {
copyV := make([]int, len(V))
// k lines are represented by the equation y = x - k. We move in
// increments of 2 because end points for even d are on even k lines.
for k := -d; k <= d; k += 2 {
// At each point, we either go down or to the right. We go down if
// k == -d, and we go to the right if k == d. We also prioritize
// the maximum x value, because we prefer deletions to insertions.
var x int
if k == -d || (k != d && V[k-1+offset] < V[k+1+offset]) {
x = V[k+1+offset] // down
} else {
x = V[k-1+offset] + 1 // right
}
y := x - k
// Diagonal moves while we have equal contents.
for x < M && y < N && a[x] == b[y] {
x++
y++
}
V[k+offset] = x
// Return if we've exceeded the maximum values.
if x == M && y == N {
// Makes sure to save the state of the array before returning.
copy(copyV, V)
trace[d] = copyV
return trace, offset
}
}
// Save the state of the array.
copy(copyV, V)
trace[d] = copyV
}
return nil, 0
}
func splitLines(text string) []string {
lines := strings.SplitAfter(text, "\n")
if lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
return lines
}
================================================
FILE: internal/x/tools/diff/ndiff.go
================================================
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package diff
import (
"bytes"
"unicode/utf8"
"github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs"
)
// Strings computes the differences between two strings.
// The resulting edits respect rune boundaries.
func Strings(before, after string) []Edit {
if before == after {
return nil // common case
}
if isASCII(before) && isASCII(after) {
// TODO(adonovan): opt: specialize diffASCII for strings.
return diffASCII([]byte(before), []byte(after))
}
return diffRunes([]rune(before), []rune(after))
}
// Bytes computes the differences between two byte slices.
// The resulting edits respect rune boundaries.
func Bytes(before, after []byte) []Edit {
if bytes.Equal(before, after) {
return nil // common case
}
if isASCII(before) && isASCII(after) {
return diffASCII(before, after)
}
return diffRunes(runes(before), runes(after))
}
func diffASCII(before, after []byte) []Edit {
diffs := lcs.DiffBytes(before, after)
// Convert from LCS diffs.
res := make([]Edit, len(diffs))
for i, d := range diffs {
res[i] = Edit{d.Start, d.End, string(after[d.ReplStart:d.ReplEnd])}
}
return res
}
func diffRunes(before, after []rune) []Edit {
diffs := lcs.DiffRunes(before, after)
// The diffs returned by the lcs package use indexes
// into whatever slice was passed in.
// Convert rune offsets to byte offsets.
res := make([]Edit, len(diffs))
lastEnd := 0
utf8Len := 0
for i, d := range diffs {
utf8Len += runesLen(before[lastEnd:d.Start]) // text between edits
start := utf8Len
utf8Len += runesLen(before[d.Start:d.End]) // text deleted by this edit
res[i] = Edit{start, utf8Len, string(after[d.ReplStart:d.ReplEnd])}
lastEnd = d.End
}
return res
}
// runes is like []rune(string(bytes)) without the duplicate allocation.
func runes(bytes []byte) []rune {
n := utf8.RuneCount(bytes)
runes := make([]rune, n)
for i := range n {
r, sz := utf8.DecodeRune(bytes)
bytes = bytes[sz:]
runes[i] = r
}
return runes
}
// runesLen returns the length in bytes of the UTF-8 encoding of runes.
func runesLen(runes []rune) (len int) {
for _, r := range runes {
len += utf8.RuneLen(r)
}
return len
}
// isASCII reports whether s contains only ASCII.
func isASCII[S string | []byte](s S) bool {
for i := 0; i < len(s); i++ {
if s[i] >= utf8.RuneSelf {
return false
}
}
return true
}
================================================
FILE: internal/x/tools/diff/readme.md
================================================
# diff
Extracted from `/internal/diff/` (related to `fixer`).
This is just a copy of the code without any changes.
## History
- https://github.com/golangci/golangci-lint/pull/6076
- sync with https://github.com/golang/tools/blob/v0.37.0/internal/diff/
- https://github.com/golangci/golangci-lint/pull/5576
- sync with https://github.com/golang/tools/blob/v0.28.0/internal/diff/
================================================
FILE: internal/x/tools/diff/unified.go
================================================
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package diff
import (
"fmt"
"log"
"strings"
)
// DefaultContextLines is the number of unchanged lines of surrounding
// context displayed by Unified. Use ToUnified to specify a different value.
const DefaultContextLines = 3
// Unified returns a unified diff of the old and new strings.
// The old and new labels are the names of the old and new files.
// If the strings are equal, it returns the empty string.
func Unified(oldLabel, newLabel, old, new string) string {
edits := Strings(old, new)
unified, err := ToUnified(oldLabel, newLabel, old, edits, DefaultContextLines)
if err != nil {
// Can't happen: edits are consistent.
log.Fatalf("internal error in diff.Unified: %v", err)
}
return unified
}
// ToUnified applies the edits to content and returns a unified diff,
// with contextLines lines of (unchanged) context around each diff hunk.
// The old and new labels are the names of the content and result files.
// It returns an error if the edits are inconsistent; see ApplyEdits.
func ToUnified(oldLabel, newLabel, content string, edits []Edit, contextLines int) (string, error) {
u, err := toUnified(oldLabel, newLabel, content, edits, contextLines)
if err != nil {
return "", err
}
return u.String(), nil
}
// unified represents a set of edits as a unified diff.
type unified struct {
// from is the name of the original file.
from string
// to is the name of the modified file.
to string
// hunks is the set of edit hunks needed to transform the file content.
hunks []*hunk
}
// Hunk represents a contiguous set of line edits to apply.
type hunk struct {
// The line in the original source where the hunk starts.
fromLine int
// The line in the original source where the hunk finishes.
toLine int
// The set of line based edits to apply.
lines []line
}
// Line represents a single line operation to apply as part of a Hunk.
type line struct {
// kind is the type of line this represents, deletion, insertion or copy.
kind opKind
// content is the content of this line.
// For deletion it is the line being removed, for all others it is the line
// to put in the output.
content string
}
// opKind is used to denote the type of operation a line represents.
type opKind int
const (
// opDelete is the operation kind for a line that is present in the input
// but not in the output.
opDelete opKind = iota
// opInsert is the operation kind for a line that is new in the output.
opInsert
// opEqual is the operation kind for a line that is the same in the input and
// output, often used to provide context around edited lines.
opEqual
)
// String returns a human readable representation of an OpKind. It is not
// intended for machine processing.
func (k opKind) String() string {
switch k {
case opDelete:
return "delete"
case opInsert:
return "insert"
case opEqual:
return "equal"
default:
panic("unknown operation kind")
}
}
// toUnified takes a file contents and a sequence of edits, and calculates
// a unified diff that represents those edits.
func toUnified(fromName, toName string, content string, edits []Edit, contextLines int) (unified, error) {
gap := contextLines * 2
u := unified{
from: fromName,
to: toName,
}
if len(edits) == 0 {
return u, nil
}
var err error
edits, err = lineEdits(content, edits) // expand to whole lines
if err != nil {
return u, err
}
lines := splitLines(content)
var h *hunk
last := 0
toLine := 0
for _, edit := range edits {
// Compute the zero-based line numbers of the edit start and end.
// TODO(adonovan): opt: compute incrementally, avoid O(n^2).
start := strings.Count(content[:edit.Start], "\n")
end := strings.Count(content[:edit.End], "\n")
if edit.End == len(content) && len(content) > 0 && content[len(content)-1] != '\n' {
end++ // EOF counts as an implicit newline
}
switch {
case h != nil && start == last:
// direct extension
case h != nil && start <= last+gap:
// within range of previous lines, add the joiners
addEqualLines(h, lines, last, start)
default:
// need to start a new hunk
if h != nil {
// add the edge to the previous hunk
addEqualLines(h, lines, last, last+contextLines)
u.hunks = append(u.hunks, h)
}
toLine += start - last
h = &hunk{
fromLine: start + 1,
toLine: toLine + 1,
}
// add the edge to the new hunk
delta := addEqualLines(h, lines, start-contextLines, start)
h.fromLine -= delta
h.toLine -= delta
}
last = start
for i := start; i < end; i++ {
h.lines = append(h.lines, line{kind: opDelete, content: lines[i]})
last++
}
if edit.New != "" {
for _, content := range splitLines(edit.New) {
h.lines = append(h.lines, line{kind: opInsert, content: content})
toLine++
}
}
}
if h != nil {
// add the edge to the final hunk
addEqualLines(h, lines, last, last+contextLines)
u.hunks = append(u.hunks, h)
}
return u, nil
}
func splitLines(text string) []string {
lines := strings.SplitAfter(text, "\n")
if lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
return lines
}
func addEqualLines(h *hunk, lines []string, start, end int) int {
delta := 0
for i := start; i < end; i++ {
if i < 0 {
continue
}
if i >= len(lines) {
return delta
}
h.lines = append(h.lines, line{kind: opEqual, content: lines[i]})
delta++
}
return delta
}
// String converts a unified diff to the standard textual form for that diff.
// The output of this function can be passed to tools like patch.
func (u unified) String() string {
if len(u.hunks) == 0 {
return ""
}
b := new(strings.Builder)
fmt.Fprintf(b, "--- %s\n", u.from)
fmt.Fprintf(b, "+++ %s\n", u.to)
for _, hunk := range u.hunks {
fromCount, toCount := 0, 0
for _, l := range hunk.lines {
switch l.kind {
case opDelete:
fromCount++
case opInsert:
toCount++
default:
fromCount++
toCount++
}
}
fmt.Fprint(b, "@@")
if fromCount > 1 {
fmt.Fprintf(b, " -%d,%d", hunk.fromLine, fromCount)
} else if hunk.fromLine == 1 && fromCount == 0 {
// Match odd GNU diff -u behavior adding to empty file.
fmt.Fprintf(b, " -0,0")
} else {
fmt.Fprintf(b, " -%d", hunk.fromLine)
}
if toCount > 1 {
fmt.Fprintf(b, " +%d,%d", hunk.toLine, toCount)
} else if hunk.toLine == 1 && toCount == 0 {
// Match odd GNU diff -u behavior adding to empty file.
fmt.Fprintf(b, " +0,0")
} else {
fmt.Fprintf(b, " +%d", hunk.toLine)
}
fmt.Fprint(b, " @@\n")
for _, l := range hunk.lines {
switch l.kind {
case opDelete:
fmt.Fprintf(b, "-%s", l.content)
case opInsert:
fmt.Fprintf(b, "+%s", l.content)
default:
fmt.Fprintf(b, " %s", l.content)
}
if !strings.HasSuffix(l.content, "\n") {
fmt.Fprintf(b, "\n\\ No newline at end of file\n")
}
}
}
return b.String()
}
================================================
FILE: internal/x/tools/driverutil/readfile.go
================================================
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package driverutil
// This file defines helpers for implementing [analysis.Pass.ReadFile].
import (
"fmt"
"slices"
"golang.org/x/tools/go/analysis"
)
// A ReadFileFunc is a function that returns the
// contents of a file, such as [os.ReadFile].
type ReadFileFunc = func(filename string) ([]byte, error)
// CheckedReadFile returns a wrapper around a Pass.ReadFile
// function that performs the appropriate checks.
func CheckedReadFile(pass *analysis.Pass, readFile ReadFileFunc) ReadFileFunc {
return func(filename string) ([]byte, error) {
if err := CheckReadable(pass, filename); err != nil {
return nil, err
}
return readFile(filename)
}
}
// CheckReadable enforces the access policy defined by the ReadFile field of [analysis.Pass].
func CheckReadable(pass *analysis.Pass, filename string) error {
if slices.Contains(pass.OtherFiles, filename) ||
slices.Contains(pass.IgnoredFiles, filename) {
return nil
}
for _, f := range pass.Files {
if pass.Fset.File(f.FileStart).Name() == filename {
return nil
}
}
return fmt.Errorf("Pass.ReadFile: %s is not among OtherFiles, IgnoredFiles, or names of Files", filename)
}
================================================
FILE: internal/x/tools/driverutil/readme.md
================================================
# driverutil
Extracted from `/internal/analysis/driverutil/` (related to `checker`).
This is just a copy of `readfile.go` and `url.go` without any changes.
Previously, it was `analysisinternal` and `analysisflags` packages.
## History
- https://github.com/golangci/golangci-lint/pull/6434
- sync with https://github.com/golang/tools/blob/v0.43.0/internal/analysis/driverutil/readfile.go
## analysisinternal History
- https://github.com/golangci/golangci-lint/pull/6076
- sync with https://github.com/golang/tools/blob/v0.37.0/internal/analysisinternal/
- https://github.com/golangci/golangci-lint/pull/5576
- sync with https://github.com/golang/tools/blob/v0.28.0/internal/analysisinternal/
## analysisflags History
- https://github.com/golangci/golangci-lint/pull/6076
- sync with https://github.com/golang/tools/blob/v0.37.0/go/analysis/internal/analysisflags
- https://github.com/golangci/golangci-lint/pull/5576
- sync with https://github.com/golang/tools/blob/v0.28.0/go/analysis/internal/analysisflags
================================================
FILE: internal/x/tools/driverutil/url.go
================================================
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package driverutil
import (
"fmt"
"net/url"
"golang.org/x/tools/go/analysis"
)
// ResolveURL resolves the URL field for a Diagnostic from an Analyzer
// and returns the URL. See Diagnostic.URL for details.
func ResolveURL(a *analysis.Analyzer, d analysis.Diagnostic) (string, error) {
if d.URL == "" && d.Category == "" && a.URL == "" {
return "", nil // do nothing
}
raw := d.URL
if d.URL == "" && d.Category != "" {
raw = "#" + d.Category
}
u, err := url.Parse(raw)
if err != nil {
return "", fmt.Errorf("invalid Diagnostic.URL %q: %s", raw, err)
}
base, err := url.Parse(a.URL)
if err != nil {
return "", fmt.Errorf("invalid Analyzer.URL %q: %s", a.URL, err)
}
return base.ResolveReference(u).String(), nil
}
================================================
FILE: jsonschema/custom-gcl.jsonschema.json
================================================
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$ref": "#/$defs/Configuration",
"$defs": {
"Configuration": {
"properties": {
"version": {
"type": "string",
"description": "golangci-lint version."
},
"name": {
"type": "string",
"description": "Name of the binary."
},
"destination": {
"type": "string",
"description": "Destination is the path to a directory to store the binary."
},
"plugins": {
"items": {
"$ref": "#/$defs/Plugin"
},
"type": "array",
"description": "Plugins information."
}
},
"additionalProperties": false,
"type": "object",
"required": [
"version"
],
"description": "Configuration represents the configuration file."
},
"Plugin": {
"oneOf": [
{
"required": [
"version"
],
"title": "version"
},
{
"required": [
"path"
],
"title": "path"
}
],
"properties": {
"module": {
"type": "string",
"description": "Module name."
},
"import": {
"type": "string",
"description": "Import to use."
},
"version": {
"type": "string",
"description": "Version of the module.\nOnly for module available through a Go proxy."
},
"path": {
"type": "string",
"description": "Path to the local module.\nOnly for local module."
}
},
"additionalProperties": false,
"type": "object",
"required": [
"module"
],
"description": "Plugin represents information about a plugin."
}
},
"description": "mygcl configuration definition file"
}
================================================
FILE: jsonschema/golangci.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupOption",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr",
"zeroByteRepeat"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"godoclint-rules": {
"enum": [
"pkg-doc",
"single-pkg-doc",
"require-pkg-doc",
"start-with-name",
"require-doc",
"deprecated",
"max-len",
"no-unused-link",
"require-stdlib-doclink"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G116",
"G117",
"G118",
"G119",
"G120",
"G121",
"G122",
"G123",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G408",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602",
"G701",
"G702",
"G703",
"G704",
"G705",
"G706",
"G707"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"epoch-naming",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"forbidden-call-in-wg-go",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"identical-ifelseif-branches",
"identical-ifelseif-conditions",
"identical-switch-branches",
"identical-switch-conditions",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"inefficient-map-lookup",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"package-naming",
"package-directory-mismatch",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-if",
"unnecessary-stmt",
"unreachable-code",
"unsecure-url-scheme",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"use-slices-sort",
"use-waitgroup-go",
"useless-break",
"useless-fallthrough",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"modernize-analyzers": {
"enum": [
"any",
"fmtappendf",
"forvar",
"mapsloop",
"minmax",
"newexpr",
"omitzero",
"plusbuild",
"rangeint",
"reflecttypefor",
"slicescontains",
"slicessort",
"stditerators",
"stringscut",
"stringscutprefix",
"stringsseq",
"stringsbuilder",
"testingcontext",
"unsafefuncs",
"waitgroup"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace",
"after-block"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godoclint",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"iotamixing",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"modernize",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
},
"comments-only": {
"description": "Checks only comments, skip strings.",
"type": "boolean",
"default": false
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"empty-line": {
"description": "Checks that there is an empty space between the embedded fields and regular fields.",
"type": "boolean",
"default": false
},
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
},
"force-tonot": {
"description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godoclintSettings": {
"type": "object",
"properties": {
"default": {
"type": "string",
"enum": ["all", "basic", "none"],
"default": "basic",
"description": "Default set of rules to enable."
},
"enable": {
"description": "List of rules to enable in addition to the default set.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"disable": {
"description": "List of rules to disable.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"options": {
"type": "object",
"description": "A map for setting individual rule options.",
"properties": {
"max-len": {
"type": "object",
"properties": {
"length": {
"type": "integer",
"description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
"default": 77
}
}
},
"require-doc": {
"type": "object",
"properties": {
"ignore-exported": {
"type": "boolean",
"description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
"default": false
},
"ignore-unexported": {
"type": "boolean",
"description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
"default": true
}
}
},
"start-with-name": {
"type": "object",
"properties": {
"include-unexported": {
"type": "boolean",
"description": "Include unexported symbols when applying the `start-with-name` rule.",
"default": false
}
}
}
}
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
},
"check-module-path": {
"description": "Check the validity of the module path.",
"type": "boolean",
"default": false
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ineffassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-escaping-errors": {
"description": "Check escaping variables of type error, may cause false positives.",
"type": "boolean",
"default": false
}
}
},
"iotamixingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-individual": {
"description": "Whether to report individual consts rather than just the const block.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"modernizeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {
"description": "List of analyzers to disable.",
"type": "array",
"items": {
"$ref": "#/definitions/modernize-analyzers"
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
},
"concat-loop": {
"description": "Enable/disable optimization of concat loop.",
"type": "boolean",
"default": true
},
"loop-other-ops": {
"description": "Optimization of `concat-loop` even with other operations.",
"type": "boolean",
"default": false
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"enable-default-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unqueryvetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-sql-builders": {
"description": "Enable SQL builder checking.",
"type": "boolean",
"default": true
},
"check-aliased-wildcard": {
"description": "Enable aliased wildcard detection like SELECT t.*.",
"type": "boolean",
"default": true
},
"check-string-concat": {
"description": "Enable string concatenation analysis.",
"type": "boolean",
"default": true
},
"check-format-strings": {
"description": "Enable format string analysis like fmt.Sprintf.",
"type": "boolean",
"default": true
},
"check-string-builder": {
"description": "Enable strings.Builder analysis.",
"type": "boolean",
"default": true
},
"check-subqueries": {
"description": "Enable subquery analysis.",
"type": "boolean",
"default": true
},
"check-n1": {
"type": "boolean",
"default": false
},
"check-sql-injection": {
"type": "boolean",
"default": false
},
"check-tx-leaks": {
"type": "boolean",
"default": false
},
"allowed-patterns": {
"description": "Regex patterns for acceptable SELECT * usage.",
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "Allow is a list of SQL patterns to allow (whitelist).",
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Functions to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"sql-builders": {
"type": "object",
"additionalProperties": false,
"properties": {
"squirrel": {
"type": "boolean",
"default": true
},
"gorm": {
"type": "boolean",
"default": true
},
"sqlx": {
"type": "boolean",
"default": true
},
"ent": {
"type": "boolean",
"default": true
},
"pgx": {
"type": "boolean",
"default": true
},
"bun": {
"type": "boolean",
"default": true
},
"sqlboiler": {
"type": "boolean",
"default": true
},
"jet": {
"type": "boolean",
"default": true
}
}
},
"custom-rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"pattern": {
"type": "string"
},
"patterns": {
"type": "array",
"items": {
"type": "string"
}
},
"when": {
"type": "string"
},
"message": {
"type": "string"
},
"action": {
"type": "string"
}
}
}
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"enable-build-vcs": {
"type": "boolean",
"default": false
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godoclint": {
"$ref": "#/definitions/settings/definitions/godoclintSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ineffassign": {
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
},
"iotamixing": {
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"modernize": {
"$ref": "#/definitions/settings/definitions/modernizeSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unqueryvet": {
"$ref": "#/definitions/settings/definitions/unqueryvetSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.next.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupOption",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr",
"zeroByteRepeat"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"godoclint-rules": {
"enum": [
"pkg-doc",
"single-pkg-doc",
"require-pkg-doc",
"start-with-name",
"require-doc",
"deprecated",
"max-len",
"no-unused-link",
"require-stdlib-doclink"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G116",
"G117",
"G118",
"G119",
"G120",
"G121",
"G122",
"G123",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G408",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602",
"G701",
"G702",
"G703",
"G704",
"G705",
"G706",
"G707"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"epoch-naming",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"forbidden-call-in-wg-go",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"identical-ifelseif-branches",
"identical-ifelseif-conditions",
"identical-switch-branches",
"identical-switch-conditions",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"inefficient-map-lookup",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"package-naming",
"package-directory-mismatch",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-if",
"unnecessary-stmt",
"unreachable-code",
"unsecure-url-scheme",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"use-slices-sort",
"use-waitgroup-go",
"useless-break",
"useless-fallthrough",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"modernize-analyzers": {
"enum": [
"any",
"fmtappendf",
"forvar",
"mapsloop",
"minmax",
"newexpr",
"omitzero",
"plusbuild",
"rangeint",
"reflecttypefor",
"slicescontains",
"slicessort",
"stditerators",
"stringscut",
"stringscutprefix",
"stringsseq",
"stringsbuilder",
"testingcontext",
"unsafefuncs",
"waitgroup"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace",
"after-block"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godoclint",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"iotamixing",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"modernize",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
},
"comments-only": {
"description": "Checks only comments, skip strings.",
"type": "boolean",
"default": false
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"empty-line": {
"description": "Checks that there is an empty space between the embedded fields and regular fields.",
"type": "boolean",
"default": false
},
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
},
"force-tonot": {
"description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godoclintSettings": {
"type": "object",
"properties": {
"default": {
"type": "string",
"enum": ["all", "basic", "none"],
"default": "basic",
"description": "Default set of rules to enable."
},
"enable": {
"description": "List of rules to enable in addition to the default set.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"disable": {
"description": "List of rules to disable.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"options": {
"type": "object",
"description": "A map for setting individual rule options.",
"properties": {
"max-len": {
"type": "object",
"properties": {
"length": {
"type": "integer",
"description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
"default": 77
}
}
},
"require-doc": {
"type": "object",
"properties": {
"ignore-exported": {
"type": "boolean",
"description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
"default": false
},
"ignore-unexported": {
"type": "boolean",
"description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
"default": true
}
}
},
"start-with-name": {
"type": "object",
"properties": {
"include-unexported": {
"type": "boolean",
"description": "Include unexported symbols when applying the `start-with-name` rule.",
"default": false
}
}
}
}
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
},
"check-module-path": {
"description": "Check the validity of the module path.",
"type": "boolean",
"default": false
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ineffassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-escaping-errors": {
"description": "Check escaping variables of type error, may cause false positives.",
"type": "boolean",
"default": false
}
}
},
"iotamixingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-individual": {
"description": "Whether to report individual consts rather than just the const block.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"modernizeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {
"description": "List of analyzers to disable.",
"type": "array",
"items": {
"$ref": "#/definitions/modernize-analyzers"
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
},
"concat-loop": {
"description": "Enable/disable optimization of concat loop.",
"type": "boolean",
"default": true
},
"loop-other-ops": {
"description": "Optimization of `concat-loop` even with other operations.",
"type": "boolean",
"default": false
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"enable-default-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unqueryvetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-sql-builders": {
"description": "Enable SQL builder checking.",
"type": "boolean",
"default": true
},
"check-aliased-wildcard": {
"description": "Enable aliased wildcard detection like SELECT t.*.",
"type": "boolean",
"default": true
},
"check-string-concat": {
"description": "Enable string concatenation analysis.",
"type": "boolean",
"default": true
},
"check-format-strings": {
"description": "Enable format string analysis like fmt.Sprintf.",
"type": "boolean",
"default": true
},
"check-string-builder": {
"description": "Enable strings.Builder analysis.",
"type": "boolean",
"default": true
},
"check-subqueries": {
"description": "Enable subquery analysis.",
"type": "boolean",
"default": true
},
"check-n1": {
"type": "boolean",
"default": false
},
"check-sql-injection": {
"type": "boolean",
"default": false
},
"check-tx-leaks": {
"type": "boolean",
"default": false
},
"allowed-patterns": {
"description": "Regex patterns for acceptable SELECT * usage.",
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "Allow is a list of SQL patterns to allow (whitelist).",
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Functions to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"sql-builders": {
"type": "object",
"additionalProperties": false,
"properties": {
"squirrel": {
"type": "boolean",
"default": true
},
"gorm": {
"type": "boolean",
"default": true
},
"sqlx": {
"type": "boolean",
"default": true
},
"ent": {
"type": "boolean",
"default": true
},
"pgx": {
"type": "boolean",
"default": true
},
"bun": {
"type": "boolean",
"default": true
},
"sqlboiler": {
"type": "boolean",
"default": true
},
"jet": {
"type": "boolean",
"default": true
}
}
},
"custom-rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"pattern": {
"type": "string"
},
"patterns": {
"type": "array",
"items": {
"type": "string"
}
},
"when": {
"type": "string"
},
"message": {
"type": "string"
},
"action": {
"type": "string"
}
}
}
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"enable-build-vcs": {
"type": "boolean",
"default": false
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godoclint": {
"$ref": "#/definitions/settings/definitions/godoclintSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ineffassign": {
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
},
"iotamixing": {
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"modernize": {
"$ref": "#/definitions/settings/definitions/modernizeSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unqueryvet": {
"$ref": "#/definitions/settings/definitions/unqueryvetSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.57.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentedOutCode",
"commentedOutImport",
"commentFormatting",
"defaultCaseOrder",
"deferUnlambda",
"deferInLoop",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringsCompare",
"stringXbytes",
"suspiciousSorting",
"switchTrue",
"syncMapLoadAndDelete",
"timeCmpSimplify",
"timeExprSimplify",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G501",
"G502",
"G503",
"G504",
"G505",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"deadcode",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"execinquery",
"exhaustive",
"exhaustivestruct",
"exhaustruct",
"exportloopref",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"goerr113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"golint",
"gomnd",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"ifshort",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"interfacer",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"maligned",
"mirror",
"misspell",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosnakecase",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"revive",
"rowserrcheck",
"scopelint",
"sloglint",
"sqlclosecheck",
"staticcheck",
"structcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"typecheck",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"varcheck",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"checkstyle",
"code-climate",
"junit-xml",
"github-actions",
"teamcity"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"ignore": {
"description": "DEPRECATED: use `exclude-functions` instead. Comma-separated list of pairs of the form \"pkg:regex\".",
"type": "string",
"default": "fmt:.*"
},
"exclude": {
"description": "DEPRECATED: use `exclude-functions` instead. Path to a file containing a list of functions to exclude from checking.",
"type": "string",
"examples": ["/path/to/file.txt"]
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print.*$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "DEPRECATED: use 'sections' and 'prefix(github.com/org/project)' instead.",
"type": "string",
"examples": ["github.com/org/project"]
},
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"type": "string"
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"lang-version": {
"description": "Select the Go version to target.",
"type": "string",
"default": "1.15"
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": true
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": true
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"go": {
"description": "Targeted Go version",
"type": "string",
"default": "1.13"
},
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"checked-types": {
"type": "array",
"description": "Order of return types to check.",
"items": {
"enum": ["ptr", "func", "iface", "map", "chan"]
},
"default": ["ptr", "func", "iface", "map", "chan"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"type": "string",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context-only": {
"description": "Enforce using methods that accept a context.",
"type": "boolean",
"default": false
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"go": {
"description": "Targeted Go version",
"type": "string",
"default": "1.13"
},
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"go": {
"description": "Targeted Go version",
"type": "string",
"default": "1.13"
},
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"enum": [
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"type": "boolean",
"default": false
}
}
},
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"go-require",
"float-compare",
"len",
"nil-compare",
"require-error",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-thelper",
"useless-assert"
]
}
},
"disable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"go-require",
"float-compare",
"len",
"nil-compare",
"require-error",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-thelper",
"useless-assert"
]
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string"
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for expected variable name.",
"type": "string"
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"]
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"os-dev-null": {
"description": "Suggest the use of os.DevNull.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
},
"syslog-priority": {
"description": "Suggest the use of syslog.Priority.",
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-is-used": {
"description": "",
"type": "boolean",
"default": true
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated-strict": {
"description": "To follow strict Go generated file convention",
"type": "boolean",
"default": false
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.58.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentedOutCode",
"commentedOutImport",
"commentFormatting",
"defaultCaseOrder",
"deferUnlambda",
"deferInLoop",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringsCompare",
"stringXbytes",
"suspiciousSorting",
"switchTrue",
"syncMapLoadAndDelete",
"timeCmpSimplify",
"timeExprSimplify",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G501",
"G502",
"G503",
"G504",
"G505",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"deadcode",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"execinquery",
"exhaustive",
"exhaustivestruct",
"exhaustruct",
"exportloopref",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"golint",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"ifshort",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"interfacer",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"maligned",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosnakecase",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"revive",
"rowserrcheck",
"scopelint",
"sloglint",
"sqlclosecheck",
"staticcheck",
"structcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"typecheck",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"varcheck",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"html",
"checkstyle",
"code-climate",
"junit-xml",
"github-actions",
"teamcity"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print.*$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": true
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": true
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"checked-types": {
"type": "array",
"description": "Order of return types to check.",
"items": {
"enum": ["ptr", "func", "iface", "map", "chan"]
},
"default": ["ptr", "func", "iface", "map", "chan"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"type": "string",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"enum": [
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"type": "boolean",
"default": false
}
}
},
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"go-require",
"float-compare",
"len",
"nil-compare",
"require-error",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-thelper",
"useless-assert"
]
}
},
"disable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"go-require",
"float-compare",
"len",
"nil-compare",
"require-error",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-thelper",
"useless-assert"
]
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string"
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for expected variable name.",
"type": "string"
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"]
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-is-used": {
"description": "",
"type": "boolean",
"default": true
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated-strict": {
"description": "To follow strict Go generated file convention",
"type": "boolean",
"default": false
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.59.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentedOutCode",
"commentedOutImport",
"commentFormatting",
"defaultCaseOrder",
"deferUnlambda",
"deferInLoop",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringsCompare",
"stringXbytes",
"suspiciousSorting",
"switchTrue",
"syncMapLoadAndDelete",
"timeCmpSimplify",
"timeExprSimplify",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G501",
"G502",
"G503",
"G504",
"G505",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range",
"range-val-address",
"range-val-in-closure",
"receiver-naming",
"redefines-builtin-id",
"redundant-import-alias",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"deadcode",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"execinquery",
"exhaustive",
"exhaustivestruct",
"exhaustruct",
"exportloopref",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"golint",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"ifshort",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"interfacer",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"maligned",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosnakecase",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"revive",
"rowserrcheck",
"scopelint",
"sloglint",
"sqlclosecheck",
"staticcheck",
"structcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"typecheck",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"varcheck",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"html",
"checkstyle",
"code-climate",
"junit-xml",
"github-actions",
"teamcity",
"sarif"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print.*$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": true
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": true
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
},
"default": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"enum": [
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-is-used": {
"description": "",
"type": "boolean",
"default": true
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated": {
"description": "Mode of the generated files analysis.",
"enum": ["lax", "strict", "disable"],
"default": "lax"
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.60.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentedOutCode",
"commentedOutImport",
"commentFormatting",
"defaultCaseOrder",
"deferUnlambda",
"deferInLoop",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringsCompare",
"stringXbytes",
"suspiciousSorting",
"switchTrue",
"syncMapLoadAndDelete",
"timeCmpSimplify",
"timeExprSimplify",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range",
"range-val-address",
"range-val-in-closure",
"receiver-naming",
"redefines-builtin-id",
"redundant-import-alias",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"deadcode",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"execinquery",
"exhaustive",
"exhaustivestruct",
"exhaustruct",
"exportloopref",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"golint",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"ifshort",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"interfacer",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"maligned",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosnakecase",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"revive",
"rowserrcheck",
"scopelint",
"sloglint",
"sqlclosecheck",
"staticcheck",
"structcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"typecheck",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"varcheck",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"html",
"checkstyle",
"code-climate",
"junit-xml",
"github-actions",
"teamcity",
"sarif"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print.*$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": true
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": true
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
},
"default": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"enum": [
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"float-compare",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions if format string is used.",
"type": "boolean",
"default": false
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated": {
"description": "Mode of the generated files analysis.",
"enum": ["lax", "strict", "disable"],
"default": "lax"
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.61.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentedOutCode",
"commentedOutImport",
"commentFormatting",
"defaultCaseOrder",
"deferUnlambda",
"deferInLoop",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringsCompare",
"stringXbytes",
"suspiciousSorting",
"switchTrue",
"syncMapLoadAndDelete",
"timeCmpSimplify",
"timeExprSimplify",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range",
"range-val-address",
"range-val-in-closure",
"receiver-naming",
"redefines-builtin-id",
"redundant-import-alias",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"deadcode",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"execinquery",
"exhaustive",
"exhaustivestruct",
"exhaustruct",
"exportloopref",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"golint",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"ifshort",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"interfacer",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"maligned",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosnakecase",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"revive",
"rowserrcheck",
"scopelint",
"sloglint",
"sqlclosecheck",
"staticcheck",
"structcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"varcheck",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"html",
"checkstyle",
"code-climate",
"junit-xml",
"junit-xml-extended",
"github-actions",
"teamcity",
"sarif"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print(ln)?$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": true
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": true
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
},
"default": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"enum": [
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"float-compare",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"empty",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions if format string is used.",
"type": "boolean",
"default": false
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated": {
"description": "Mode of the generated files analysis.",
"enum": ["lax", "strict", "disable"],
"default": "lax"
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.62.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range",
"range-val-address",
"range-val-in-closure",
"receiver-naming",
"redefines-builtin-id",
"redundant-import-alias",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exportloopref",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"html",
"checkstyle",
"code-climate",
"junit-xml",
"junit-xml-extended",
"github-actions",
"teamcity",
"sarif"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print(ln)?$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtype": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": false
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"iface": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"enum": [
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated": {
"description": "Mode of the generated files analysis.",
"enum": ["lax", "strict", "disable"],
"default": "lax"
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.63.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range",
"range-val-address",
"range-val-in-closure",
"receiver-naming",
"redefines-builtin-id",
"redundant-import-alias",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque"
]
},
"tagliatelle-cases": {
"enum": [
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exportloopref",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"html",
"checkstyle",
"code-climate",
"junit-xml",
"junit-xml-extended",
"github-actions",
"teamcity",
"sarif"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print(ln)?$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtype": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"iface": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetesting": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": true
},
"context-todo": {
"type": "boolean",
"default": true
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": false
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated": {
"description": "Mode of the generated files analysis.",
"enum": ["lax", "strict", "disable"],
"default": "lax"
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.64.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"html",
"checkstyle",
"code-climate",
"junit-xml",
"junit-xml-extended",
"github-actions",
"teamcity",
"sarif"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"fatcontext": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print(ln)?$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtype": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"iface": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetesting": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": true
},
"context-todo": {
"type": "boolean",
"default": true
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "lax"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"default": {
"type": "array",
"items": {
"enum": [
"comments",
"stdErrorHandling",
"commonFalsePositives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated": {
"description": "Mode of the generated files analysis.",
"enum": ["lax", "strict", "disable"],
"default": "lax"
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"enum": [
"EXC0001",
"EXC0002",
"EXC0003",
"EXC0004",
"EXC0005",
"EXC0006",
"EXC0007",
"EXC0008",
"EXC0009",
"EXC0010",
"EXC0011",
"EXC0012",
"EXC0013",
"EXC0014",
"EXC0015"
]
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v1.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"linters": {
"$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
"description": "Linters usable.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"gci",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"gofmt",
"gofumpt",
"goheader",
"goimports",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"tenv",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"default": "stdout",
"anyOf": [
{
"enum": [ "stdout", "stderr" ]
},
{
"type": "string"
}
]
},
"format": {
"default": "colored-line-number",
"enum": [
"colored-line-number",
"line-number",
"json",
"colored-tab",
"tab",
"html",
"checkstyle",
"code-climate",
"junit-xml",
"junit-xml-extended",
"github-actions",
"teamcity",
"sarif"
]
}
},
"required": ["format"]
}
},
"print-issued-lines": {
"description": "Print lines of code with issue.",
"type": "boolean",
"default": true
},
"print-linter-name": {
"description": "Print linter name in the end of issue text.",
"type": "boolean",
"default": true
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": false
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
},
"sort-results": {
"description": "Sort results by: filepath, line and column.",
"type": "boolean",
"default": true
}
}
},
"linters-settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalint": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
},
"ignore-test": {
"description": "Ignore *_test.go files.",
"type": "boolean",
"default": false
}
}
},
"bidichk": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclop": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-tests": {
"description": "Should the linter execute on test files as well",
"type": "boolean",
"default": false
},
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorder": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsled": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"dupl": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjson": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustive": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"check-generated": {
"description": "Check switch statements in generated files",
"type": "boolean",
"default": false
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustruct": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"fatcontext": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigo": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"examples": ["^print(ln)?$"],
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"p": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
]
}
}
}
},
"funlen": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": false
}
}
},
"gci": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"skip-generated": {
"description": "Skip generated files.",
"type": "boolean",
"default": true
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtype": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognit": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconst": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocritic": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocyclo": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godot": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godox": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmt": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"interfacebloat": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheader": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimports": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
"type": "string",
"examples": ["github.com/org/project"]
}
}
},
"gomoddirectives": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local_replace_directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosimple": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"gosec": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"exclude-generated": {
"description": "Exclude generated files",
"type": "boolean",
"default": false
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitan": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"ignore-tests": {
"description": "Ignore test files.",
"type": "boolean",
"default": false
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govet": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouper": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"iface": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importas": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturn": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lll": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidx": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezero": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspell": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-words": {
"description": "List of words to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttag": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedret": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestif": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnil": {
"type": "object",
"additionalProperties": false,
"properties": {
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturn": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mnd": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlint": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassign": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturns": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltest": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprint": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
}
}
},
"prealloc": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclared": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "Comma-separated list of predeclared identifiers to not report on.",
"type": "string"
},
"q": {
"description": "Include method names and field names (i.e., qualified names) in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinter": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetter": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"revive": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"ignore-generated-header": {
"type": "boolean"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglint": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
}
}
}
},
"stylecheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": ["all"]
},
{
"type": "string"
}
]
},
"default": [
"all",
"-ST1000",
"-ST1003",
"-ST1016",
"-ST1020",
"-ST1021",
"-ST1022"
]
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalign": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelle": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"tenv": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
"type": "boolean",
"default": false
}
}
},
"testifylint": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackage": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelper": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvars": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetesting": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": true
},
"context-todo": {
"type": "boolean",
"default": true
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvert": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparam": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelen": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespace": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheck": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreSigRegexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignorePackageGlobs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignoreInterfaceRegexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wsl": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvar": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"custom": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"enable-all": {
"description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
"type": "boolean",
"default": false
},
"presets": {
"description": "Allow to use different presets of linters",
"type": "array",
"items": {
"enum": [
"bugs",
"comment",
"complexity",
"error",
"format",
"import",
"metalinter",
"module",
"performance",
"sql",
"style",
"test",
"unused"
]
}
},
"fast": {
"description": "Enable run of fast linters.",
"type": "boolean",
"default": false
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "lax"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"default": {
"type": "array",
"items": {
"enum": [
"comments",
"stdErrorHandling",
"commonFalsePositives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
"type": "array",
"items": {
"type": "string"
}
},
"exclude-rules": {
"description": "Exclude configuration per-path, per-linter, per-text and per-source",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
}
}
},
"exclude-use-default": {
"description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
"type": "boolean",
"default": true
},
"exclude-case-sensitive": {
"description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"exclude-generated": {
"description": "Mode of the generated files analysis.",
"enum": ["lax", "strict", "disable"],
"default": "lax"
},
"exclude-dirs": {
"description": "Which directories to exclude: issues from them won't be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": ["generated.*"]
},
"default": [],
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
},
"exclude-dirs-use-default": {
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
"type": "boolean",
"default": true
},
"exclude-files": {
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
"type": "array",
"items": {
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
"type": "string",
"examples": [".*\\.my\\.go$"]
},
"default": [],
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
},
"include": {
"description": "The list of ids of default excludes to include or disable.",
"type": "array",
"items": {
"enum": [
"EXC0001",
"EXC0002",
"EXC0003",
"EXC0004",
"EXC0005",
"EXC0006",
"EXC0007",
"EXC0008",
"EXC0009",
"EXC0010",
"EXC0011",
"EXC0012",
"EXC0013",
"EXC0014",
"EXC0015"
]
},
"default": []
},
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-severity": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"case-sensitive": {
"description": "If set to true, severity-rules regular expressions become case sensitive.",
"type": "boolean",
"default": false
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linters"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default-severity"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.0.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G113",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-strings": {
"description": "Exclude strings matching the given regular expression",
"type": "string"
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": true
},
"context-todo": {
"type": "boolean",
"default": true
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.1.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": true
},
"context-todo": {
"type": "boolean",
"default": true
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.10.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupOption",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr",
"zeroByteRepeat"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"godoclint-rules": {
"enum": [
"pkg-doc",
"single-pkg-doc",
"require-pkg-doc",
"start-with-name",
"require-doc",
"deprecated",
"max-len",
"no-unused-link",
"require-stdlib-doclink"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G116",
"G117",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602",
"G701",
"G702",
"G703",
"G704",
"G705",
"G706"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"epoch-naming",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"forbidden-call-in-wg-go",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"identical-ifelseif-branches",
"identical-ifelseif-conditions",
"identical-switch-branches",
"identical-switch-conditions",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"inefficient-map-lookup",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"package-directory-mismatch",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-if",
"unnecessary-stmt",
"unreachable-code",
"unsecure-url-scheme",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"use-slices-sort",
"use-waitgroup-go",
"useless-break",
"useless-fallthrough",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"modernize-analyzers": {
"enum": [
"any",
"fmtappendf",
"forvar",
"mapsloop",
"minmax",
"newexpr",
"omitzero",
"plusbuild",
"rangeint",
"reflecttypefor",
"slicescontains",
"slicessort",
"stditerators",
"stringscut",
"stringscutprefix",
"stringsseq",
"stringsbuilder",
"testingcontext",
"unsafefuncs",
"waitgroup"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace",
"after-block"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godoclint",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"iotamixing",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"modernize",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
},
"comments-only": {
"description": "Checks only comments, skip strings.",
"type": "boolean",
"default": false
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"empty-line": {
"description": "Checks that there is an empty space between the embedded fields and regular fields.",
"type": "boolean",
"default": false
},
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
},
"force-tonot": {
"description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godoclintSettings": {
"type": "object",
"properties": {
"default": {
"type": "string",
"enum": ["all", "basic", "none"],
"default": "basic",
"description": "Default set of rules to enable."
},
"enable": {
"description": "List of rules to enable in addition to the default set.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"disable": {
"description": "List of rules to disable.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"options": {
"type": "object",
"description": "A map for setting individual rule options.",
"properties": {
"max-len": {
"type": "object",
"properties": {
"length": {
"type": "integer",
"description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
"default": 77
}
}
},
"require-doc": {
"type": "object",
"properties": {
"ignore-exported": {
"type": "boolean",
"description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
"default": false
},
"ignore-unexported": {
"type": "boolean",
"description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
"default": true
}
}
},
"start-with-name": {
"type": "object",
"properties": {
"include-unexported": {
"type": "boolean",
"description": "Include unexported symbols when applying the `start-with-name` rule.",
"default": false
}
}
}
}
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
},
"check-module-path": {
"description": "Check the validity of the module path.",
"type": "boolean",
"default": false
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ineffassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-escaping-errors": {
"description": "Check escaping variables of type error, may cause false positives.",
"type": "boolean",
"default": false
}
}
},
"iotamixingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-individual": {
"description": "Whether to report individual consts rather than just the const block.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"modernizeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {
"description": "List of analyzers to disable.",
"type": "array",
"items": {
"$ref": "#/definitions/modernize-analyzers"
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
},
"concat-loop": {
"description": "Enable/disable optimization of concat loop.",
"type": "boolean",
"default": true
},
"loop-other-ops": {
"description": "Optimization of `concat-loop` even with other operations.",
"type": "boolean",
"default": false
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"enable-default-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unqueryvetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-sql-builders": {
"description": "Enable SQL builder checking.",
"type": "boolean",
"default": true
},
"check-aliased-wildcard": {
"description": "Enable aliased wildcard detection like SELECT t.*.",
"type": "boolean",
"default": true
},
"check-string-concat": {
"description": "Enable string concatenation analysis.",
"type": "boolean",
"default": true
},
"check-format-strings": {
"description": "Enable format string analysis like fmt.Sprintf.",
"type": "boolean",
"default": true
},
"check-string-builder": {
"description": "Enable strings.Builder analysis.",
"type": "boolean",
"default": true
},
"check-subqueries": {
"description": "Enable subquery analysis.",
"type": "boolean",
"default": true
},
"check-n1": {
"type": "boolean",
"default": false
},
"check-sql-injection": {
"type": "boolean",
"default": false
},
"check-tx-leaks": {
"type": "boolean",
"default": false
},
"allowed-patterns": {
"description": "Regex patterns for acceptable SELECT * usage.",
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "Allow is a list of SQL patterns to allow (whitelist).",
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Functions to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"sql-builders": {
"type": "object",
"additionalProperties": false,
"properties": {
"squirrel": {
"type": "boolean",
"default": true
},
"gorm": {
"type": "boolean",
"default": true
},
"sqlx": {
"type": "boolean",
"default": true
},
"ent": {
"type": "boolean",
"default": true
},
"pgx": {
"type": "boolean",
"default": true
},
"bun": {
"type": "boolean",
"default": true
},
"sqlboiler": {
"type": "boolean",
"default": true
},
"jet": {
"type": "boolean",
"default": true
}
}
},
"custom-rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"pattern": {
"type": "string"
},
"patterns": {
"type": "array",
"items": {
"type": "string"
}
},
"when": {
"type": "string"
},
"message": {
"type": "string"
},
"action": {
"type": "string"
}
}
}
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"enable-build-vcs": {
"type": "boolean",
"default": false
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godoclint": {
"$ref": "#/definitions/settings/definitions/godoclintSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ineffassign": {
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
},
"iotamixing": {
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"modernize": {
"$ref": "#/definitions/settings/definitions/modernizeSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unqueryvet": {
"$ref": "#/definitions/settings/definitions/unqueryvetSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.2.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.3.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.4.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-stmt",
"unreachable-code",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"useless-break",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.5.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"ioutilDeprecated",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"godoclint-rules": {
"enum": [
"pkg-doc",
"single-pkg-doc",
"require-pkg-doc",
"start-with-name",
"require-doc",
"deprecated",
"max-len",
"no-unused-link"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"identical-ifelseif-branches",
"identical-ifelseif-conditions",
"identical-switch-branches",
"identical-switch-conditions",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"package-directory-mismatch",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-stmt",
"unreachable-code",
"unsecure-url-scheme",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"use-waitgroup-go",
"useless-break",
"useless-fallthrough",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godoclint",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"iotamixing",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"empty-line": {
"description": "Checks that there is an empty space between the embedded fields and regular fields.",
"type": "boolean",
"default": false
},
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
},
"force-tonot": {
"description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godoclintSettings": {
"type": "object",
"properties": {
"default": {
"type": "string",
"enum": ["all", "basic", "none"],
"default": "basic",
"description": "Default set of rules to enable."
},
"enable": {
"description": "List of rules to enable in addition to the default set.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"disable": {
"description": "List of rules to disable.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"options": {
"type": "object",
"description": "A map for setting individual rule options.",
"properties": {
"max-len": {
"type": "object",
"properties": {
"length": {
"type": "integer",
"description": "Maximum line length for godocs, not including the `// `, or `/*` or `*/` tokens.",
"default": 77
}
}
},
"require-doc": {
"type": "object",
"properties": {
"ignore-exported": {
"type": "boolean",
"description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
"default": false
},
"ignore-unexported": {
"type": "boolean",
"description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
"default": true
}
}
},
"start-with-name": {
"type": "object",
"properties": {
"include-unexported": {
"type": "boolean",
"description": "Include unexported symbols when applying the `start-with-name` rule.",
"default": false
}
}
}
}
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ineffassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-escaping-errors": {
"description": "Check escaping variables of type error, may cause false positives.",
"type": "boolean",
"default": false
}
}
},
"iotamixingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-individual": {
"description": "Whether to report individual consts rather than just the const block.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unqueryvetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-sql-builders": {
"description": "Enable SQL builder checking.",
"type": "boolean",
"default": true
},
"allowed-patterns": {
"description": "Regex patterns for acceptable SELECT * usage.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godoclint": {
"$ref": "#/definitions/settings/definitions/godoclintSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ineffassign": {
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
},
"iotamixing": {
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unqueryvet": {
"$ref": "#/definitions/settings/definitions/unqueryvetSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Fix found issues (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.6.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupOption",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr",
"zeroByteRepeat"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"godoclint-rules": {
"enum": [
"pkg-doc",
"single-pkg-doc",
"require-pkg-doc",
"start-with-name",
"require-doc",
"deprecated",
"max-len",
"no-unused-link"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"identical-ifelseif-branches",
"identical-ifelseif-conditions",
"identical-switch-branches",
"identical-switch-conditions",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"package-directory-mismatch",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-stmt",
"unreachable-code",
"unsecure-url-scheme",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"use-waitgroup-go",
"useless-break",
"useless-fallthrough",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"modernize-analyzers": {
"enum": [
"any",
"bloop",
"fmtappendf",
"forvar",
"mapsloop",
"minmax",
"newexpr",
"omitzero",
"rangeint",
"reflecttypefor",
"slicescontains",
"slicessort",
"stditerators",
"stringscutprefix",
"stringsseq",
"stringsbuilder",
"testingcontext",
"waitgroup"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godoclint",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"iotamixing",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"modernize",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
},
"comments-only": {
"description": "Checks only comments, skip strings.",
"type": "boolean",
"default": false
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"empty-line": {
"description": "Checks that there is an empty space between the embedded fields and regular fields.",
"type": "boolean",
"default": false
},
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
},
"force-tonot": {
"description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godoclintSettings": {
"type": "object",
"properties": {
"default": {
"type": "string",
"enum": ["all", "basic", "none"],
"default": "basic",
"description": "Default set of rules to enable."
},
"enable": {
"description": "List of rules to enable in addition to the default set.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"disable": {
"description": "List of rules to disable.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"options": {
"type": "object",
"description": "A map for setting individual rule options.",
"properties": {
"max-len": {
"type": "object",
"properties": {
"length": {
"type": "integer",
"description": "Maximum line length for godocs, not including the `// `, or `/*` or `*/` tokens.",
"default": 77
}
}
},
"require-doc": {
"type": "object",
"properties": {
"ignore-exported": {
"type": "boolean",
"description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
"default": false
},
"ignore-unexported": {
"type": "boolean",
"description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
"default": true
}
}
},
"start-with-name": {
"type": "object",
"properties": {
"include-unexported": {
"type": "boolean",
"description": "Include unexported symbols when applying the `start-with-name` rule.",
"default": false
}
}
}
}
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ineffassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-escaping-errors": {
"description": "Check escaping variables of type error, may cause false positives.",
"type": "boolean",
"default": false
}
}
},
"iotamixingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-individual": {
"description": "Whether to report individual consts rather than just the const block.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"modernizeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {
"description": "List of analyzers to disable.",
"type": "array",
"items": {
"$ref": "#/definitions/modernize-analyzers"
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
},
"concat-loop": {
"description": "Enable/disable optimization of concat loop.",
"type": "boolean",
"default": true
},
"loop-other-ops": {
"description": "Optimization of `concat-loop` even with other operations.",
"type": "boolean",
"default": false
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unqueryvetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-sql-builders": {
"description": "Enable SQL builder checking.",
"type": "boolean",
"default": true
},
"allowed-patterns": {
"description": "Regex patterns for acceptable SELECT * usage.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godoclint": {
"$ref": "#/definitions/settings/definitions/godoclintSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ineffassign": {
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
},
"iotamixing": {
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"modernize": {
"$ref": "#/definitions/settings/definitions/modernizeSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unqueryvet": {
"$ref": "#/definitions/settings/definitions/unqueryvetSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.7.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupOption",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr",
"zeroByteRepeat"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"godoclint-rules": {
"enum": [
"pkg-doc",
"single-pkg-doc",
"require-pkg-doc",
"start-with-name",
"require-doc",
"deprecated",
"max-len",
"no-unused-link"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"forbidden-call-in-wg-go",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"identical-ifelseif-branches",
"identical-ifelseif-conditions",
"identical-switch-branches",
"identical-switch-conditions",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"inefficient-map-lookup",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"package-directory-mismatch",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-if",
"unnecessary-stmt",
"unreachable-code",
"unsecure-url-scheme",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"use-waitgroup-go",
"useless-break",
"useless-fallthrough",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"modernize-analyzers": {
"enum": [
"any",
"bloop",
"fmtappendf",
"forvar",
"mapsloop",
"minmax",
"newexpr",
"omitzero",
"plusbuild",
"rangeint",
"reflecttypefor",
"slicescontains",
"slicessort",
"stditerators",
"stringscutprefix",
"stringsseq",
"stringsbuilder",
"testingcontext",
"waitgroup"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godoclint",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"iotamixing",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"modernize",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
},
"comments-only": {
"description": "Checks only comments, skip strings.",
"type": "boolean",
"default": false
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"empty-line": {
"description": "Checks that there is an empty space between the embedded fields and regular fields.",
"type": "boolean",
"default": false
},
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
},
"force-tonot": {
"description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godoclintSettings": {
"type": "object",
"properties": {
"default": {
"type": "string",
"enum": ["all", "basic", "none"],
"default": "basic",
"description": "Default set of rules to enable."
},
"enable": {
"description": "List of rules to enable in addition to the default set.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"disable": {
"description": "List of rules to disable.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"options": {
"type": "object",
"description": "A map for setting individual rule options.",
"properties": {
"max-len": {
"type": "object",
"properties": {
"length": {
"type": "integer",
"description": "Maximum line length for godocs, not including the `// `, or `/*` or `*/` tokens.",
"default": 77
}
}
},
"require-doc": {
"type": "object",
"properties": {
"ignore-exported": {
"type": "boolean",
"description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
"default": false
},
"ignore-unexported": {
"type": "boolean",
"description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
"default": true
}
}
},
"start-with-name": {
"type": "object",
"properties": {
"include-unexported": {
"type": "boolean",
"description": "Include unexported symbols when applying the `start-with-name` rule.",
"default": false
}
}
}
}
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ineffassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-escaping-errors": {
"description": "Check escaping variables of type error, may cause false positives.",
"type": "boolean",
"default": false
}
}
},
"iotamixingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-individual": {
"description": "Whether to report individual consts rather than just the const block.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"modernizeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {
"description": "List of analyzers to disable.",
"type": "array",
"items": {
"$ref": "#/definitions/modernize-analyzers"
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
},
"concat-loop": {
"description": "Enable/disable optimization of concat loop.",
"type": "boolean",
"default": true
},
"loop-other-ops": {
"description": "Optimization of `concat-loop` even with other operations.",
"type": "boolean",
"default": false
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"enable-default-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unqueryvetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-sql-builders": {
"description": "Enable SQL builder checking.",
"type": "boolean",
"default": true
},
"allowed-patterns": {
"description": "Regex patterns for acceptable SELECT * usage.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godoclint": {
"$ref": "#/definitions/settings/definitions/godoclintSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ineffassign": {
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
},
"iotamixing": {
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"modernize": {
"$ref": "#/definitions/settings/definitions/modernizeSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unqueryvet": {
"$ref": "#/definitions/settings/definitions/unqueryvetSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.8.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupOption",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr",
"zeroByteRepeat"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"godoclint-rules": {
"enum": [
"pkg-doc",
"single-pkg-doc",
"require-pkg-doc",
"start-with-name",
"require-doc",
"deprecated",
"max-len",
"no-unused-link",
"require-stdlib-doclink"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G116",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"forbidden-call-in-wg-go",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"identical-ifelseif-branches",
"identical-ifelseif-conditions",
"identical-switch-branches",
"identical-switch-conditions",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"inefficient-map-lookup",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"package-directory-mismatch",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-if",
"unnecessary-stmt",
"unreachable-code",
"unsecure-url-scheme",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"use-waitgroup-go",
"useless-break",
"useless-fallthrough",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"modernize-analyzers": {
"enum": [
"any",
"bloop",
"fmtappendf",
"forvar",
"mapsloop",
"minmax",
"newexpr",
"omitzero",
"plusbuild",
"rangeint",
"reflecttypefor",
"slicescontains",
"slicessort",
"stditerators",
"stringscut",
"stringscutprefix",
"stringsseq",
"stringsbuilder",
"testingcontext",
"unsafefuncs",
"waitgroup"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godoclint",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"iotamixing",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"modernize",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
},
"comments-only": {
"description": "Checks only comments, skip strings.",
"type": "boolean",
"default": false
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"empty-line": {
"description": "Checks that there is an empty space between the embedded fields and regular fields.",
"type": "boolean",
"default": false
},
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
},
"force-tonot": {
"description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godoclintSettings": {
"type": "object",
"properties": {
"default": {
"type": "string",
"enum": ["all", "basic", "none"],
"default": "basic",
"description": "Default set of rules to enable."
},
"enable": {
"description": "List of rules to enable in addition to the default set.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"disable": {
"description": "List of rules to disable.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"options": {
"type": "object",
"description": "A map for setting individual rule options.",
"properties": {
"max-len": {
"type": "object",
"properties": {
"length": {
"type": "integer",
"description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
"default": 77
}
}
},
"require-doc": {
"type": "object",
"properties": {
"ignore-exported": {
"type": "boolean",
"description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
"default": false
},
"ignore-unexported": {
"type": "boolean",
"description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
"default": true
}
}
},
"start-with-name": {
"type": "object",
"properties": {
"include-unexported": {
"type": "boolean",
"description": "Include unexported symbols when applying the `start-with-name` rule.",
"default": false
}
}
}
}
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
},
"check-module-path": {
"description": "Check the validity of the module path.",
"type": "boolean",
"default": false
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ineffassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-escaping-errors": {
"description": "Check escaping variables of type error, may cause false positives.",
"type": "boolean",
"default": false
}
}
},
"iotamixingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-individual": {
"description": "Whether to report individual consts rather than just the const block.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"modernizeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {
"description": "List of analyzers to disable.",
"type": "array",
"items": {
"$ref": "#/definitions/modernize-analyzers"
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
},
"concat-loop": {
"description": "Enable/disable optimization of concat loop.",
"type": "boolean",
"default": true
},
"loop-other-ops": {
"description": "Optimization of `concat-loop` even with other operations.",
"type": "boolean",
"default": false
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"enable-default-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unqueryvetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-sql-builders": {
"description": "Enable SQL builder checking.",
"type": "boolean",
"default": true
},
"check-aliased-wildcard": {
"description": "Enable aliased wildcard detection like SELECT t.*.",
"type": "boolean",
"default": true
},
"check-string-concat": {
"description": "Enable string concatenation analysis.",
"type": "boolean",
"default": true
},
"check-format-strings": {
"description": "Enable format string analysis like fmt.Sprintf.",
"type": "boolean",
"default": true
},
"check-string-builder": {
"description": "Enable strings.Builder analysis.",
"type": "boolean",
"default": true
},
"check-subqueries": {
"description": "Enable subquery analysis.",
"type": "boolean",
"default": true
},
"allowed-patterns": {
"description": "Regex patterns for acceptable SELECT * usage.",
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Functions to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"sql-builders": {
"type": "object",
"additionalProperties": false,
"properties": {
"squirrel": {
"type": "boolean",
"default": true
},
"gorm": {
"type": "boolean",
"default": true
},
"sqlx": {
"type": "boolean",
"default": true
},
"ent": {
"type": "boolean",
"default": true
},
"pgx": {
"type": "boolean",
"default": true
},
"bun": {
"type": "boolean",
"default": true
},
"sqlboiler": {
"type": "boolean",
"default": true
},
"jet": {
"type": "boolean",
"default": true
}
}
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godoclint": {
"$ref": "#/definitions/settings/definitions/godoclintSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ineffassign": {
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
},
"iotamixing": {
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"modernize": {
"$ref": "#/definitions/settings/definitions/modernizeSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unqueryvet": {
"$ref": "#/definitions/settings/definitions/unqueryvetSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: jsonschema/golangci.v2.9.jsonschema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/golangci-lint.json",
"definitions": {
"gocritic-checks": {
"enum": [
"appendAssign",
"appendCombine",
"argOrder",
"assignOp",
"badCall",
"badCond",
"badLock",
"badRegexp",
"badSorting",
"badSyncOnceFunc",
"boolExprSimplify",
"builtinShadow",
"builtinShadowDecl",
"captLocal",
"caseOrder",
"codegenComment",
"commentFormatting",
"commentedOutCode",
"commentedOutImport",
"defaultCaseOrder",
"deferInLoop",
"deferUnlambda",
"deprecatedComment",
"docStub",
"dupArg",
"dupBranchBody",
"dupCase",
"dupImport",
"dupOption",
"dupSubExpr",
"dynamicFmtString",
"elseif",
"emptyDecl",
"emptyFallthrough",
"emptyStringTest",
"equalFold",
"evalOrder",
"exitAfterDefer",
"exposedSyncMutex",
"externalErrorReassign",
"filepathJoin",
"flagDeref",
"flagName",
"hexLiteral",
"httpNoBody",
"hugeParam",
"ifElseChain",
"importShadow",
"indexAlloc",
"initClause",
"mapKey",
"methodExprCall",
"nestingReduce",
"newDeref",
"nilValReturn",
"octalLiteral",
"offBy1",
"paramTypeCombine",
"preferDecodeRune",
"preferFilepathJoin",
"preferFprint",
"preferStringWriter",
"preferWriteByte",
"ptrToRefParam",
"rangeAppendAll",
"rangeExprCopy",
"rangeValCopy",
"redundantSprint",
"regexpMust",
"regexpPattern",
"regexpSimplify",
"returnAfterHttpError",
"ruleguard",
"singleCaseSwitch",
"sliceClear",
"sloppyLen",
"sloppyReassign",
"sloppyTypeAssert",
"sortSlice",
"sprintfQuotedString",
"sqlQuery",
"stringConcatSimplify",
"stringXbytes",
"stringsCompare",
"switchTrue",
"syncMapLoadAndDelete",
"timeExprSimplify",
"todoCommentWithoutDetail",
"tooManyResultsChecker",
"truncateCmp",
"typeAssertChain",
"typeDefFirst",
"typeSwitchVar",
"typeUnparen",
"uncheckedInlineErr",
"underef",
"unlabelStmt",
"unlambda",
"unnamedResult",
"unnecessaryBlock",
"unnecessaryDefer",
"unslice",
"valSwap",
"weakCond",
"whyNoLint",
"wrapperFunc",
"yodaStyleExpr",
"zeroByteRepeat"
]
},
"gocritic-tags": {
"enum": [
"diagnostic",
"style",
"performance",
"experimental",
"opinionated",
"security"
]
},
"staticcheck-checks": {
"enum": [
"*",
"all",
"SA*",
"-SA*",
"SA1*",
"-SA1*",
"SA1000",
"-SA1000",
"SA1001",
"-SA1001",
"SA1002",
"-SA1002",
"SA1003",
"-SA1003",
"SA1004",
"-SA1004",
"SA1005",
"-SA1005",
"SA1006",
"-SA1006",
"SA1007",
"-SA1007",
"SA1008",
"-SA1008",
"SA1010",
"-SA1010",
"SA1011",
"-SA1011",
"SA1012",
"-SA1012",
"SA1013",
"-SA1013",
"SA1014",
"-SA1014",
"SA1015",
"-SA1015",
"SA1016",
"-SA1016",
"SA1017",
"-SA1017",
"SA1018",
"-SA1018",
"SA1019",
"-SA1019",
"SA1020",
"-SA1020",
"SA1021",
"-SA1021",
"SA1023",
"-SA1023",
"SA1024",
"-SA1024",
"SA1025",
"-SA1025",
"SA1026",
"-SA1026",
"SA1027",
"-SA1027",
"SA1028",
"-SA1028",
"SA1029",
"-SA1029",
"SA1030",
"-SA1030",
"SA1031",
"-SA1031",
"SA1032",
"-SA1032",
"SA2*",
"-SA2*",
"SA2000",
"-SA2000",
"SA2001",
"-SA2001",
"SA2002",
"-SA2002",
"SA2003",
"-SA2003",
"SA3*",
"-SA3*",
"SA3000",
"-SA3000",
"SA3001",
"-SA3001",
"SA4*",
"-SA4*",
"SA4000",
"-SA4000",
"SA4001",
"-SA4001",
"SA4003",
"-SA4003",
"SA4004",
"-SA4004",
"SA4005",
"-SA4005",
"SA4006",
"-SA4006",
"SA4008",
"-SA4008",
"SA4009",
"-SA4009",
"SA4010",
"-SA4010",
"SA4011",
"-SA4011",
"SA4012",
"-SA4012",
"SA4013",
"-SA4013",
"SA4014",
"-SA4014",
"SA4015",
"-SA4015",
"SA4016",
"-SA4016",
"SA4017",
"-SA4017",
"SA4018",
"-SA4018",
"SA4019",
"-SA4019",
"SA4020",
"-SA4020",
"SA4021",
"-SA4021",
"SA4022",
"-SA4022",
"SA4023",
"-SA4023",
"SA4024",
"-SA4024",
"SA4025",
"-SA4025",
"SA4026",
"-SA4026",
"SA4027",
"-SA4027",
"SA4028",
"-SA4028",
"SA4029",
"-SA4029",
"SA4030",
"-SA4030",
"SA4031",
"-SA4031",
"SA4032",
"-SA4032",
"SA5*",
"-SA5*",
"SA5000",
"-SA5000",
"SA5001",
"-SA5001",
"SA5002",
"-SA5002",
"SA5003",
"-SA5003",
"SA5004",
"-SA5004",
"SA5005",
"-SA5005",
"SA5007",
"-SA5007",
"SA5008",
"-SA5008",
"SA5009",
"-SA5009",
"SA5010",
"-SA5010",
"SA5011",
"-SA5011",
"SA5012",
"-SA5012",
"SA6*",
"-SA6*",
"SA6000",
"-SA6000",
"SA6001",
"-SA6001",
"SA6002",
"-SA6002",
"SA6003",
"-SA6003",
"SA6005",
"-SA6005",
"SA6006",
"-SA6006",
"SA9*",
"-SA9*",
"SA9001",
"-SA9001",
"SA9002",
"-SA9002",
"SA9003",
"-SA9003",
"SA9004",
"-SA9004",
"SA9005",
"-SA9005",
"SA9006",
"-SA9006",
"SA9007",
"-SA9007",
"SA9008",
"-SA9008",
"SA9009",
"-SA9009",
"ST*",
"-ST*",
"ST1*",
"-ST1*",
"ST1000",
"-ST1000",
"ST1001",
"-ST1001",
"ST1003",
"-ST1003",
"ST1005",
"-ST1005",
"ST1006",
"-ST1006",
"ST1008",
"-ST1008",
"ST1011",
"-ST1011",
"ST1012",
"-ST1012",
"ST1013",
"-ST1013",
"ST1015",
"-ST1015",
"ST1016",
"-ST1016",
"ST1017",
"-ST1017",
"ST1018",
"-ST1018",
"ST1019",
"-ST1019",
"ST1020",
"-ST1020",
"ST1021",
"-ST1021",
"ST1022",
"-ST1022",
"ST1023",
"-ST1023",
"S*",
"-S*",
"S1*",
"-S1*",
"S1000",
"-S1000",
"S1001",
"-S1001",
"S1002",
"-S1002",
"S1003",
"-S1003",
"S1004",
"-S1004",
"S1005",
"-S1005",
"S1006",
"-S1006",
"S1007",
"-S1007",
"S1008",
"-S1008",
"S1009",
"-S1009",
"S1010",
"-S1010",
"S1011",
"-S1011",
"S1012",
"-S1012",
"S1016",
"-S1016",
"S1017",
"-S1017",
"S1018",
"-S1018",
"S1019",
"-S1019",
"S1020",
"-S1020",
"S1021",
"-S1021",
"S1023",
"-S1023",
"S1024",
"-S1024",
"S1025",
"-S1025",
"S1028",
"-S1028",
"S1029",
"-S1029",
"S1030",
"-S1030",
"S1031",
"-S1031",
"S1032",
"-S1032",
"S1033",
"-S1033",
"S1034",
"-S1034",
"S1035",
"-S1035",
"S1036",
"-S1036",
"S1037",
"-S1037",
"S1038",
"-S1038",
"S1039",
"-S1039",
"S1040",
"-S1040",
"QF*",
"-QF*",
"QF1*",
"-QF1*",
"QF1001",
"-QF1001",
"QF1002",
"-QF1002",
"QF1003",
"-QF1003",
"QF1004",
"-QF1004",
"QF1005",
"-QF1005",
"QF1006",
"-QF1006",
"QF1007",
"-QF1007",
"QF1008",
"-QF1008",
"QF1009",
"-QF1009",
"QF1010",
"-QF1010",
"QF1011",
"-QF1011",
"QF1012",
"-QF1012"
]
},
"godoclint-rules": {
"enum": [
"pkg-doc",
"single-pkg-doc",
"require-pkg-doc",
"start-with-name",
"require-doc",
"deprecated",
"max-len",
"no-unused-link",
"require-stdlib-doclink"
]
},
"gosec-rules": {
"enum": [
"G101",
"G102",
"G103",
"G104",
"G106",
"G107",
"G108",
"G109",
"G110",
"G111",
"G112",
"G114",
"G115",
"G116",
"G201",
"G202",
"G203",
"G204",
"G301",
"G302",
"G303",
"G304",
"G305",
"G306",
"G307",
"G401",
"G402",
"G403",
"G404",
"G405",
"G406",
"G501",
"G502",
"G503",
"G504",
"G505",
"G506",
"G507",
"G601",
"G602"
]
},
"govet-analyzers": {
"enum": [
"appends",
"asmdecl",
"assign",
"atomic",
"atomicalign",
"bools",
"buildtag",
"cgocall",
"composites",
"copylocks",
"deepequalerrors",
"defers",
"directive",
"errorsas",
"fieldalignment",
"findcall",
"framepointer",
"hostport",
"httpmux",
"httpresponse",
"ifaceassert",
"loopclosure",
"lostcancel",
"nilfunc",
"nilness",
"printf",
"reflectvaluecompare",
"shadow",
"shift",
"sigchanyzer",
"slog",
"sortslice",
"stdmethods",
"stdversion",
"stringintconv",
"structtag",
"testinggoroutine",
"tests",
"timeformat",
"unmarshal",
"unreachable",
"unsafeptr",
"unusedresult",
"unusedwrite",
"waitgroup"
]
},
"revive-rules": {
"enum": [
"add-constant",
"argument-limit",
"atomic",
"banned-characters",
"bare-return",
"blank-imports",
"bool-literal-in-expr",
"call-to-gc",
"cognitive-complexity",
"comment-spacings",
"comments-density",
"confusing-naming",
"confusing-results",
"constant-logical-expr",
"context-as-argument",
"context-keys-type",
"cyclomatic",
"datarace",
"deep-exit",
"defer",
"dot-imports",
"duplicated-imports",
"early-return",
"empty-block",
"empty-lines",
"enforce-map-style",
"enforce-repeated-arg-type-style",
"enforce-slice-style",
"enforce-switch-style",
"epoch-naming",
"error-naming",
"error-return",
"error-strings",
"errorf",
"exported",
"file-header",
"file-length-limit",
"filename-format",
"flag-parameter",
"forbidden-call-in-wg-go",
"function-length",
"function-result-limit",
"get-return",
"identical-branches",
"identical-ifelseif-branches",
"identical-ifelseif-conditions",
"identical-switch-branches",
"identical-switch-conditions",
"if-return",
"import-alias-naming",
"import-shadowing",
"imports-blocklist",
"increment-decrement",
"indent-error-flow",
"inefficient-map-lookup",
"line-length-limit",
"max-control-nesting",
"max-public-structs",
"modifies-parameter",
"modifies-value-receiver",
"nested-structs",
"optimize-operands-order",
"package-comments",
"package-directory-mismatch",
"range-val-address",
"range-val-in-closure",
"range",
"receiver-naming",
"redefines-builtin-id",
"redundant-build-tag",
"redundant-import-alias",
"redundant-test-main-exit",
"string-format",
"string-of-int",
"struct-tag",
"superfluous-else",
"time-date",
"time-equal",
"time-naming",
"unchecked-type-assertion",
"unconditional-recursion",
"unexported-naming",
"unexported-return",
"unhandled-error",
"unnecessary-format",
"unnecessary-if",
"unnecessary-stmt",
"unreachable-code",
"unsecure-url-scheme",
"unused-parameter",
"unused-receiver",
"use-any",
"use-errors-new",
"use-fmt-print",
"use-slices-sort",
"use-waitgroup-go",
"useless-break",
"useless-fallthrough",
"var-declaration",
"var-naming",
"waitgroup-by-value"
]
},
"iface-analyzers": {
"enum": [
"identical",
"unused",
"opaque",
"unexported"
]
},
"tagliatelle-cases": {
"enum": [
"",
"camel",
"pascal",
"kebab",
"snake",
"goCamel",
"goPascal",
"goKebab",
"goSnake",
"upper",
"upperSnake",
"lower",
"header"
]
},
"modernize-analyzers": {
"enum": [
"any",
"fmtappendf",
"forvar",
"mapsloop",
"minmax",
"newexpr",
"omitzero",
"plusbuild",
"rangeint",
"reflecttypefor",
"slicescontains",
"slicessort",
"stditerators",
"stringscut",
"stringscutprefix",
"stringsseq",
"stringsbuilder",
"testingcontext",
"unsafefuncs",
"waitgroup"
]
},
"wsl-checks": {
"enum": [
"assign",
"branch",
"decl",
"defer",
"expr",
"for",
"go",
"if",
"inc-dec",
"label",
"range",
"return",
"select",
"send",
"switch",
"type-switch",
"append",
"assign-exclusive",
"assign-expr",
"err",
"leading-whitespace",
"trailing-whitespace",
"after-block"
]
},
"relative-path-modes": {
"enum": [
"gomod",
"gitroot",
"cfg",
"wd"
]
},
"simple-format": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
}
}
},
"formats-path" : {
"anyOf": [
{
"enum": [
"stdout",
"stderr"
]
},
{
"type": "string"
}
]
},
"linter-names": {
"$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
"description": "Usable linter names.",
"anyOf": [
{
"enum": [
"arangolint",
"asasalint",
"asciicheck",
"bidichk",
"bodyclose",
"canonicalheader",
"containedctx",
"contextcheck",
"copyloopvar",
"cyclop",
"decorder",
"depguard",
"dogsled",
"dupl",
"dupword",
"durationcheck",
"embeddedstructfieldcheck",
"errcheck",
"errchkjson",
"errname",
"errorlint",
"exhaustive",
"exhaustruct",
"exptostd",
"fatcontext",
"forbidigo",
"forcetypeassert",
"funcorder",
"funlen",
"ginkgolinter",
"gocheckcompilerdirectives",
"gochecknoglobals",
"gochecknoinits",
"gochecksumtype",
"gocognit",
"goconst",
"gocritic",
"gocyclo",
"godoclint",
"godot",
"godox",
"err113",
"goheader",
"gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
"gosimple",
"gosmopolitan",
"govet",
"grouper",
"iface",
"importas",
"inamedparam",
"ineffassign",
"interfacebloat",
"intrange",
"iotamixing",
"ireturn",
"lll",
"loggercheck",
"maintidx",
"makezero",
"mirror",
"misspell",
"mnd",
"modernize",
"musttag",
"nakedret",
"nestif",
"nilerr",
"nilnesserr",
"nilnil",
"nlreturn",
"noctx",
"noinlineerr",
"nolintlint",
"nonamedreturns",
"nosprintfhostport",
"paralleltest",
"perfsprint",
"prealloc",
"predeclared",
"promlinter",
"protogetter",
"reassign",
"recvcheck",
"revive",
"rowserrcheck",
"sloglint",
"sqlclosecheck",
"staticcheck",
"stylecheck",
"tagalign",
"tagliatelle",
"testableexamples",
"testifylint",
"testpackage",
"thelper",
"tparallel",
"unconvert",
"unparam",
"unused",
"usestdlibvars",
"usetesting",
"varnamelen",
"wastedassign",
"whitespace",
"wrapcheck",
"wsl",
"wsl_v5",
"zerologlint"
]
},
{
"type": "string"
}
]
},
"formatter-names": {
"description": "Usable formatter names.",
"enum": [
"gci",
"gofmt",
"gofumpt",
"goimports",
"golines",
"swaggo"
]
},
"settings": {
"definitions": {
"dupwordSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["the", "and", "a"]
}
},
"ignore": {
"description": "Keywords used to ignore detection.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["0C0C"]
}
},
"comments-only": {
"description": "Checks only comments, skip strings.",
"type": "boolean",
"default": false
}
}
},
"asasalintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"description": "To specify a set of function names to exclude.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["\\.Wrapf"]
}
},
"use-builtin-exclusions": {
"description": "To enable/disable the asasalint builtin exclusions of function names.",
"type": "boolean",
"default": true
}
}
},
"bidichkSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"left-to-right-embedding": {
"description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
"type": "boolean",
"default": false
},
"right-to-left-embedding": {
"description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
"type": "boolean",
"default": false
},
"pop-directional-formatting": {
"description": "Disallow: POP-DIRECTIONAL-FORMATTING",
"type": "boolean",
"default": false
},
"left-to-right-override": {
"description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
"type": "boolean",
"default": false
},
"right-to-left-override": {
"description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
"type": "boolean",
"default": false
},
"left-to-right-isolate": {
"description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
"type": "boolean",
"default": false
},
"right-to-left-isolate": {
"description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
"type": "boolean",
"default": false
},
"first-strong-isolate": {
"description": "Disallow: FIRST-STRONG-ISOLATE",
"type": "boolean",
"default": false
},
"pop-directional-isolate": {
"description": "Disallow: POP-DIRECTIONAL-ISOLATE",
"type": "boolean",
"default": false
}
}
},
"cyclopSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-complexity": {
"description": "Max complexity the function can have",
"type": "integer",
"default": 10,
"minimum": 0
},
"package-average": {
"description": "Max average complexity in package",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"decorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"dec-order": {
"type": "array",
"default": [["type", "const", "var", "func"]],
"items": {
"enum": ["type", "const", "var", "func"]
}
},
"ignore-underscore-vars": {
"description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
"default": true,
"type": "boolean"
},
"disable-dec-order-check": {
"description": "Order of declarations is not checked",
"default": true,
"type": "boolean"
},
"disable-init-func-first-check": {
"description": "Allow init func to be anywhere in file",
"default": true,
"type": "boolean"
},
"disable-dec-num-check": {
"description": "Multiple global type, const and var declarations are allowed",
"default": true,
"type": "boolean"
},
"disable-type-dec-num-check": {
"description": "Type declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-const-dec-num-check": {
"description": "Const declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
},
"disable-var-dec-num-check": {
"description": "Var declarations will be ignored for dec num check",
"default": true,
"type": "boolean"
}
}
},
"depguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"rules": {
"description": "Rules to apply.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^.]+$": {
"description": "Name of a rule.",
"type": "object",
"additionalProperties": false,
"properties": {
"list-mode": {
"description": "Used to determine the package matching priority.",
"enum": ["original", "strict", "lax"],
"default": "original"
},
"files": {
"description": "List of file globs that will match this list of settings to compare against.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "List of allowed packages.",
"additionalProperties": false,
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Packages that are not allowed where the value is a suggestion.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"desc": {
"description": "Description",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
}
}
}
}
}
}
}
}
}
},
"dogsledSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-blank-identifiers": {
"description": "Check assignments with too many blank identifiers.",
"type": "integer",
"default": 2,
"minimum": 0
}
}
},
"duplSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"threshold": {
"description": "Tokens count to trigger issue.",
"type": "integer",
"default": 150,
"minimum": 0
}
}
},
"embeddedstructfieldcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"empty-line": {
"description": "Checks that there is an empty space between the embedded fields and regular fields.",
"type": "boolean",
"default": false
},
"forbid-mutex": {
"description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
"type": "boolean",
"default": false
}
}
},
"errcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-type-assertions": {
"description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
"type": "boolean",
"default": false
},
"check-blank": {
"description": "Report about assignment of errors to blank identifier",
"type": "boolean",
"default": false
},
"exclude-functions": {
"description": "List of functions to exclude from checking, where each entry is a single function to exclude",
"type": "array",
"examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
"items": {
"type": "string"
}
},
"disable-default-exclusions": {
"description": "To disable the errcheck built-in exclude list",
"type": "boolean",
"default": false
},
"verbose": {
"description": "Display function signature instead of selector",
"type": "boolean",
"default": false
}
}
},
"errchkjsonSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-error-free-encoding": {
"type": "boolean",
"default": false
},
"report-no-exported": {
"description": "Issue on struct that doesn't have exported fields.",
"type": "boolean",
"default": false
}
}
},
"errorlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"errorf": {
"description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
"type": "boolean",
"default": true
},
"errorf-multi": {
"description": "Permit more than 1 %w verb, valid per Go 1.20",
"type": "boolean",
"default": true
},
"asserts": {
"description": "Check for plain type assertions and type switches.",
"type": "boolean",
"default": true
},
"comparison": {
"description": "Check for plain error comparisons",
"type": "boolean",
"default": true
},
"allowed-errors": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
},
"allowed-errors-wildcard": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"err": {
"type": "string"
},
"fun": {
"type": "string"
}
}
}
}
}
},
"exhaustiveSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check": {
"description": "Program elements to check for exhaustiveness.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["switch", "map"]
}
},
"explicit-exhaustive-switch": {
"description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"explicit-exhaustive-map": {
"description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
"type": "boolean",
"default": false
},
"default-case-required": {
"description": "Switch statement requires default case even if exhaustive.",
"type": "boolean",
"default": false
},
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
"type": "boolean",
"default": false
},
"ignore-enum-members": {
"description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
"type": "string"
},
"ignore-enum-types": {
"description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
"type": "string"
},
"package-scope-only": {
"description": "Consider enums only in package scopes, not in inner scopes.",
"type": "boolean",
"default": false
}
}
},
"exhaustructSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"include": {
"description": "List of regular expressions to match struct packages and names.",
"type": "array",
"examples": [".*\\.Test"],
"items": {
"type": "string"
}
},
"exclude": {
"description": "List of regular expressions to exclude struct packages and names from check.",
"type": "array",
"examples": ["cobra\\.Command$"],
"items": {
"type": "string"
}
},
"allow-empty": {
"description": "Allows empty structures, effectively excluding them from the check.",
"type": "boolean",
"default": false
},
"allow-empty-rx": {
"description": "List of regular expressions to match type names that should be allowed to be empty.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-empty-returns": {
"description": "Allows empty structures in return statements.",
"type": "boolean",
"default": false
},
"allow-empty-declarations": {
"description": "Allows empty structures in variable declarations.",
"type": "boolean",
"default": false
}
}
},
"fatcontextSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-struct-pointers": {
"description": "Check for potential fat contexts in struct pointers.",
"type": "boolean",
"default": false
}
}
},
"forbidigoSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude-godoc-examples": {
"description": "Exclude code in godoc examples.",
"type": "boolean",
"default": true
},
"analyze-types": {
"description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
"type": "boolean",
"default": true
},
"forbid": {
"description": "List of identifiers to forbid (written using `regexp`)",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Pattern",
"type": "string"
},
"pkg": {
"description": "Package",
"type": "string"
},
"msg": {
"description": "Message",
"type": "string"
}
}
}
}
}
},
"funcorderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"constructor": {
"description": "Checks that constructors are placed after the structure declaration.",
"type": "boolean",
"default": true
},
"struct-method": {
"description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
"type": "boolean",
"default": true
},
"alphabetical": {
"description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
"type": "boolean",
"default": false
}
}
},
"funlenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"lines": {
"description": "Limit lines number per function.",
"type": "integer",
"default": 60
},
"statements": {
"description": "Limit statements number per function.",
"type": "integer",
"default": 40
},
"ignore-comments": {
"description": "Ignore comments when counting lines.",
"type": "boolean",
"default": true
}
}
},
"gciSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"sections": {
"description": "Section configuration to compare against.",
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"standard",
"default",
"blank",
"dot",
"alias",
"localmodule"
]
},
{
"type": "string"
}
]
},
"default": ["standard", "default"]
},
"no-inline-comments": {
"description": "Checks that no inline Comments are present.",
"type": "boolean",
"default": false
},
"no-prefix-comments": {
"description": "Checks that no prefix Comments(comment lines above an import) are present.",
"type": "boolean",
"default": false
},
"custom-order": {
"description": "Enable custom order of sections.",
"type": "boolean",
"default": false
},
"no-lex-order": {
"description": "Drops lexical ordering for custom sections.",
"type": "boolean",
"default": false
}
}
},
"ginkgolinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"suppress-len-assertion": {
"description": "Suppress the wrong length assertion warning.",
"type": "boolean",
"default": false
},
"suppress-nil-assertion": {
"description": "Suppress the wrong nil assertion warning.",
"type": "boolean",
"default": false
},
"suppress-err-assertion": {
"description": "Suppress the wrong error assertion warning.",
"type": "boolean",
"default": false
},
"suppress-compare-assertion": {
"description": "Suppress the wrong comparison assertion warning.",
"type": "boolean",
"default": false
},
"suppress-async-assertion": {
"description": "Suppress the function all in async assertion warning.",
"type": "boolean",
"default": false
},
"suppress-type-compare-assertion": {
"description": "Suppress warning for comparing values from different types, like int32 and uint32.",
"type": "boolean",
"default": false
},
"forbid-focus-container": {
"description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
"type": "boolean",
"default": false
},
"allow-havelen-zero": {
"description": "Don't trigger warnings for HaveLen(0).",
"type": "boolean",
"default": false
},
"force-expect-to": {
"description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
"type": "boolean",
"default": false
},
"validate-async-intervals": {
"description": "Best effort validation of async intervals (timeout and polling).",
"type": "boolean",
"default": false
},
"forbid-spec-pollution": {
"description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
"type": "boolean",
"default": false
},
"force-succeed": {
"description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
"type": "boolean",
"default": false
},
"force-assertion-description": {
"description": "Force adding assertion descriptions to gomega matchers.",
"type": "boolean",
"default": false
},
"force-tonot": {
"description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
"type": "boolean",
"default": false
}
}
},
"gochecksumtypeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"default-signifies-exhaustive": {
"description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
"type": "boolean",
"default": true
},
"include-shared-interfaces": {
"description": "Include shared interfaces in the exhaustiviness check.",
"type": "boolean",
"default": false
}
}
},
"gocognitSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimal code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"goconstSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"match-constant": {
"description": "Look for existing constants matching the values",
"type": "boolean",
"default": true
},
"min-len": {
"description": "Minimum length of string constant.",
"type": "integer",
"default": 3
},
"min-occurrences": {
"description": "Minimum occurrences count to trigger.",
"type": "integer",
"default": 3
},
"ignore-calls": {
"description": "Ignore when constant is not used as function argument",
"type": "boolean",
"default": true
},
"ignore-string-values": {
"description": "Exclude strings matching the given regular expression",
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"description": "Search also for duplicated numbers.",
"type": "boolean",
"default": false
},
"min": {
"description": "Minimum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"max": {
"description": "Maximum value, only works with `numbers`",
"type": "integer",
"default": 3
},
"find-duplicates": {
"description": "Detects constants with identical values",
"type": "boolean",
"default": false
},
"eval-const-expressions": {
"description": "Evaluates of constant expressions like Prefix + \"suffix\"",
"type": "boolean",
"default": false
}
}
},
"gocriticSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled-checks": {
"description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
}
},
"disabled-checks": {
"description": "Which checks should be disabled.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-checks"
},
"default": []
},
"enabled-tags": {
"description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"disabled-tags": {
"description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
"type": "array",
"items": {
"$ref": "#/definitions/gocritic-tags"
}
},
"settings": {
"description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
"type": "object",
"additionalProperties": false,
"properties": {
"captLocal": {
"type": "object",
"additionalProperties": false,
"properties": {
"paramsOnly" : {
"type": "boolean",
"default": true
}
}
},
"commentedOutCode": {
"type": "object",
"additionalProperties": false,
"properties": {
"minLength" : {
"type": "number",
"default": 15
}
}
},
"elseif": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipBalanced" : {
"type": "boolean",
"default": true
}
}
},
"hugeParam": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 80
}
}
},
"ifElseChain": {
"type": "object",
"additionalProperties": false,
"properties": {
"minThreshold" : {
"type": "number",
"default": 2
}
}
},
"nestingReduce": {
"type": "object",
"additionalProperties": false,
"properties": {
"bodyWidth" : {
"type": "number",
"default": 5
}
}
},
"rangeExprCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 512
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"rangeValCopy": {
"type": "object",
"additionalProperties": false,
"properties": {
"sizeThreshold" : {
"type": "number",
"default": 128
},
"skipTestFuncs" : {
"type": "boolean",
"default": true
}
}
},
"ruleguard": {
"type": "object",
"additionalProperties": false,
"properties": {
"debug" : {
"type": "string"
},
"enable" : {
"type": "string"
},
"disable" : {
"type": "string"
},
"failOn" : {
"type": "string"
},
"rules" : {
"type": "string"
}
}
},
"tooManyResultsChecker": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxResults" : {
"type": "number",
"default": 5
}
}
},
"truncateCmp": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipArchDependent" : {
"type": "boolean",
"default": true
}
}
},
"underef": {
"type": "object",
"additionalProperties": false,
"properties": {
"skipRecvDeref" : {
"type": "boolean",
"default": true
}
}
},
"unnamedResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"checkExported" : {
"type": "boolean",
"default": false
}
}
}
}
},
"disable-all": {
"type": "boolean",
"default": false
},
"enable-all": {
"type": "boolean",
"default": false
}
}
},
"gocycloSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum code complexity to report (we recommend 10-20).",
"type": "integer",
"default": 30
}
}
},
"godoclintSettings": {
"type": "object",
"properties": {
"default": {
"type": "string",
"enum": ["all", "basic", "none"],
"default": "basic",
"description": "Default set of rules to enable."
},
"enable": {
"description": "List of rules to enable in addition to the default set.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"disable": {
"description": "List of rules to disable.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/godoclint-rules"
}
},
"options": {
"type": "object",
"description": "A map for setting individual rule options.",
"properties": {
"max-len": {
"type": "object",
"properties": {
"length": {
"type": "integer",
"description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
"default": 77
}
}
},
"require-doc": {
"type": "object",
"properties": {
"ignore-exported": {
"type": "boolean",
"description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
"default": false
},
"ignore-unexported": {
"type": "boolean",
"description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
"default": true
}
}
},
"start-with-name": {
"type": "object",
"properties": {
"include-unexported": {
"type": "boolean",
"description": "Include unexported symbols when applying the `start-with-name` rule.",
"default": false
}
}
}
}
}
}
},
"godotSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope": {
"description": "Comments to be checked.",
"enum": ["declarations", "toplevel", "all", "noinline"],
"default": "declarations"
},
"exclude": {
"description": "List of regexps for excluding particular comment lines from check.",
"type": "array",
"items": {
"type": "string"
}
},
"period": {
"description": "Check that each sentence ends with a period.",
"type": "boolean",
"default": true
},
"capital": {
"description": "Check that each sentence starts with a capital letter.",
"type": "boolean",
"default": false
},
"check-all": {
"description": "DEPRECATED: Check all top-level comments, not only declarations.",
"type": "boolean",
"default": false
}
}
},
"godoxSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"keywords": {
"description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
"type": "array",
"items": {
"type": "string"
},
"default": ["TODO", "BUG", "FIXME"]
}
}
},
"gofmtSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"simplify": {
"description": "Simplify code.",
"type": "boolean",
"default": true
},
"rewrite-rules": {
"description": "Apply the rewrite rules to the source before reformatting.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"type": "string"
},
"replacement": {
"type": "string"
}
}
}
}
}
},
"golinesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-len": {
"type": "integer",
"default": 100
},
"tab-len": {
"type": "integer",
"default": 4
},
"shorten-comments": {
"type": "boolean",
"default": false
},
"reformat-tags": {
"type": "boolean",
"default": true
},
"chain-split-dots": {
"type": "boolean",
"default": true
}
}
},
"interfacebloatSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max": {
"description": "The maximum number of methods allowed for an interface.",
"type": "integer"
}
}
},
"gofumptSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-rules": {
"description": "Choose whether or not to use the extra rules that are disabled by default.",
"type": "boolean",
"default": false
},
"module-path": {
"description": " Module path which contains the source code being formatted.",
"type": "string"
}
}
},
"goheaderSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"values": {
"type": "object",
"additionalProperties": false,
"properties": {
"const": {
"description": "Constants to use in the template.",
"type": "object",
"patternProperties": {
"^.+$": {
"description": "Value for the constant.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"YEAR": "2030",
"COMPANY": "MY FUTURISTIC COMPANY"
}
]
},
"regexp": {
"description": "Regular expressions to use in your template.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"examples": [
{
"AUTHOR": ".*@mycompany\\.com"
}
]
}
}
},
"template": {
"description": "Template to put on top of every file.",
"type": "string",
"examples": [
"{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
]
},
"template-path": {
"description": "Path to the file containing the template source.",
"type": "string",
"examples": ["my_header_template.txt"]
}
},
"oneOf": [
{ "required": ["template"] },
{ "required": ["template-path"] }
]
},
"goimportsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"local-prefixes": {
"description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"gomoddirectivesSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"replace-local": {
"description": "Allow local `replace` directives.",
"type": "boolean",
"default": true
},
"replace-allow-list": {
"description": "List of allowed `replace` directives.",
"type": "array",
"items": {
"type": "string"
}
},
"retract-allow-no-explanation": {
"description": "Allow to not explain why the version has been retracted in the `retract` directives.",
"type": "boolean",
"default": false
},
"exclude-forbidden": {
"description": "Forbid the use of the `exclude` directives.",
"type": "boolean",
"default": false
},
"ignore-forbidden": {
"description": "Forbid the use of the `ignore` directives. (>= go1.25)",
"type": "boolean",
"default": false
},
"toolchain-forbidden": {
"description": "Forbid the use of the `toolchain` directive.",
"type": "boolean",
"default": false
},
"toolchain-pattern": {
"description": "Defines a pattern to validate `toolchain` directive.",
"type": "string"
},
"tool-forbidden": {
"description": "Forbid the use of the `tool` directives.",
"type": "boolean",
"default": false
},
"go-debug-forbidden": {
"description": "Forbid the use of the `godebug` directive.",
"type": "boolean",
"default": false
},
"go-version-pattern": {
"description": "Defines a pattern to validate `go` minimum version directive.",
"type": "string",
"default": ""
},
"check-module-path": {
"description": "Check the validity of the module path.",
"type": "boolean",
"default": false
}
}
},
"gomodguardSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allowed": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of allowed modules.",
"type": "array",
"items": {
"type": "string",
"examples": ["gopkg.in/yaml.v2"]
}
},
"domains": {
"description": "List of allowed module domains.",
"type": "array",
"items": {
"type": "string",
"examples": ["golang.org"]
}
}
}
},
"blocked": {
"type": "object",
"additionalProperties": false,
"properties": {
"modules": {
"description": "List of blocked modules.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"recommendations": {
"description": "Recommended modules that should be used instead.",
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"description": "Reason why the recommended module should be used.",
"type": "string"
}
}
}
},
"additionalProperties": false
}
},
"versions": {
"description": "List of blocked module version constraints.",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"description": "Version constraint.",
"type": "string"
},
"reason": {
"description": "Reason why the version constraint exists.",
"type": "string"
}
},
"required": ["reason"]
}
}
}
},
"local-replace-directives": {
"description": "Raise lint issues if loading local path with replace directive",
"type": "boolean",
"default": true
}
}
}
}
},
"gosecSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"type": "array",
"description": "To select a subset of rules to run",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"excludes": {
"type": "array",
"description": "To specify a set of rules to explicitly exclude",
"examples": [["G401"]],
"items": {
"$ref": "#/definitions/gosec-rules"
}
},
"severity": {
"description": "Filter out the issues with a lower severity than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"confidence": {
"description": "Filter out the issues with a lower confidence than the given value",
"type": "string",
"enum": ["low", "medium", "high"],
"default": "low"
},
"config": {
"description": "To specify the configuration of rules",
"type": "object"
},
"concurrency": {
"description": "Concurrency value",
"type": "integer"
}
}
},
"gosmopolitanSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-time-local": {
"description": "Allow and ignore `time.Local` usages.",
"type": "boolean",
"default": false
},
"escape-hatches": {
"description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
"type": "array",
"items": {
"type": "string"
}
},
"watch-for-scripts": {
"description": "List of Unicode scripts to watch for any usage in string literals.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"govetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"settings": {
"description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
"type": "object",
"propertyNames": {
"$ref": "#/definitions/govet-analyzers"
},
"patternProperties": {
"^.*$": {
"description": "Run `go tool vet help ` to see all settings.",
"type": "object"
}
}
},
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"disable": {
"description": "Disable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/govet-analyzers"
}
},
"enable-all": {
"description": "Enable all analyzers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all analyzers.",
"type": "boolean",
"default": false
}
}
},
"grouperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"const-require-single-const": {
"type": "boolean",
"default": false
},
"const-require-grouping": {
"type": "boolean",
"default": false
},
"import-require-single-import": {
"type": "boolean",
"default": false
},
"import-require-grouping": {
"type": "boolean",
"default": false
},
"type-require-single-type": {
"type": "boolean",
"default": false
},
"type-require-grouping": {
"type": "boolean",
"default": false
},
"var-require-single-var": {
"type": "boolean",
"default": false
},
"var-require-grouping": {
"type": "boolean",
"default": false
}
}
},
"ifaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "Enable analyzers by name.",
"type": "array",
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"unused": {
"type": "object",
"additionalProperties": false,
"properties": {
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"importasSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"no-unaliased": {
"description": "Do not allow unaliased imports of aliased packages.",
"type": "boolean",
"default": false
},
"no-extra-aliases": {
"description": "Do not allow non-required aliases.",
"type": "boolean",
"default": false
},
"alias": {
"description": "List of aliases",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"pkg": {
"description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
"type": "string"
},
"alias": {
"description": "Package alias e.g. autoscalingv1alpha1",
"type": "string"
}
},
"required": ["pkg", "alias"]
}
}
}
},
"inamedparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-single-param": {
"description": "Skips check for interface methods with only a single parameter.",
"type": "boolean",
"default": false
}
}
},
"ineffassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-escaping-errors": {
"description": "Check escaping variables of type error, may cause false positives.",
"type": "boolean",
"default": false
}
}
},
"iotamixingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-individual": {
"description": "Whether to report individual consts rather than just the const block.",
"type": "boolean",
"default": false
}
}
},
"ireturnSettings": {
"type": "object",
"additionalProperties": false,
"description": "Use either `reject` or `allow` properties for interfaces matching.",
"properties": {
"allow": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
},
"reject": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"enum": ["anon", "error", "empty", "stdlib"]
}
]
}
}
},
"anyOf": [
{
"not": {
"properties": {
"allow": {
"const": "reject"
}
}
},
"required": ["allow"]
},
{
"required": ["reject"]
}
]
},
"lllSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"tab-width": {
"description": "Width of \"\\t\" in spaces.",
"type": "integer",
"minimum": 0,
"default": 1
},
"line-length": {
"description": "Maximum allowed line length, lines longer will be reported.",
"type": "integer",
"minimum": 1,
"default": 120
}
}
},
"maintidxSettings": {
"description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
"type": "object",
"additionalProperties": false,
"properties": {
"under": {
"description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
"type": "number",
"default": 20
}
}
},
"makezeroSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"always": {
"description": "Allow only slices initialized with a length of zero.",
"type": "boolean",
"default": false
}
}
},
"loggercheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kitlog": {
"description": "Allow check for the github.com/go-kit/log library.",
"type": "boolean",
"default": true
},
"klog": {
"description": "Allow check for the k8s.io/klog/v2 library.",
"type": "boolean",
"default": true
},
"logr": {
"description": "Allow check for the github.com/go-logr/logr library.",
"type": "boolean",
"default": true
},
"slog": {
"description": "Allow check for the log/slog library.",
"type": "boolean",
"default": true
},
"zap": {
"description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
"type": "boolean",
"default": true
},
"require-string-key": {
"description": "Require all logging keys to be inlined constant strings.",
"type": "boolean",
"default": false
},
"no-printf-like": {
"description": "Require printf-like format specifier (%s, %d for example) not present.",
"type": "boolean",
"default": false
},
"rules": {
"description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"misspellSettings": {
"description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"enum": ["US", "UK"]
},
"ignore-rules": {
"description": "List of rules to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"description": "Mode of the analysis.",
"enum": ["restricted", "", "default"],
"default": ""
},
"extra-words": {
"description": "Extra word corrections.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"correction": {
"type": "string"
},
"typo": {
"type": "string"
}
}
}
}
}
},
"musttagSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"functions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"arg-pos": {
"type": "integer"
}
}
}
}
}
},
"nakedretSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-func-lines": {
"description": "Report if a function has more lines of code than this value and it has naked returns.",
"type": "integer",
"minimum": 0,
"default": 30
}
}
},
"nestifSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"min-complexity": {
"description": "Minimum complexity of \"if\" statements to report.",
"type": "integer",
"default": 5
}
}
},
"nilnilSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"only-two": {
"type": "boolean",
"description": "To check functions with only two return values.",
"default": true
},
"detect-opposite": {
"type": "boolean",
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
"default": false
},
"checked-types": {
"type": "array",
"description": "List of return types to check.",
"items": {
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
},
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
}
}
},
"nlreturnSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"block-size": {
"description": "set block size that is still ok",
"type": "number",
"default": 0,
"minimum": 0
}
}
},
"mndSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignored-files": {
"description": "List of file patterns to exclude from analysis.",
"examples": [["magic1_.*.go"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Comma-separated list of function patterns to exclude from the analysis.",
"examples": [["math.*", "http.StatusText", "make"]],
"type": "array",
"items": {
"type": "string"
}
},
"ignored-numbers": {
"description": "List of numbers to exclude from analysis.",
"examples": [["1000", "1234_567_890", "3.14159264"]],
"type": "array",
"items": {
"type": "string"
}
},
"checks": {
"description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
"type": "array",
"items": {
"enum": [
"argument",
"case",
"condition",
"operation",
"return",
"assign"
]
}
}
}
},
"modernizeSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {
"description": "List of analyzers to disable.",
"type": "array",
"items": {
"$ref": "#/definitions/modernize-analyzers"
}
}
}
},
"nolintlintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-unused": {
"description": "Enable to ensure that nolint directives are all used.",
"type": "boolean",
"default": true
},
"allow-no-explanation": {
"description": "Exclude these linters from requiring an explanation.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
},
"default": []
},
"require-explanation": {
"description": "Enable to require an explanation of nonzero length after each nolint directive.",
"type": "boolean",
"default": false
},
"require-specific": {
"description": "Enable to require nolint directives to mention the specific linter being suppressed.",
"type": "boolean",
"default": false
}
}
},
"reassignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"patterns": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"recvcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable-builtin": {
"description": "Disables the built-in method exclusions.",
"type": "boolean",
"default": true
},
"exclusions": {
"description": "User-defined method exclusions.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"nonamedreturnsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"report-error-in-defer": {
"description": "Report named error if it is assigned inside defer.",
"type": "boolean",
"default": false
}
}
},
"paralleltestSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-missing": {
"description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
"type": "boolean",
"default": false
},
"ignore-missing-subtests": {
"description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
"type": "boolean",
"default": false
}
}
},
"perfsprintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"integer-format": {
"description": "Enable/disable optimization of integer formatting.",
"type": "boolean",
"default": true
},
"int-conversion": {
"description": "Optimizes even if it requires an int or uint type cast.",
"type": "boolean",
"default": true
},
"error-format": {
"description": "Enable/disable optimization of error formatting.",
"type": "boolean",
"default": true
},
"err-error": {
"description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
"type": "boolean",
"default": false
},
"errorf": {
"description": "Optimizes `fmt.Errorf`.",
"type": "boolean",
"default": true
},
"string-format": {
"description": "Enable/disable optimization of string formatting.",
"type": "boolean",
"default": true
},
"sprintf1": {
"description": "Optimizes `fmt.Sprintf` with only one argument.",
"type": "boolean",
"default": true
},
"strconcat": {
"description": "Optimizes into strings concatenation.",
"type": "boolean",
"default": true
},
"bool-format": {
"description": "Enable/disable optimization of bool formatting.",
"type": "boolean",
"default": true
},
"hex-format": {
"description": "Enable/disable optimization of hex formatting.",
"type": "boolean",
"default": true
},
"concat-loop": {
"description": "Enable/disable optimization of concat loop.",
"type": "boolean",
"default": true
},
"loop-other-ops": {
"description": "Optimization of `concat-loop` even with other operations.",
"type": "boolean",
"default": false
}
}
},
"preallocSettings": {
"description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
"type": "object",
"additionalProperties": false,
"properties": {
"simple": {
"description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
"type": "boolean",
"default": true
},
"range-loops": {
"description": "Report preallocation suggestions on range loops.",
"type": "boolean",
"default": true
},
"for-loops": {
"description": "Report preallocation suggestions on for loops.",
"type": "boolean",
"default": false
}
}
},
"predeclaredSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore": {
"description": "List of predeclared identifiers to not report on.",
"type": "array",
"items": {
"type": "string"
}
},
"qualified-name": {
"description": "Include method names and field names in checks.",
"type": "boolean",
"default": false
}
}
},
"promlinterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"strict": {},
"disabled-linters": {
"type": "array",
"items": {
"enum": [
"Help",
"MetricUnits",
"Counter",
"HistogramSummaryReserved",
"MetricTypeInName",
"ReservedChars",
"CamelCase",
"UnitAbbreviations"
]
}
}
}
},
"protogetterSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-generated-by": {
"type": "array",
"items": {
"type": "string",
"examples": ["protoc-gen-go-my-own-generator"]
}
},
"skip-files": {
"type": "array",
"items": {
"type": "string",
"examples": ["*.pb.go"]
}
},
"skip-any-generated": {
"description": "Skip any generated files from the checking.",
"type": "boolean",
"default": false
},
"replace-first-arg-in-append": {
"description": "Skip first argument of append function.",
"type": "boolean",
"default": false
}
}
},
"reviveSettings": {
"type": "object",
"additionalProperties": false,
"examples": [
{
"ignore-generated-header": true,
"severity": "warning",
"rules": [
{
"name": "indent-error-flow",
"severity": "warning"
},
{
"name": "add-constant",
"severity": "warning",
"arguments": [
{
"maxLitCount": "3",
"allowStrs": "\"\"",
"allowInts": "0,1,2",
"allowFloats": "0.0,0.,1.0,1.,2.0,2."
}
]
}
]
}
],
"properties": {
"max-open-files": {
"type": "integer"
},
"confidence": {
"type": "number"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"enable-all-rules": {
"type": "boolean",
"default": false
},
"enable-default-rules": {
"type": "boolean",
"default": false
},
"directives": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"enum": ["specify-disable-reason"]
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"$ref": "#/definitions/revive-rules",
"title": "The rule name"
},
"disabled": {
"type": "boolean"
},
"severity": {
"type": "string",
"enum": ["warning", "error"]
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
},
"arguments": {
"type": "array"
}
}
}
}
}
},
"rowserrcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"packages": {
"type": "array",
"items": {
"description": "",
"type": "string",
"examples": ["github.com/jmoiron/sqlx"]
}
}
}
},
"sloglintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"kv-only": {
"description": "Enforce using key-value pairs only (incompatible with attr-only).",
"type": "boolean",
"default": false
},
"no-global": {
"description": "Enforce not using global loggers.",
"enum": ["", "all", "default"],
"default": ""
},
"no-mixed-args": {
"description": "Enforce not mixing key-value pairs and attributes.",
"type": "boolean",
"default": true
},
"context": {
"description": "Enforce using methods that accept a context.",
"enum": ["", "all", "scope"],
"default": ""
},
"static-msg": {
"description": "Enforce using static values for log messages.",
"type": "boolean",
"default": false
},
"msg-style": {
"description": "Enforce message style.",
"enum": ["", "lowercased", "capitalized"],
"default": ""
},
"key-naming-case": {
"description": "Enforce a single key naming convention.",
"enum": ["snake", "kebab", "camel", "pascal"]
},
"attr-only": {
"description": "Enforce using attributes only (incompatible with kv-only).",
"type": "boolean",
"default": false
},
"no-raw-keys": {
"description": "Enforce using constants instead of raw keys.",
"type": "boolean",
"default": false
},
"forbidden-keys": {
"description": "Enforce not using specific keys.",
"type": "array",
"items": {
"type": "string"
}
},
"args-on-sep-lines": {
"description": "Enforce putting arguments on separate lines.",
"type": "boolean",
"default": false
}
}
},
"spancheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"description": "Checks to enable.",
"type": "array",
"items": {
"enum": ["end", "record-error", "set-status"]
}
},
"ignore-check-signatures": {
"description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
"type": "array",
"items": {
"type": "string"
}
},
"extra-start-span-signatures": {
"description": "A list of regexes for additional function signatures that create spans.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"staticcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"checks": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/staticcheck-checks"
},
{
"type": "string"
}
]
}
},
"dot-import-whitelist": {
"description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
"type": "array",
"items": {
"type": "string"
}
},
"http-status-code-whitelist": {
"description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
"default": ["200", "400", "404", "500"],
"type": "array",
"items": {
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"306",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"421",
"422",
"423",
"424",
"425",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"510",
"511"
]
}
},
"initialisms": {
"description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
"type": "array",
"items": {
"type": "string",
"default": [
"ACL",
"API",
"ASCII",
"CPU",
"CSS",
"DNS",
"EOF",
"GUID",
"HTML",
"HTTP",
"HTTPS",
"ID",
"IP",
"JSON",
"QPS",
"RAM",
"RPC",
"SLA",
"SMTP",
"SQL",
"SSH",
"TCP",
"TLS",
"TTL",
"UDP",
"UI",
"GID",
"UID",
"UUID",
"URI",
"URL",
"UTF8",
"VM",
"XML",
"XMPP",
"XSRF",
"XSS",
"SIP",
"RTP",
"AMQP",
"DB",
"TS"
]
}
}
}
},
"tagalignSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"align": {
"description": "Align and sort can be used together or separately.",
"type": "boolean",
"default": true
},
"sort": {
"description": "Whether enable tags sort.",
"type": "boolean",
"default": true
},
"order": {
"description": "Specify the order of tags, the other tags will be sorted by name.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [
[
"json",
"yaml",
"yml",
"toml",
"mapstructure",
"binding",
"validate"
]
]
},
"strict": {
"description": "Whether enable strict style.",
"type": "boolean",
"default": false
}
}
},
"tagliatelleSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"case": {
"type": "object",
"additionalProperties": false,
"properties": {
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
},
"overrides": {
"description": "Overrides the default/root configuration.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["pkg"],
"properties": {
"pkg": {
"description": "A package path.",
"type": "string"
},
"use-field-name": {
"description": "Use the struct field name to check the name of the struct tag.",
"type": "boolean",
"default": false
},
"ignored-fields": {
"description": "The field names to ignore.",
"type": "array",
"items": {
"type": "string",
"examples": ["example"]
}
},
"ignore": {
"description": "Ignore the package (takes precedence over all other configurations).",
"type": "boolean",
"default": false
},
"rules": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/tagliatelle-cases"
}
}
},
"extended-rules": {
"description": "Defines the association between tag name and case.",
"type": "object",
"patternProperties": {
"^.+$": {
"type": "object",
"additionalProperties": false,
"required": ["case"],
"properties": {
"case": {
"$ref": "#/definitions/tagliatelle-cases"
},
"extra-initialisms": {
"type": "boolean",
"default": false
},
"initialism-overrides": {
"type": "object",
"patternProperties": {
"^.+$": {
"type": "boolean",
"default": false
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"testifylintSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable-all": {
"description": "Enable all checkers.",
"type": "boolean",
"default": false
},
"disable-all": {
"description": "Disable all checkers.",
"type": "boolean",
"default": false
},
"enable": {
"description": "Enable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
]
},
"default": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"useless-assert"
]
},
"disable": {
"description": "Disable specific checkers.",
"type": "array",
"items": {
"enum": [
"blank-import",
"bool-compare",
"compares",
"contains",
"empty",
"encoded-compare",
"equal-values",
"error-is-as",
"error-nil",
"expected-actual",
"float-compare",
"formatter",
"go-require",
"len",
"negative-positive",
"nil-compare",
"regexp",
"require-error",
"suite-broken-parallel",
"suite-dont-use-pkg",
"suite-extra-assert-call",
"suite-method-signature",
"suite-subtest-run",
"suite-thelper",
"useless-assert"
],
"default": [
"suite-thelper"
]
}
},
"bool-compare": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-custom-types": {
"description": "To ignore user defined types (over builtin bool).",
"type": "boolean",
"default": false
}
}
},
"expected-actual": {
"type": "object",
"additionalProperties": false,
"properties": {
"pattern": {
"description": "Regexp for expected variable name.",
"type": "string",
"default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
}
}
},
"formatter": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-format-string": {
"description": "To enable go vet's printf checks.",
"type": "boolean",
"default": true
},
"require-f-funcs": {
"description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
"type": "boolean",
"default": false
},
"require-string-msg": {
"description": "To require that the first element of msgAndArgs (msg) has a string type.",
"type": "boolean",
"default": true
}
}
},
"go-require": {
"type": "object",
"additionalProperties": false,
"properties": {
"ignore-http-handlers": {
"description": "To ignore HTTP handlers (like http.HandlerFunc).",
"type": "boolean",
"default": false
}
}
},
"require-error": {
"type": "object",
"additionalProperties": false,
"properties": {
"fn-pattern": {
"description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
"type": "string",
"default": ""
}
}
},
"suite-extra-assert-call": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"description": "To require or remove extra Assert() call?",
"type": "string",
"enum": ["remove", "require"],
"default": "remove"
}
}
}
}
},
"testpackageSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"skip-regexp": {
"description": "Files with names matching this regular expression are skipped.",
"type": "string",
"examples": ["(export|internal)_test\\.go"]
},
"allow-packages": {
"description": "List of packages that don't end with _test that tests are allowed to be in.",
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"examples": ["example"]
}
}
}
},
"thelperSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `t.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.T is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.T param has t name.",
"default": true,
"type": "boolean"
}
}
},
"benchmark": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `b.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.B is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.B param has b name.",
"default": true,
"type": "boolean"
}
}
},
"tb": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `tb.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.TB is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.TB param has tb name.",
"default": true,
"type": "boolean"
}
}
},
"fuzz": {
"type": "object",
"additionalProperties": false,
"properties": {
"begin": {
"description": "Check if `f.Helper()` begins helper function.",
"default": true,
"type": "boolean"
},
"first": {
"description": "Check if *testing.F is first param of helper function.",
"default": true,
"type": "boolean"
},
"name": {
"description": "Check if *testing.F param has f name.",
"default": true,
"type": "boolean"
}
}
}
}
},
"usestdlibvarsSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"http-method": {
"description": "Suggest the use of http.MethodXX.",
"type": "boolean",
"default": true
},
"http-status-code": {
"description": "Suggest the use of http.StatusXX.",
"type": "boolean",
"default": true
},
"time-weekday": {
"description": "Suggest the use of time.Weekday.String().",
"type": "boolean",
"default": false
},
"time-month": {
"description": "Suggest the use of time.Month.String().",
"type": "boolean",
"default": false
},
"time-layout": {
"description": "Suggest the use of time.Layout.",
"type": "boolean",
"default": false
},
"time-date-month": {
"description": "Suggest the use of time.Month in time.Date.",
"type": "boolean",
"default": false
},
"crypto-hash": {
"description": "Suggest the use of crypto.Hash.String().",
"type": "boolean",
"default": false
},
"default-rpc-path": {
"description": "Suggest the use of rpc.DefaultXXPath.",
"type": "boolean",
"default": false
},
"sql-isolation-level": {
"description": "Suggest the use of sql.LevelXX.String().",
"type": "boolean",
"default": false
},
"tls-signature-scheme": {
"description": "Suggest the use of tls.SignatureScheme.String().",
"type": "boolean",
"default": false
},
"constant-kind": {
"description": "Suggest the use of constant.Kind.String().",
"type": "boolean",
"default": false
}
}
},
"usetestingSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"context-background": {
"type": "boolean",
"default": false
},
"context-todo": {
"type": "boolean",
"default": false
},
"os-chdir": {
"type": "boolean",
"default": true
},
"os-mkdir-temp": {
"type": "boolean",
"default": true
},
"os-setenv": {
"type": "boolean",
"default": true
},
"os-create-temp": {
"type": "boolean",
"default": true
},
"os-temp-dir": {
"type": "boolean",
"default": false
}
}
},
"unconvertSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"fast-math": {
"type": "boolean",
"default": false
},
"safe": {
"type": "boolean",
"default": false
}
}
},
"unparamSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-exported": {
"description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
"type": "boolean",
"default": false
}
}
},
"unqueryvetSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-sql-builders": {
"description": "Enable SQL builder checking.",
"type": "boolean",
"default": true
},
"check-aliased-wildcard": {
"description": "Enable aliased wildcard detection like SELECT t.*.",
"type": "boolean",
"default": true
},
"check-string-concat": {
"description": "Enable string concatenation analysis.",
"type": "boolean",
"default": true
},
"check-format-strings": {
"description": "Enable format string analysis like fmt.Sprintf.",
"type": "boolean",
"default": true
},
"check-string-builder": {
"description": "Enable strings.Builder analysis.",
"type": "boolean",
"default": true
},
"check-subqueries": {
"description": "Enable subquery analysis.",
"type": "boolean",
"default": true
},
"check-n1": {
"type": "boolean",
"default": false
},
"check-sql-injection": {
"type": "boolean",
"default": false
},
"check-tx-leaks": {
"type": "boolean",
"default": false
},
"allowed-patterns": {
"description": "Regex patterns for acceptable SELECT * usage.",
"type": "array",
"items": {
"type": "string"
}
},
"allow": {
"description": "Allow is a list of SQL patterns to allow (whitelist).",
"type": "array",
"items": {
"type": "string"
}
},
"ignored-functions": {
"description": "Functions to ignore.",
"type": "array",
"items": {
"type": "string"
}
},
"sql-builders": {
"type": "object",
"additionalProperties": false,
"properties": {
"squirrel": {
"type": "boolean",
"default": true
},
"gorm": {
"type": "boolean",
"default": true
},
"sqlx": {
"type": "boolean",
"default": true
},
"ent": {
"type": "boolean",
"default": true
},
"pgx": {
"type": "boolean",
"default": true
},
"bun": {
"type": "boolean",
"default": true
},
"sqlboiler": {
"type": "boolean",
"default": true
},
"jet": {
"type": "boolean",
"default": true
}
}
},
"custom-rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"pattern": {
"type": "string"
},
"patterns": {
"type": "array",
"items": {
"type": "string"
}
},
"when": {
"type": "string"
},
"message": {
"type": "string"
},
"action": {
"type": "string"
}
}
}
}
}
},
"unusedSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"field-writes-are-uses": {
"description": "",
"type": "boolean",
"default": true
},
"post-statements-are-reads": {
"description": "",
"type": "boolean",
"default": false
},
"exported-fields-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"parameters-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"local-variables-are-used": {
"description": "",
"type": "boolean",
"default": true
},
"generated-is-used": {
"description": "",
"type": "boolean",
"default": true
}
}
},
"varnamelenSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-distance": {
"description": "Variables used in at most this N-many lines will be ignored.",
"type": "integer",
"default": 5
},
"min-name-length": {
"description": "The minimum length of a variable's name that is considered `long`.",
"type": "integer",
"default": 3
},
"check-receiver": {
"description": "Check method receiver names.",
"default": false,
"type": "boolean"
},
"check-return": {
"description": "Check named return values.",
"default": false,
"type": "boolean"
},
"check-type-param": {
"description": "Check type parameters.",
"default": false,
"type": "boolean"
},
"ignore-type-assert-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a type assertion",
"default": false,
"type": "boolean"
},
"ignore-map-index-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a map index.",
"default": false,
"type": "boolean"
},
"ignore-chan-recv-ok": {
"description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
"default": false,
"type": "boolean"
},
"ignore-names": {
"description": "Optional list of variable names that should be ignored completely.",
"default": [[]],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-decls": {
"description": "Optional list of variable declarations that should be ignored completely.",
"type": "array",
"items": {
"type": "string"
},
"examples": [
["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
]
}
}
},
"whitespaceSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"multi-if": {
"description": "Enforces newlines (or comments) after every multi-line if statement",
"type": "boolean",
"default": false
},
"multi-func": {
"description": "Enforces newlines (or comments) after every multi-line function signature",
"type": "boolean",
"default": false
}
}
},
"wrapcheckSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"extra-ignore-sigs": {
"description": "An array of strings specifying additional substrings of signatures to ignore.",
"default": [
".CustomError(",
".SpecificWrap("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sigs": {
"description": "An array of strings which specify substrings of signatures to ignore.",
"default": [
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack("
],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-sig-regexps": {
"description": "An array of strings which specify regular expressions of signatures to ignore.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-package-globs": {
"description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"ignore-interface-regexps": {
"description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
"default": [""],
"type": "array",
"items": {
"type": "string"
}
},
"report-internal-errors": {
"description": "Determines whether wrapcheck should report errors returned from inside the package.",
"type": "boolean",
"default": false
}
}
},
"wslSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-assign-and-anything": {
"description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
"type": "boolean",
"default": false
},
"allow-assign-and-call": {
"description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
"type": "boolean",
"default": true
},
"allow-cuddle-declarations": {
"description": "Allow declarations (var) to be cuddled.",
"type": "boolean",
"default": false
},
"allow-cuddle-with-calls": {
"description": "A list of call idents that everything can be cuddled with.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-with-rhs": {
"description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
"type": "array",
"items": {
"type": "string"
}
},
"allow-cuddle-used-in-block": {
"description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
"type": "boolean",
"default": false
},
"allow-multiline-assign": {
"description": "Allow multiline assignments to be cuddled.",
"type": "boolean",
"default": true
},
"allow-separated-leading-comment": {
"description": "Allow leading comments to be separated with empty lines.",
"type": "boolean",
"default": false
},
"allow-trailing-comment": {
"description": "Allow trailing comments in ending of blocks.",
"type": "boolean",
"default": false
},
"error-variable-names": {
"description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
"type": "array",
"items": {
"type": "string"
}
},
"force-case-trailing-whitespace": {
"description": "Force newlines in end of case at this limit (0 = never).",
"type": "integer",
"minimum": 0,
"default": 0
},
"force-err-cuddling": {
"description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
"type": "boolean",
"default": false
},
"force-short-decl-cuddling": {
"description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
"type": "boolean",
"default": false
},
"strict-append": {
"description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
"type": "boolean",
"default": true
}
}
},
"wslSettingsV5": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow-first-in-block": {
"type": "boolean",
"default": true
},
"allow-whole-block": {
"type": "boolean",
"default": false
},
"branch-max-lines": {
"type": "integer",
"default": 2
},
"case-max-lines": {
"type": "integer",
"default": 0
},
"default": {
"enum": ["all", "none", "default", ""],
"default": "default"
},
"enable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
},
"disable": {
"type": "array",
"items": {
"$ref": "#/definitions/wsl-checks"
}
}
}
},
"copyloopvarSettings": {
"type": "object",
"additionalProperties": false,
"properties": {
"check-alias": {
"type": "boolean",
"default": false
}
}
},
"customSettings": {
"description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "The plugin type.",
"enum": ["module", "goplugin"],
"default": "goplugin"
},
"path": {
"description": "The path to the plugin *.so. Can be absolute or local.",
"type": "string",
"examples": ["/path/to/example.so"]
},
"description": {
"description": "The description of the linter, for documentation purposes only.",
"type": "string"
},
"original-url": {
"description": "Intended to point to the repo location of the linter, for documentation purposes only.",
"type": "string"
},
"settings": {
"description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
"type": "object"
}
},
"oneOf": [
{
"properties": {
"type": {"enum": ["module"] }
},
"required": ["type"]
},
{
"required": ["path"]
}
]
}
}
}
}
}
},
"type": "object",
"additionalProperties": false,
"required": ["version"],
"properties": {
"version": {
"type": "string",
"default": "2"
},
"run": {
"description": "Options for analysis running,",
"type": "object",
"additionalProperties": false,
"properties": {
"concurrency": {
"description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
"type": "integer",
"minimum": 0,
"examples": [4]
},
"timeout": {
"description": "Timeout for the analysis.",
"type": "string",
"pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
"default": "1m",
"examples": ["30s", "5m", "5m30s"]
},
"issues-exit-code": {
"description": "Exit code when at least one issue was found.",
"type": "integer",
"default": 1
},
"tests": {
"description": "Enable inclusion of test files.",
"type": "boolean",
"default": true
},
"build-tags": {
"description": "List of build tags to pass to all linters.",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"examples": [["mytag"]]
},
"modules-download-mode": {
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
"enum": ["mod", "readonly", "vendor"]
},
"enable-build-vcs": {
"type": "boolean",
"default": false
},
"allow-parallel-runners": {
"description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
"type": "boolean",
"default": false
},
"allow-serial-runners": {
"description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
"type": "boolean",
"default": false
},
"go": {
"description": "Targeted Go version.",
"type": "string",
"default": "1.17"
},
"relative-path-mode": {
"description": "The mode used to evaluate relative paths.",
"type": "string",
"$ref": "#/definitions/relative-path-modes",
"default": "wd"
}
}
},
"output": {
"description": "Output configuration options.",
"type": "object",
"additionalProperties": false,
"properties": {
"formats": {
"description": "Output formats to use.",
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"print-issued-lines": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"json": {
"$ref": "#/definitions/simple-format"
},
"tab": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"print-linter-name": {
"type": "boolean",
"default": true
},
"colors": {
"type": "boolean",
"default": true
}
}
},
"html": {
"$ref": "#/definitions/simple-format"
},
"checkstyle": {
"$ref": "#/definitions/simple-format"
},
"code-climate": {
"$ref": "#/definitions/simple-format"
},
"junit-xml": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/formats-path",
"default": "stdout"
},
"extended": {
"type": "boolean",
"default": true
}
}
},
"teamcity": {
"$ref": "#/definitions/simple-format"
},
"sarif": {
"$ref": "#/definitions/simple-format"
}
}
},
"path-mode": {
"type": "string",
"default": "",
"examples": ["abs"]
},
"path-prefix": {
"description": "Add a prefix to the output file references.",
"type": "string",
"default": ""
},
"show-stats": {
"description": "Show statistics per linter.",
"type": "boolean",
"default": true
},
"sort-order": {
"type": "array",
"items": {
"enum": ["linter", "severity", "file"]
}
}
}
},
"linters": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"enum": [
"standard",
"all",
"none",
"fast"
]
},
"enable": {
"description": "List of enabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"disable": {
"description": "List of disabled linters.",
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"settings": {
"description": "All available settings of specific linters.",
"type": "object",
"additionalProperties": false,
"properties": {
"dupword": {
"$ref": "#/definitions/settings/definitions/dupwordSettings"
},
"asasalint": {
"$ref": "#/definitions/settings/definitions/asasalintSettings"
},
"bidichk": {
"$ref": "#/definitions/settings/definitions/bidichkSettings"
},
"cyclop": {
"$ref": "#/definitions/settings/definitions/cyclopSettings"
},
"decorder": {
"$ref": "#/definitions/settings/definitions/decorderSettings"
},
"depguard":{
"$ref": "#/definitions/settings/definitions/depguardSettings"
},
"dogsled": {
"$ref": "#/definitions/settings/definitions/dogsledSettings"
},
"dupl": {
"$ref": "#/definitions/settings/definitions/duplSettings"
},
"embeddedstructfieldcheck": {
"$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
},
"errcheck": {
"$ref": "#/definitions/settings/definitions/errcheckSettings"
},
"errchkjson": {
"$ref": "#/definitions/settings/definitions/errchkjsonSettings"
},
"errorlint": {
"$ref": "#/definitions/settings/definitions/errorlintSettings"
},
"exhaustive": {
"$ref": "#/definitions/settings/definitions/exhaustiveSettings"
},
"exhaustruct": {
"$ref": "#/definitions/settings/definitions/exhaustructSettings"
},
"fatcontext": {
"$ref": "#/definitions/settings/definitions/fatcontextSettings"
},
"forbidigo": {
"$ref": "#/definitions/settings/definitions/forbidigoSettings"
},
"funcorder": {
"$ref": "#/definitions/settings/definitions/funcorderSettings"
},
"funlen": {
"$ref": "#/definitions/settings/definitions/funlenSettings"
},
"ginkgolinter": {
"$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
},
"gochecksumtype": {
"$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
},
"gocognit": {
"$ref": "#/definitions/settings/definitions/gocognitSettings"
},
"goconst": {
"$ref": "#/definitions/settings/definitions/goconstSettings"
},
"gocritic": {
"$ref": "#/definitions/settings/definitions/gocriticSettings"
},
"gocyclo": {
"$ref": "#/definitions/settings/definitions/gocycloSettings"
},
"godoclint": {
"$ref": "#/definitions/settings/definitions/godoclintSettings"
},
"godot": {
"$ref": "#/definitions/settings/definitions/godotSettings"
},
"godox": {
"$ref": "#/definitions/settings/definitions/godoxSettings"
},
"interfacebloat":{
"$ref": "#/definitions/settings/definitions/interfacebloatSettings"
},
"goheader": {
"$ref": "#/definitions/settings/definitions/goheaderSettings"
},
"gomoddirectives": {
"$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
},
"gomodguard": {
"$ref": "#/definitions/settings/definitions/gomodguardSettings"
},
"gosec": {
"$ref": "#/definitions/settings/definitions/gosecSettings"
},
"gosmopolitan": {
"$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
},
"govet": {
"$ref": "#/definitions/settings/definitions/govetSettings"
},
"grouper": {
"$ref": "#/definitions/settings/definitions/grouperSettings"
},
"iface": {
"$ref": "#/definitions/settings/definitions/ifaceSettings"
},
"importas": {
"$ref": "#/definitions/settings/definitions/importasSettings"
},
"inamedparam": {
"$ref": "#/definitions/settings/definitions/inamedparamSettings"
},
"ineffassign": {
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
},
"iotamixing": {
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
},
"ireturn": {
"$ref": "#/definitions/settings/definitions/ireturnSettings"
},
"lll": {
"$ref": "#/definitions/settings/definitions/lllSettings"
},
"maintidx": {
"$ref": "#/definitions/settings/definitions/maintidxSettings"
},
"makezero":{
"$ref": "#/definitions/settings/definitions/makezeroSettings"
},
"loggercheck": {
"$ref": "#/definitions/settings/definitions/loggercheckSettings"
},
"misspell": {
"$ref": "#/definitions/settings/definitions/misspellSettings"
},
"musttag": {
"$ref": "#/definitions/settings/definitions/musttagSettings"
},
"nakedret": {
"$ref": "#/definitions/settings/definitions/nakedretSettings"
},
"nestif": {
"$ref": "#/definitions/settings/definitions/nestifSettings"
},
"nilnil": {
"$ref": "#/definitions/settings/definitions/nilnilSettings"
},
"nlreturn": {
"$ref": "#/definitions/settings/definitions/nlreturnSettings"
},
"mnd": {
"$ref": "#/definitions/settings/definitions/mndSettings"
},
"modernize": {
"$ref": "#/definitions/settings/definitions/modernizeSettings"
},
"nolintlint":{
"$ref": "#/definitions/settings/definitions/nolintlintSettings"
},
"reassign": {
"$ref": "#/definitions/settings/definitions/reassignSettings"
},
"recvcheck": {
"$ref": "#/definitions/settings/definitions/recvcheckSettings"
},
"nonamedreturns": {
"$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
},
"paralleltest": {
"$ref": "#/definitions/settings/definitions/paralleltestSettings"
},
"perfsprint": {
"$ref": "#/definitions/settings/definitions/perfsprintSettings"
},
"prealloc": {
"$ref": "#/definitions/settings/definitions/preallocSettings"
},
"predeclared": {
"$ref": "#/definitions/settings/definitions/predeclaredSettings"
},
"promlinter": {
"$ref": "#/definitions/settings/definitions/promlinterSettings"
},
"protogetter": {
"$ref": "#/definitions/settings/definitions/protogetterSettings"
},
"revive": {
"$ref": "#/definitions/settings/definitions/reviveSettings"
},
"rowserrcheck": {
"$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
},
"sloglint": {
"$ref": "#/definitions/settings/definitions/sloglintSettings"
},
"spancheck": {
"$ref": "#/definitions/settings/definitions/spancheckSettings"
},
"staticcheck":{
"$ref": "#/definitions/settings/definitions/staticcheckSettings"
},
"tagalign": {
"$ref": "#/definitions/settings/definitions/tagalignSettings"
},
"tagliatelle": {
"$ref": "#/definitions/settings/definitions/tagliatelleSettings"
},
"testifylint": {
"$ref": "#/definitions/settings/definitions/testifylintSettings"
},
"testpackage": {
"$ref": "#/definitions/settings/definitions/testpackageSettings"
},
"thelper": {
"$ref": "#/definitions/settings/definitions/thelperSettings"
},
"usestdlibvars": {
"$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
},
"usetesting": {
"$ref": "#/definitions/settings/definitions/usetestingSettings"
},
"unconvert": {
"$ref": "#/definitions/settings/definitions/unconvertSettings"
},
"unparam": {
"$ref": "#/definitions/settings/definitions/unparamSettings"
},
"unqueryvet": {
"$ref": "#/definitions/settings/definitions/unqueryvetSettings"
},
"unused": {
"$ref": "#/definitions/settings/definitions/unusedSettings"
},
"varnamelen": {
"$ref": "#/definitions/settings/definitions/varnamelenSettings"
},
"whitespace": {
"$ref": "#/definitions/settings/definitions/whitespaceSettings"
},
"wrapcheck": {
"$ref": "#/definitions/settings/definitions/wrapcheckSettings"
},
"wsl": {
"$ref": "#/definitions/settings/definitions/wslSettings"
},
"wsl_v5": {
"$ref": "#/definitions/settings/definitions/wslSettingsV5"
},
"copyloopvar": {
"$ref": "#/definitions/settings/definitions/copyloopvarSettings"
},
"custom":{
"$ref": "#/definitions/settings/definitions/customSettings"
}
}
},
"exclusions":{
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"warn-unused": {
"type": "boolean",
"default": false
},
"presets": {
"type": "array",
"items": {
"enum": [
"comments",
"std-error-handling",
"common-false-positives",
"legacy"
]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
}
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"paths-except": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"formatters": {
"type": "object",
"additionalProperties": false,
"properties": {
"enable": {
"description": "List of enabled formatters.",
"type": "array",
"items": {
"$ref": "#/definitions/formatter-names"
}
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"gci": {
"$ref": "#/definitions/settings/definitions/gciSettings"
},
"gofmt": {
"$ref": "#/definitions/settings/definitions/gofmtSettings"
},
"gofumpt": {
"$ref": "#/definitions/settings/definitions/gofumptSettings"
},
"goimports": {
"$ref": "#/definitions/settings/definitions/goimportsSettings"
},
"golines": {
"$ref": "#/definitions/settings/definitions/golinesSettings"
}
}
},
"exclusions": {
"type": "object",
"additionalProperties": false,
"properties": {
"generated": {
"enum": ["strict", "lax", "disable"],
"default": "strict"
},
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"warn-unused": {
"type": "boolean",
"default": false
}
}
}
}
},
"issues": {
"type": "object",
"additionalProperties": false,
"properties": {
"max-issues-per-linter": {
"description": "Maximum issues count per one linter. Set to 0 to disable.",
"type": "integer",
"default": 50,
"minimum": 0
},
"max-same-issues": {
"description": "Maximum count of issues with the same text. Set to 0 to disable.",
"type": "integer",
"default": 3,
"minimum": 0
},
"new": {
"description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
"type": "boolean",
"default": false
},
"new-from-merge-base": {
"description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
"type": "string"
},
"new-from-rev": {
"description": "Show only new issues created after this git revision.",
"type": "string"
},
"new-from-patch": {
"description": "Show only new issues created in git patch with this file path.",
"type": "string",
"examples": ["path/to/patch/file"]
},
"fix": {
"description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
"type": "boolean",
"default": false
},
"uniq-by-line": {
"description": "Make issues output unique by line.",
"type": "boolean",
"default": true
},
"whole-files": {
"description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
"type": "boolean",
"default": false
}
}
},
"severity": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
"type": "string",
"default": ""
},
"rules": {
"description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"severity": {
"type": "string"
},
"path": {
"type": "string"
},
"path-except": {
"type": "string"
},
"linters": {
"type": "array",
"items": {
"$ref": "#/definitions/linter-names"
}
},
"text": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": ["severity"],
"anyOf": [
{ "required": ["path"] },
{ "required": ["path-except"] },
{ "required": ["linters"] },
{ "required": ["text"] },
{ "required": ["source"] }
]
},
"default": []
}
},
"required": ["default"]
}
}
}
================================================
FILE: pkg/commands/cache.go
================================================
package commands
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
"github.com/golangci/golangci-lint/v2/internal/cache"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type cacheCommand struct {
cmd *cobra.Command
}
func newCacheCommand() *cacheCommand {
c := &cacheCommand{}
cacheCmd := &cobra.Command{
Use: "cache",
Short: "Cache control and information.",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return cmd.Help()
},
}
cacheCmd.AddCommand(
&cobra.Command{
Use: "clean",
Short: "Clean cache",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
RunE: c.executeClean,
},
&cobra.Command{
Use: "status",
Short: "Show cache status",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
Run: c.executeStatus,
},
)
c.cmd = cacheCmd
return c
}
func (*cacheCommand) executeClean(_ *cobra.Command, _ []string) error {
cacheDir := cache.DefaultDir()
if err := os.RemoveAll(cacheDir); err != nil {
return fmt.Errorf("failed to remove dir %s: %w", cacheDir, err)
}
return nil
}
func (*cacheCommand) executeStatus(_ *cobra.Command, _ []string) {
cacheDir := cache.DefaultDir()
_, _ = fmt.Fprintf(logutils.StdOut, "Dir: %s\n", cacheDir)
cacheSizeBytes, err := dirSizeBytes(cacheDir)
if err == nil {
_, _ = fmt.Fprintf(logutils.StdOut, "Size: %s\n", fsutils.PrettifyBytesCount(cacheSizeBytes))
}
}
func dirSizeBytes(path string) (int64, error) {
var size int64
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
if err == nil && !info.IsDir() {
size += info.Size()
}
return err
})
return size, err
}
================================================
FILE: pkg/commands/config.go
================================================
package commands
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type pathOptions struct {
JSON bool
}
type configCommand struct {
viper *viper.Viper
cmd *cobra.Command
opts config.LoaderOptions
verifyOpts verifyOptions
pathOpts pathOptions
buildInfo BuildInfo
log logutils.Log
}
func newConfigCommand(log logutils.Log, info BuildInfo) *configCommand {
c := &configCommand{
viper: viper.New(),
log: log,
buildInfo: info,
}
configCmd := &cobra.Command{
Use: "config",
Short: "Configuration file information and verification.",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return cmd.Help()
},
PersistentPreRunE: c.preRunE,
}
verifyCommand := &cobra.Command{
Use: "verify",
Short: "Verify configuration against JSON schema.",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
RunE: c.executeVerify,
SilenceUsage: true,
SilenceErrors: true,
}
pathCommand := &cobra.Command{
Use: "path",
Short: "Print used configuration path.",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
RunE: c.executePath,
}
configCmd.AddCommand(
pathCommand,
verifyCommand,
)
flagSet := configCmd.PersistentFlags()
flagSet.SortFlags = false // sort them as they are defined here
setupConfigFileFlagSet(flagSet, &c.opts)
// ex: --schema jsonschema/golangci.next.jsonschema.json
verifyFlagSet := verifyCommand.Flags()
verifyFlagSet.StringVar(&c.verifyOpts.schemaURL, "schema", "", color.GreenString("JSON schema URL"))
_ = verifyFlagSet.MarkHidden("schema")
pathFlagSet := pathCommand.Flags()
pathFlagSet.BoolVar(&c.pathOpts.JSON, "json", false, color.GreenString("Display as JSON"))
c.cmd = configCmd
return c
}
func (c *configCommand) preRunE(cmd *cobra.Command, args []string) error {
// The command doesn't depend on the real configuration.
// It only needs to know the path of the configuration file.
cfg := config.NewDefault()
loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts, cfg, args)
err := loader.Load(config.LoadOptions{})
if err != nil {
return fmt.Errorf("can't load config: %w", err)
}
return nil
}
func (c *configCommand) executePath(cmd *cobra.Command, _ []string) error {
usedConfigFile := c.getUsedConfig()
if c.pathOpts.JSON {
abs, err := filepath.Abs(usedConfigFile)
if err != nil {
return err
}
return json.NewEncoder(cmd.OutOrStdout()).Encode(map[string]string{
"path": usedConfigFile,
"absolutePath": abs,
})
}
if usedConfigFile == "" {
c.log.Warnf("No config file detected")
os.Exit(exitcodes.NoConfigFileDetected)
}
cmd.Println(usedConfigFile)
return nil
}
// getUsedConfig returns the resolved path to the golangci config file,
// or the empty string if no configuration could be found.
func (c *configCommand) getUsedConfig() string {
usedConfigFile := c.viper.ConfigFileUsed()
if usedConfigFile == "" {
return ""
}
prettyUsedConfigFile, err := fsutils.ShortestRelPath(usedConfigFile, "")
if err != nil {
c.log.Warnf("Can't pretty print config file path: %s", err)
return usedConfigFile
}
return prettyUsedConfigFile
}
================================================
FILE: pkg/commands/config_verify.go
================================================
package commands
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
hcversion "github.com/hashicorp/go-version"
"github.com/pelletier/go-toml/v2"
"github.com/santhosh-tekuri/jsonschema/v6"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"go.yaml.in/yaml/v3"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
)
type verifyOptions struct {
schemaURL string // For debugging purpose only (Flag only).
}
func (c *configCommand) executeVerify(cmd *cobra.Command, _ []string) error {
usedConfigFile := c.getUsedConfig()
if usedConfigFile == "" {
c.log.Warnf("No config file detected")
os.Exit(exitcodes.NoConfigFileDetected)
}
schemaURL, err := createSchemaURL(cmd.Flags(), c.buildInfo)
if err != nil {
return fmt.Errorf("get JSON schema: %w", err)
}
c.log.Infof("Verifying the configuration file %q with the JSON Schema from %s", usedConfigFile, schemaURL)
err = validateConfiguration(schemaURL, usedConfigFile)
if err != nil {
var v *jsonschema.ValidationError
if !errors.As(err, &v) {
return fmt.Errorf("[%s] validate: %w", usedConfigFile, err)
}
printValidationDetail(cmd, v.DetailedOutput())
return errors.New("the configuration contains invalid elements")
}
return nil
}
func createSchemaURL(flags *pflag.FlagSet, buildInfo BuildInfo) (string, error) {
schemaURL, err := flags.GetString("schema")
if err != nil {
return "", fmt.Errorf("get schema flag: %w", err)
}
if schemaURL != "" {
return schemaURL, nil
}
switch {
case buildInfo.Version != "" && buildInfo.Version != "(devel)":
version, err := hcversion.NewVersion(buildInfo.Version)
if err != nil {
return "", fmt.Errorf("parse version: %w", err)
}
if version.Core().Equal(hcversion.Must(hcversion.NewVersion("v0.0.0"))) {
commit, err := extractCommitHash(buildInfo)
if err != nil {
return "", err
}
return fmt.Sprintf("https://raw.githubusercontent.com/golangci/golangci-lint/%s/jsonschema/golangci.next.jsonschema.json",
commit), nil
}
return fmt.Sprintf("https://golangci-lint.run/jsonschema/golangci.v%d.%d.jsonschema.json",
version.Segments()[0], version.Segments()[1]), nil
case buildInfo.Commit != "" && buildInfo.Commit != "?":
commit, err := extractCommitHash(buildInfo)
if err != nil {
return "", err
}
return fmt.Sprintf("https://raw.githubusercontent.com/golangci/golangci-lint/%s/jsonschema/golangci.next.jsonschema.json",
commit), nil
default:
return "", errors.New("version not found")
}
}
func extractCommitHash(buildInfo BuildInfo) (string, error) {
if buildInfo.Commit == "" || buildInfo.Commit == "?" {
return "", errors.New("empty commit information")
}
if buildInfo.Commit == "unknown" {
return "", errors.New("unknown commit information")
}
commit := buildInfo.Commit
if after, ok := strings.CutPrefix(commit, "("); ok {
c, _, ok := strings.Cut(after, ",")
if !ok {
return "", errors.New("commit information not found")
}
commit = c
}
if commit == "unknown" {
return "", errors.New("unknown commit information")
}
return commit, nil
}
func validateConfiguration(schemaPath, targetFile string) error {
compiler := jsonschema.NewCompiler()
compiler.UseLoader(jsonschema.SchemeURLLoader{
"file": jsonschema.FileLoader{},
"https": newJSONSchemaHTTPLoader(),
})
compiler.DefaultDraft(jsonschema.Draft7)
schema, err := compiler.Compile(schemaPath)
if err != nil {
return fmt.Errorf("compile schema: %w", err)
}
var m any
switch strings.ToLower(filepath.Ext(targetFile)) {
case ".yaml", ".yml", ".json":
m, err = decodeYamlFile(targetFile)
if err != nil {
return err
}
case ".toml":
m, err = decodeTomlFile(targetFile)
if err != nil {
return err
}
default:
// unsupported
return errors.New("unsupported configuration format")
}
return schema.Validate(m)
}
func printValidationDetail(cmd *cobra.Command, detail *jsonschema.OutputUnit) {
if detail.Error != nil {
data, _ := json.Marshal(detail.Error)
details, _ := strconv.Unquote(string(data))
cmd.PrintErrf("jsonschema: %q does not validate with %q: %s\n",
strings.ReplaceAll(strings.TrimPrefix(detail.InstanceLocation, "/"), "/", "."), detail.KeywordLocation, details)
}
for _, d := range detail.Errors {
printValidationDetail(cmd, &d)
}
}
func decodeYamlFile(filename string) (any, error) {
file, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("[%s] file open: %w", filename, err)
}
defer func() { _ = file.Close() }()
var m any
err = yaml.NewDecoder(file).Decode(&m)
if err != nil {
return nil, fmt.Errorf("[%s] YAML decode: %w", filename, err)
}
return m, nil
}
func decodeTomlFile(filename string) (any, error) {
file, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("[%s] file open: %w", filename, err)
}
defer func() { _ = file.Close() }()
var m any
err = toml.NewDecoder(file).Decode(&m)
if err != nil {
return nil, fmt.Errorf("[%s] TOML decode: %w", filename, err)
}
return m, nil
}
type jsonschemaHTTPLoader struct {
*http.Client
}
func newJSONSchemaHTTPLoader() *jsonschemaHTTPLoader {
return &jsonschemaHTTPLoader{Client: &http.Client{
Timeout: 2 * time.Second,
}}
}
func (l jsonschemaHTTPLoader) Load(url string) (any, error) {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, http.NoBody)
if err != nil {
return nil, err
}
resp, err := l.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s returned status code %d", url, resp.StatusCode)
}
return jsonschema.UnmarshalJSON(resp.Body)
}
================================================
FILE: pkg/commands/config_verify_test.go
================================================
package commands
import (
"testing"
"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_createSchemaURL(t *testing.T) {
testCases := []struct {
desc string
flag string
info BuildInfo
expected string
}{
{
desc: "schema flag only",
flag: "https://example.com",
expected: "https://example.com",
},
{
desc: "schema flag and build info",
flag: "https://example.com",
info: BuildInfo{
Version: "v1.0.0",
Commit: "cd8b11773c6c1f595e8eb98c0d4310af20ae20df",
},
expected: "https://example.com",
},
{
desc: "version and commit",
info: BuildInfo{
Version: "v1.0.0",
Commit: "cd8b11773c6c1f595e8eb98c0d4310af20ae20df",
},
expected: "https://golangci-lint.run/jsonschema/golangci.v1.0.jsonschema.json",
},
{
desc: "commit only",
info: BuildInfo{
Commit: "cd8b11773c6c1f595e8eb98c0d4310af20ae20df",
},
expected: "https://raw.githubusercontent.com/golangci/golangci-lint/cd8b11773c6c1f595e8eb98c0d4310af20ae20df/jsonschema/golangci.next.jsonschema.json",
},
{
desc: "version devel and commit",
info: BuildInfo{
Version: "(devel)",
Commit: "cd8b11773c6c1f595e8eb98c0d4310af20ae20df",
},
expected: "https://raw.githubusercontent.com/golangci/golangci-lint/cd8b11773c6c1f595e8eb98c0d4310af20ae20df/jsonschema/golangci.next.jsonschema.json",
},
{
desc: "composite commit info",
info: BuildInfo{
Version: "",
Commit: `(cd8b11773c6c1f595e8eb98c0d4310af20ae20df, modified: "false", mod sum: "123")`,
},
expected: "https://raw.githubusercontent.com/golangci/golangci-lint/cd8b11773c6c1f595e8eb98c0d4310af20ae20df/jsonschema/golangci.next.jsonschema.json",
},
{
desc: "v0 version",
info: BuildInfo{
Version: "v0.0.0-20250213211019-0a603e49e5e9",
Commit: `(0a603e49e5e9870f5f9f2035bcbe42cd9620a9d5, modified: "false", mod sum: "123")`,
},
expected: "https://raw.githubusercontent.com/golangci/golangci-lint/0a603e49e5e9870f5f9f2035bcbe42cd9620a9d5/jsonschema/golangci.next.jsonschema.json",
},
{
desc: "dirty",
info: BuildInfo{
Version: "v1.64.6-0.20250225205237-3eecab1ebde9+dirty",
Commit: `(3eecab1ebde9, modified: "false", mod sum: "123")`,
},
expected: "https://golangci-lint.run/jsonschema/golangci.v1.64.jsonschema.json",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
flags.String("schema", "", "")
if test.flag != "" {
_ = flags.Set("schema", test.flag)
}
schemaURL, err := createSchemaURL(flags, test.info)
require.NoError(t, err)
assert.Equal(t, test.expected, schemaURL)
})
}
}
func Test_createSchemaURL_error(t *testing.T) {
testCases := []struct {
desc string
info BuildInfo
expected string
}{
{
desc: "unknown commit",
info: BuildInfo{
Commit: "unknown",
},
expected: "unknown commit information",
},
{
desc: "detailed unknown commit",
info: BuildInfo{
Version: "",
Commit: `(unknown, modified: ?, mod sum: "")`,
},
expected: "unknown commit information",
},
{
desc: "commit ?",
info: BuildInfo{
Commit: "?",
},
expected: "version not found",
},
{
desc: "version devel only",
info: BuildInfo{
Version: "(devel)",
},
expected: "version not found",
},
{
desc: "invalid version",
info: BuildInfo{
Version: "example",
},
expected: "parse version: malformed version: example",
},
{
desc: "invalid composite commit info",
info: BuildInfo{
Version: "",
Commit: `(cd8b11773c6c1f595e8eb98c0d4310af20ae20df)`,
},
expected: "commit information not found",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
flags.String("schema", "", "")
_, err := createSchemaURL(flags, test.info)
require.EqualError(t, err, test.expected)
})
}
}
================================================
FILE: pkg/commands/custom.go
================================================
package commands
import (
"fmt"
"log"
"os"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const envKeepTempFiles = "CUSTOM_GCL_KEEP_TEMP_FILES"
type customOptions struct {
version string
name string
destination string
}
type customCommand struct {
cmd *cobra.Command
cfg *internal.Configuration
opts customOptions
log logutils.Log
}
func newCustomCommand(logger logutils.Log) *customCommand {
c := &customCommand{log: logger}
customCmd := &cobra.Command{
Use: "custom",
Short: "Build a version of golangci-lint with custom linters.",
Args: cobra.NoArgs,
PreRunE: c.preRunE,
RunE: c.runE,
SilenceUsage: true,
}
flagSet := customCmd.PersistentFlags()
flagSet.SortFlags = false // sort them as they are defined here
flagSet.StringVar(&c.opts.version, "version", "", color.GreenString("The golangci-lint version used to build the custom binary"))
flagSet.StringVar(&c.opts.name, "name", "", color.GreenString("The name of the custom binary"))
flagSet.StringVar(&c.opts.destination, "destination", "", color.GreenString("The directory path used to store the custom binary"))
c.cmd = customCmd
return c
}
func (c *customCommand) preRunE(_ *cobra.Command, _ []string) error {
cfg, err := internal.LoadConfiguration()
if err != nil {
return err
}
if c.opts.version != "" {
cfg.Version = c.opts.version
}
if c.opts.name != "" {
cfg.Name = c.opts.name
}
if c.opts.destination != "" {
cfg.Destination = c.opts.destination
}
err = cfg.Validate()
if err != nil {
return err
}
c.cfg = cfg
return nil
}
func (c *customCommand) runE(cmd *cobra.Command, _ []string) error {
tmp, err := os.MkdirTemp(os.TempDir(), "custom-gcl")
if err != nil {
return fmt.Errorf("create temporary directory: %w", err)
}
defer func() {
if os.Getenv(envKeepTempFiles) != "" {
log.Printf("WARN: The env var %s has been detected: the temporary directory is preserved: %s", envKeepTempFiles, tmp)
return
}
_ = os.RemoveAll(tmp)
}()
err = internal.NewBuilder(c.log, c.cfg, tmp).Build(cmd.Context())
if err != nil {
return fmt.Errorf("build process: %w", err)
}
return nil
}
================================================
FILE: pkg/commands/flagsets.go
================================================
package commands
import (
"github.com/fatih/color"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
)
const defaultMaxIssuesPerLinter = 50
func setupLintersFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
internal.AddFlagAndBind(v, fs, fs.String, "default", "linters.default", config.GroupStandard,
color.GreenString("Default set of linters to enable"))
internal.AddHackedStringSliceP(fs, "disable", "D", color.GreenString("Disable specific linter"))
internal.AddHackedStringSliceP(fs, "enable", "E", color.GreenString("Enable specific linter"))
fs.StringSlice("enable-only", nil,
color.GreenString("Override linters configuration section to only run the specific linter(s)")) // Flags only.
internal.AddFlagAndBind(v, fs, fs.Bool, "fast-only", "linters.fast-only", false,
color.GreenString("Filter enabled linters to run only fast linters"))
}
func setupFormattersFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
internal.AddFlagAndBindP(v, fs, fs.StringSliceP, "enable", "E", "formatters.enable", nil,
color.GreenString("Enable specific formatter"))
}
func setupRunFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
internal.AddFlagAndBindP(v, fs, fs.IntP, "concurrency", "j", "run.concurrency", 0,
color.GreenString("Number of CPUs to use (Default: Automatically set to match Linux container CPU quota"+
" and fall back to the number of logical CPUs in the machine)"))
internal.AddFlagAndBind(v, fs, fs.String, "modules-download-mode", "run.modules-download-mode", "",
color.GreenString("Modules download mode. If not empty, passed as -mod= to go tools"))
internal.AddFlagAndBind(v, fs, fs.Int, "issues-exit-code", "run.issues-exit-code", exitcodes.IssuesFound,
color.GreenString("Exit code when issues were found"))
internal.AddHackedStringSlice(fs, "build-tags", color.GreenString("Build tags"))
internal.AddFlagAndBind(v, fs, fs.Duration, "timeout", "run.timeout", defaultTimeout,
color.GreenString("Timeout for total work. Disabled by default"))
internal.AddFlagAndBind(v, fs, fs.Bool, "tests", "run.tests", true, color.GreenString("Analyze tests (*_test.go)"))
internal.AddDeprecatedHackedStringSlice(fs, "skip-files", color.GreenString("Regexps of files to skip"))
internal.AddDeprecatedHackedStringSlice(fs, "skip-dirs", color.GreenString("Regexps of directories to skip"))
const allowParallelDesc = "Allow multiple parallel golangci-lint instances running.\n" +
"If false (default) - golangci-lint acquires file lock on start."
internal.AddFlagAndBind(v, fs, fs.Bool, "allow-parallel-runners", "run.allow-parallel-runners", false,
color.GreenString(allowParallelDesc))
const allowSerialDesc = "Allow multiple golangci-lint instances running, but serialize them around a lock.\n" +
"If false (default) - golangci-lint exits with an error if it fails to acquire file lock on start."
internal.AddFlagAndBind(v, fs, fs.Bool, "allow-serial-runners", "run.allow-serial-runners", false, color.GreenString(allowSerialDesc))
}
func setupOutputFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
internal.AddFlagAndBind(v, fs, fs.String, "path-prefix", "output.path-prefix", "",
color.GreenString("Path prefix to add to output"))
internal.AddFlagAndBind(v, fs, fs.String, "path-mode", "output.path-mode", "",
color.GreenString("Path mode to use (empty, or 'abs')"))
internal.AddFlagAndBind(v, fs, fs.Bool, "show-stats", "output.show-stats", true, color.GreenString("Show statistics per linter"))
setupOutputFormatsFlagSet(v, fs)
}
func setupOutputFormatsFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
outputPathDesc := "Output path can be either `stdout`, `stderr` or path to the file to write to."
printLinterNameDesc := "Print linter name in the end of issue text."
colorsDesc := "Use colors."
internal.AddFlagAndBind(v, fs, fs.String, "output.text.path", "output.formats.text.path", "",
color.GreenString(outputPathDesc))
internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.print-linter-name", "output.formats.text.print-linter-name", true,
color.GreenString(printLinterNameDesc))
internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.print-issued-lines", "output.formats.text.print-issued-lines", true,
color.GreenString("Print lines of code with issue."))
internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.colors", "output.formats.text.colors", true,
color.GreenString(colorsDesc))
internal.AddFlagAndBind(v, fs, fs.String, "output.json.path", "output.formats.json.path", "",
color.GreenString(outputPathDesc))
internal.AddFlagAndBind(v, fs, fs.String, "output.tab.path", "output.formats.tab.path", "",
color.GreenString(outputPathDesc))
internal.AddFlagAndBind(v, fs, fs.Bool, "output.tab.print-linter-name", "output.formats.tab.print-linter-name",
true, color.GreenString(printLinterNameDesc))
internal.AddFlagAndBind(v, fs, fs.Bool, "output.tab.colors", "output.formats.tab.colors", true,
color.GreenString(colorsDesc))
internal.AddFlagAndBind(v, fs, fs.String, "output.html.path", "output.formats.html.path", "",
color.GreenString(outputPathDesc))
internal.AddFlagAndBind(v, fs, fs.String, "output.checkstyle.path", "output.formats.checkstyle.path", "",
color.GreenString(outputPathDesc))
internal.AddFlagAndBind(v, fs, fs.String, "output.code-climate.path", "output.formats.code-climate.path", "",
color.GreenString(outputPathDesc))
internal.AddFlagAndBind(v, fs, fs.String, "output.junit-xml.path", "output.formats.junit-xml.path", "",
color.GreenString(outputPathDesc))
internal.AddFlagAndBind(v, fs, fs.Bool, "output.junit-xml.extended", "output.formats.junit-xml.extended", false,
color.GreenString("Support extra JUnit XML fields."))
internal.AddFlagAndBind(v, fs, fs.String, "output.teamcity.path", "output.formats.teamcity.path", "",
color.GreenString(outputPathDesc))
internal.AddFlagAndBind(v, fs, fs.String, "output.sarif.path", "output.formats.sarif.path", "",
color.GreenString(outputPathDesc))
}
func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
internal.AddFlagAndBind(v, fs, fs.Int, "max-issues-per-linter", "issues.max-issues-per-linter", defaultMaxIssuesPerLinter,
color.GreenString("Maximum issues count per one linter. Set to 0 to disable"))
internal.AddFlagAndBind(v, fs, fs.Int, "max-same-issues", "issues.max-same-issues", 3,
color.GreenString("Maximum count of issues with the same text. Set to 0 to disable"))
internal.AddFlagAndBind(v, fs, fs.Bool, "uniq-by-line", "issues.uniq-by-line", true,
color.GreenString("Make issues output unique by line"))
const newDesc = "Show only new issues: if there are unstaged changes or untracked files, only those changes " +
"are analyzed, else only changes in HEAD~ are analyzed.\nIt's a super-useful option for integration " +
"of golangci-lint into existing large codebase.\nIt's not practical to fix all existing issues at " +
"the moment of integration: much better to not allow issues in new code.\nFor CI setups, prefer " +
"--new-from-rev=HEAD~, as --new can skip linting the current patch if any scripts generate " +
"unstaged files before golangci-lint runs."
internal.AddFlagAndBindP(v, fs, fs.BoolP, "new", "n", "issues.new", false, color.GreenString(newDesc))
internal.AddFlagAndBind(v, fs, fs.String, "new-from-rev", "issues.new-from-rev", "",
color.GreenString("Show only new issues created after git revision `REV`"))
internal.AddFlagAndBind(v, fs, fs.String, "new-from-patch", "issues.new-from-patch", "",
color.GreenString("Show only new issues created in git patch with file path `PATH`"))
internal.AddFlagAndBind(v, fs, fs.String, "new-from-merge-base", "issues.new-from-merge-base", "",
color.GreenString("Show only new issues created after the best common ancestor (merge-base against HEAD)"))
internal.AddFlagAndBind(v, fs, fs.Bool, "whole-files", "issues.whole-files", false,
color.GreenString("Show issues in any part of update files (requires new-from-rev or new-from-patch)"))
internal.AddFlagAndBind(v, fs, fs.Bool, "fix", "issues.fix", false,
color.GreenString("Apply the fixes detected by the linters and formatters (if it's supported by the linter)"))
}
================================================
FILE: pkg/commands/fmt.go
================================================
package commands
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goformat"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
"github.com/golangci/golangci-lint/v2/pkg/result/processors"
)
type fmtOptions struct {
config.LoaderOptions
diff bool // Flag only.
diffColored bool // Flag only.
stdin bool // Flag only.
}
type fmtCommand struct {
viper *viper.Viper
cmd *cobra.Command
opts fmtOptions
cfg *config.Config
buildInfo BuildInfo
runner *goformat.Runner
log logutils.Log
}
func newFmtCommand(logger logutils.Log, info BuildInfo) *fmtCommand {
c := &fmtCommand{
viper: viper.New(),
log: logger,
cfg: config.NewDefault(),
buildInfo: info,
}
fmtCmd := &cobra.Command{
Use: "fmt",
Short: "Format Go source files.",
RunE: c.execute,
PreRunE: c.preRunE,
PersistentPreRunE: c.persistentPreRunE,
PersistentPostRun: c.persistentPostRun,
SilenceUsage: true,
}
fmtCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals
fmtCmd.SetErr(logutils.StdErr)
fs := fmtCmd.Flags()
fs.SortFlags = false // sort them as they are defined here
setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
setupFormattersFlagSet(c.viper, fs)
fs.BoolVarP(&c.opts.diff, "diff", "d", false, color.GreenString("Display diffs instead of rewriting files"))
fs.BoolVar(&c.opts.diffColored, "diff-colored", false, color.GreenString("Display diffs instead of rewriting files (with colors)"))
fs.BoolVar(&c.opts.stdin, "stdin", false, color.GreenString("Use standard input for piping source files"))
c.cmd = fmtCmd
return c
}
func (c *fmtCommand) persistentPreRunE(cmd *cobra.Command, args []string) error {
c.log.Infof("%s", c.buildInfo.String())
loader := config.NewFormattersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
err := loader.Load(config.LoadOptions{CheckDeprecation: true, Validation: true})
if err != nil {
return fmt.Errorf("can't load config: %w", err)
}
return nil
}
func (c *fmtCommand) preRunE(_ *cobra.Command, _ []string) error {
if c.cfg.GetConfigDir() != "" && c.cfg.Version != "2" {
return fmt.Errorf("invalid version of the configuration: %q", c.cfg.Version)
}
metaFormatter, err := goformatters.NewMetaFormatter(c.log, &c.cfg.Formatters, &c.cfg.Run)
if err != nil {
return fmt.Errorf("failed to create meta-formatter: %w", err)
}
matcher := processors.NewGeneratedFileMatcher(c.cfg.Formatters.Exclusions.Generated)
opts, err := goformat.NewRunnerOptions(c.cfg, c.opts.diff, c.opts.diffColored, c.opts.stdin)
if err != nil {
return fmt.Errorf("build walk options: %w", err)
}
c.runner = goformat.NewRunner(c.log, metaFormatter, matcher, opts)
return nil
}
func (c *fmtCommand) execute(_ *cobra.Command, args []string) error {
paths := cleanArgs(args)
c.log.Infof("Formatting Go files...")
err := c.runner.Run(paths)
if err != nil {
return fmt.Errorf("failed to process files: %w", err)
}
return nil
}
func (c *fmtCommand) persistentPostRun(_ *cobra.Command, _ []string) {
if c.runner.ExitCode() != 0 {
os.Exit(c.runner.ExitCode())
}
}
func cleanArgs(args []string) []string {
if len(args) == 0 {
return []string{"."}
}
var expanded []string
for _, arg := range args {
expanded = append(expanded, filepath.Clean(strings.ReplaceAll(arg, "...", "")))
}
return expanded
}
================================================
FILE: pkg/commands/formatters.go
================================================
package commands
import (
"encoding/json"
"fmt"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type formattersHelp struct {
Enabled []formatterHelp
Disabled []formatterHelp
}
type formattersOptions struct {
config.LoaderOptions
JSON bool
}
type formattersCommand struct {
viper *viper.Viper
cmd *cobra.Command
opts formattersOptions
cfg *config.Config
log logutils.Log
dbManager *lintersdb.Manager
}
func newFormattersCommand(logger logutils.Log) *formattersCommand {
c := &formattersCommand{
viper: viper.New(),
cfg: config.NewDefault(),
log: logger,
}
formattersCmd := &cobra.Command{
Use: "formatters",
Short: "List current formatters configuration.",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
RunE: c.execute,
PreRunE: c.preRunE,
SilenceUsage: true,
}
fs := formattersCmd.Flags()
fs.SortFlags = false // sort them as they are defined here
setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
setupFormattersFlagSet(c.viper, fs)
fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
c.cmd = formattersCmd
return c
}
func (c *formattersCommand) preRunE(cmd *cobra.Command, args []string) error {
loader := config.NewFormattersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
err := loader.Load(config.LoadOptions{Validation: true})
if err != nil {
return fmt.Errorf("can't load config: %w", err)
}
dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg,
lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log))
if err != nil {
return err
}
c.dbManager = dbManager
return nil
}
func (c *formattersCommand) execute(_ *cobra.Command, _ []string) error {
enabledLintersMap, err := c.dbManager.GetEnabledLintersMap()
if err != nil {
return fmt.Errorf("can't get enabled formatters: %w", err)
}
var enabledFormatters []*linter.Config
var disabledFormatters []*linter.Config
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
if lc.Internal {
continue
}
if !goformatters.IsFormatter(lc.Name()) {
continue
}
if enabledLintersMap[lc.Name()] == nil {
disabledFormatters = append(disabledFormatters, lc)
} else {
enabledFormatters = append(enabledFormatters, lc)
}
}
if c.opts.JSON {
formatters := formattersHelp{}
for _, lc := range enabledFormatters {
formatters.Enabled = append(formatters.Enabled, newFormatterHelp(lc))
}
for _, lc := range disabledFormatters {
formatters.Disabled = append(formatters.Disabled, newFormatterHelp(lc))
}
return json.NewEncoder(c.cmd.OutOrStdout()).Encode(formatters)
}
color.Green("Enabled by your configuration formatters:\n")
printFormatters(enabledFormatters)
color.Red("\nDisabled by your configuration formatters:\n")
printFormatters(disabledFormatters)
return nil
}
================================================
FILE: pkg/commands/help.go
================================================
package commands
import (
"strings"
"unicode"
"unicode/utf8"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type helpOptions struct {
JSON bool
}
type helpCommand struct {
cmd *cobra.Command
opts helpOptions
dbManager *lintersdb.Manager
log logutils.Log
}
func newHelpCommand(logger logutils.Log) *helpCommand {
c := &helpCommand{log: logger}
helpCmd := &cobra.Command{
Use: "help",
Short: "Display extra help",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return cmd.Help()
},
}
lintersCmd := &cobra.Command{
Use: "linters",
Short: "Display help for linters.",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
RunE: c.lintersExecute,
PreRunE: c.lintersPreRunE,
}
fsLinter := lintersCmd.Flags()
fsLinter.SortFlags = false // sort them as they are defined here
fsLinter.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
helpCmd.AddCommand(lintersCmd)
formattersCmd := &cobra.Command{
Use: "formatters",
Short: "Display help for formatters.",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
RunE: c.formattersExecute,
PreRunE: c.formattersPreRunE,
}
fsFormatter := formattersCmd.Flags()
fsFormatter.SortFlags = false // sort them as they are defined here
fsFormatter.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
helpCmd.AddCommand(formattersCmd)
c.cmd = helpCmd
return c
}
func formatDescription(desc string) string {
desc = strings.TrimSpace(desc)
if desc == "" {
return desc
}
// If the linter description spans multiple lines, truncate everything following the first newline
endFirstLine := strings.IndexRune(desc, '\n')
if endFirstLine > 0 {
desc = desc[:endFirstLine]
}
rawDesc := []rune(desc)
r, _ := utf8.DecodeRuneInString(desc)
rawDesc[0] = unicode.ToUpper(r)
if rawDesc[len(rawDesc)-1] != '.' {
rawDesc = append(rawDesc, '.')
}
return string(rawDesc)
}
================================================
FILE: pkg/commands/help_formatters.go
================================================
package commands
import (
"encoding/json"
"fmt"
"slices"
"strings"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type formatterHelp struct {
Name string `json:"name"`
Desc string `json:"description"`
Deprecated bool `json:"deprecated"`
Since string `json:"since"`
OriginalURL string `json:"originalURL,omitempty"`
}
func newFormatterHelp(lc *linter.Config) formatterHelp {
return formatterHelp{
Name: lc.Name(),
Desc: formatDescription(lc.Linter.Desc()),
Deprecated: lc.IsDeprecated(),
Since: lc.Since,
OriginalURL: lc.OriginalURL,
}
}
func (c *helpCommand) formattersPreRunE(_ *cobra.Command, _ []string) error {
// The command doesn't depend on the real configuration.
dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), config.NewDefault(), lintersdb.NewLinterBuilder())
if err != nil {
return err
}
c.dbManager = dbManager
return nil
}
func (c *helpCommand) formattersExecute(_ *cobra.Command, _ []string) error {
if c.opts.JSON {
return c.formattersPrintJSON()
}
c.formattersPrint()
return nil
}
func (c *helpCommand) formattersPrintJSON() error {
var formatters []formatterHelp
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
if lc.Internal {
continue
}
if !goformatters.IsFormatter(lc.Name()) {
continue
}
formatters = append(formatters, newFormatterHelp(lc))
}
return json.NewEncoder(c.cmd.OutOrStdout()).Encode(formatters)
}
func (c *helpCommand) formattersPrint() {
var lcs []*linter.Config
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
if lc.Internal {
continue
}
if !goformatters.IsFormatter(lc.Name()) {
continue
}
lcs = append(lcs, lc)
}
color.Green("Disabled by default formatters:\n")
printFormatters(lcs)
}
func printFormatters(lcs []*linter.Config) {
slices.SortFunc(lcs, func(a, b *linter.Config) int {
if a.IsDeprecated() && b.IsDeprecated() {
return strings.Compare(a.Name(), b.Name())
}
if a.IsDeprecated() {
return 1
}
if b.IsDeprecated() {
return -1
}
return strings.Compare(a.Name(), b.Name())
})
for _, lc := range lcs {
desc := formatDescription(lc.Linter.Desc())
deprecatedMark := ""
if lc.IsDeprecated() {
deprecatedMark = " [" + color.RedString("deprecated") + "]"
}
_, _ = fmt.Fprintf(logutils.StdOut, "%s%s: %s\n",
color.YellowString(lc.Name()), deprecatedMark, desc)
}
}
================================================
FILE: pkg/commands/help_linters.go
================================================
package commands
import (
"encoding/json"
"fmt"
"maps"
"slices"
"strings"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type linterHelp struct {
Name string `json:"name"`
Desc string `json:"description"`
Groups []string `json:"groups"`
Fast bool `json:"fast"`
AutoFix bool `json:"autoFix"`
Deprecated bool `json:"deprecated"`
Since string `json:"since"`
OriginalURL string `json:"originalURL,omitempty"`
}
func newLinterHelp(lc *linter.Config) linterHelp {
groups := []string{config.GroupAll}
if !lc.IsSlowLinter() {
groups = append(groups, config.GroupFast)
}
return linterHelp{
Name: lc.Name(),
Desc: formatDescription(lc.Linter.Desc()),
Groups: slices.Concat(groups, slices.Collect(maps.Keys(lc.Groups))),
Fast: !lc.IsSlowLinter(),
AutoFix: lc.CanAutoFix,
Deprecated: lc.IsDeprecated(),
Since: lc.Since,
OriginalURL: lc.OriginalURL,
}
}
func (c *helpCommand) lintersPreRunE(_ *cobra.Command, _ []string) error {
// The command doesn't depend on the real configuration.
dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), config.NewDefault(), lintersdb.NewLinterBuilder())
if err != nil {
return err
}
c.dbManager = dbManager
return nil
}
func (c *helpCommand) lintersExecute(_ *cobra.Command, _ []string) error {
if c.opts.JSON {
return c.lintersPrintJSON()
}
c.lintersPrint()
return nil
}
func (c *helpCommand) lintersPrintJSON() error {
var linters []linterHelp
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
if lc.Internal {
continue
}
if goformatters.IsFormatter(lc.Name()) {
continue
}
linters = append(linters, newLinterHelp(lc))
}
return json.NewEncoder(c.cmd.OutOrStdout()).Encode(linters)
}
func (c *helpCommand) lintersPrint() {
var enabledLCs, disabledLCs []*linter.Config
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
if lc.Internal {
continue
}
if goformatters.IsFormatter(lc.Name()) {
continue
}
if lc.FromGroup(config.GroupStandard) {
enabledLCs = append(enabledLCs, lc)
} else {
disabledLCs = append(disabledLCs, lc)
}
}
color.Green("Enabled by default linters:\n")
printLinters(enabledLCs)
color.Red("\nDisabled by default linters:\n")
printLinters(disabledLCs)
}
func printLinters(lcs []*linter.Config) {
slices.SortFunc(lcs, func(a, b *linter.Config) int {
if a.IsDeprecated() && b.IsDeprecated() {
return strings.Compare(a.Name(), b.Name())
}
if a.IsDeprecated() {
return 1
}
if b.IsDeprecated() {
return -1
}
return strings.Compare(a.Name(), b.Name())
})
for _, lc := range lcs {
desc := formatDescription(lc.Linter.Desc())
deprecatedMark := ""
if lc.IsDeprecated() {
deprecatedMark = " [" + color.RedString("deprecated") + "]"
}
var capabilities []string
if !lc.IsSlowLinter() {
capabilities = append(capabilities, color.BlueString("fast"))
}
if lc.CanAutoFix {
capabilities = append(capabilities, color.GreenString("auto-fix"))
}
var capability string
if capabilities != nil {
capability = " [" + strings.Join(capabilities, ", ") + "]"
}
_, _ = fmt.Fprintf(logutils.StdOut, "%s%s: %s%s\n",
color.YellowString(lc.Name()), deprecatedMark, desc, capability)
}
}
================================================
FILE: pkg/commands/help_test.go
================================================
package commands
import (
"testing"
"github.com/stretchr/testify/assert"
)
func Test_formatDescription(t *testing.T) {
testCases := []struct {
desc string
doc string
expected string
}{
{
desc: "empty description",
doc: "",
expected: "",
},
{
desc: "simple description",
doc: "this is a test",
expected: "This is a test.",
},
{
desc: "formatted description",
doc: "This is a test.",
expected: "This is a test.",
},
{
desc: "multiline description",
doc: "this is a test\nanother line\n",
expected: "This is a test.",
},
{
desc: "leading newline",
doc: "\nThis is a test.",
expected: "This is a test.",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
v := formatDescription(test.doc)
assert.Equal(t, test.expected, v)
})
}
}
================================================
FILE: pkg/commands/internal/builder.go
================================================
package internal
import (
"context"
"crypto/sha256"
"encoding/base64"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"
"unicode"
"golang.org/x/mod/sumdb/dirhash"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
// Builder runs all the required commands to build a binary.
type Builder struct {
cfg *Configuration
log logutils.Log
root string
repo string
}
// NewBuilder creates a new Builder.
func NewBuilder(logger logutils.Log, cfg *Configuration, root string) *Builder {
return &Builder{
cfg: cfg,
log: logger,
root: root,
repo: filepath.Join(root, "golangci-lint"),
}
}
// Build builds the custom binary.
func (b Builder) Build(ctx context.Context) error {
b.log.Infof("Cloning golangci-lint repository")
err := b.clone(ctx)
if err != nil {
return fmt.Errorf("clone golangci-lint: %w", err)
}
b.log.Infof("Adding plugin imports")
err = b.updatePluginsFile()
if err != nil {
return fmt.Errorf("update plugin file: %w", err)
}
b.log.Infof("Adding replace directives")
err = b.addToGoMod(ctx)
if err != nil {
return fmt.Errorf("add to go.mod: %w", err)
}
b.log.Infof("Running go mod tidy")
err = b.goModTidy(ctx)
if err != nil {
return fmt.Errorf("go mod tidy: %w", err)
}
b.log.Infof("Building golangci-lint binary")
binaryName := b.getBinaryName()
err = b.goBuild(ctx, binaryName)
if err != nil {
return fmt.Errorf("build golangci-lint binary: %w", err)
}
b.log.Infof("Moving golangci-lint binary")
err = b.copyBinary(binaryName)
if err != nil {
return fmt.Errorf("move golangci-lint binary: %w", err)
}
return nil
}
func (b Builder) clone(ctx context.Context) error {
//nolint:gosec // the variable is sanitized.
cmd := exec.CommandContext(ctx,
"git", "clone", "--branch", sanitizeVersion(b.cfg.Version),
"--single-branch", "--depth", "1", "-c", "advice.detachedHead=false", "-q",
"https://github.com/golangci/golangci-lint.git",
)
cmd.Dir = b.root
output, err := cmd.CombinedOutput()
if err != nil {
b.log.Infof("%s", string(output))
return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err)
}
return nil
}
func (b Builder) addToGoMod(ctx context.Context) error {
for _, plugin := range b.cfg.Plugins {
if plugin.Path != "" {
err := b.addReplaceDirective(ctx, plugin)
if err != nil {
return err
}
continue
}
err := b.goGet(ctx, plugin)
if err != nil {
return err
}
}
return nil
}
func (b Builder) goGet(ctx context.Context, plugin *Plugin) error {
//nolint:gosec // the variables are user related.
cmd := exec.CommandContext(ctx, "go", "get", plugin.Module+"@"+plugin.Version)
cmd.Dir = b.repo
b.log.Infof("run: %s", strings.Join(cmd.Args, " "))
output, err := cmd.CombinedOutput()
if err != nil {
b.log.Warnf("%s", string(output))
return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err)
}
return nil
}
func (b Builder) addReplaceDirective(ctx context.Context, plugin *Plugin) error {
replace := fmt.Sprintf("%s=%s", plugin.Module, plugin.Path)
cmd := exec.CommandContext(ctx, "go", "mod", "edit", "-replace", replace)
cmd.Dir = b.repo
b.log.Infof("run: %s", strings.Join(cmd.Args, " "))
output, err := cmd.CombinedOutput()
if err != nil {
b.log.Warnf("%s", string(output))
return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err)
}
return nil
}
func (b Builder) goModTidy(ctx context.Context) error {
cmd := exec.CommandContext(ctx, "go", "mod", "tidy")
cmd.Dir = b.repo
output, err := cmd.CombinedOutput()
if err != nil {
b.log.Warnf("%s", string(output))
return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err)
}
return nil
}
func (b Builder) goBuild(ctx context.Context, binaryName string) error {
version, err := b.createVersion(b.cfg.Version)
if err != nil {
return fmt.Errorf("custom version: %w", err)
}
b.log.Infof("version: %s", version)
//nolint:gosec // the variable is sanitized.
cmd := exec.CommandContext(ctx, "go", "build",
"-ldflags",
fmt.Sprintf("-s -w -X 'main.version=%s' -X 'main.date=%s'", version, time.Now().UTC().String()),
"-o", binaryName,
"./cmd/golangci-lint",
)
cmd.Dir = b.repo
output, err := cmd.CombinedOutput()
if err != nil {
b.log.Warnf("%s", string(output))
return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err)
}
return nil
}
func (b Builder) copyBinary(binaryName string) error {
src := filepath.Join(b.repo, binaryName)
source, err := os.Open(filepath.Clean(src))
if err != nil {
return fmt.Errorf("open source file: %w", err)
}
defer func() { _ = source.Close() }()
info, err := source.Stat()
if err != nil {
return fmt.Errorf("stat source file: %w", err)
}
if b.cfg.Destination != "" {
err = os.MkdirAll(b.cfg.Destination, os.ModePerm)
if err != nil {
return fmt.Errorf("create destination directory: %w", err)
}
}
dst, err := os.OpenFile(filepath.Join(b.cfg.Destination, binaryName), os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode())
if err != nil {
return fmt.Errorf("create destination file: %w", err)
}
defer func() { _ = dst.Close() }()
_, err = io.Copy(dst, source)
if err != nil {
return fmt.Errorf("copy source to destination: %w", err)
}
return nil
}
func (b Builder) getBinaryName() string {
name := b.cfg.Name
if runtime.GOOS == "windows" {
name += ".exe"
}
return name
}
func (b Builder) createVersion(orig string) (string, error) {
hash := sha256.New()
for _, plugin := range b.cfg.Plugins {
if plugin.Path == "" {
continue
}
dh, err := hashDir(plugin.Path, "", dirhash.DefaultHash)
if err != nil {
return "", fmt.Errorf("hash plugin directory: %w", err)
}
b.log.Infof("%s: %s", plugin.Path, dh)
hash.Write([]byte(dh))
}
return fmt.Sprintf("%s-custom-gcl-%s",
sanitizeVersion(orig),
sanitizeVersion(base64.URLEncoding.EncodeToString(hash.Sum(nil))),
), nil
}
func sanitizeVersion(v string) string {
fn := func(c rune) bool {
return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '.' && c != '/'
}
return strings.Join(strings.FieldsFunc(v, fn), "")
}
================================================
FILE: pkg/commands/internal/builder_test.go
================================================
package internal
import (
"testing"
"github.com/stretchr/testify/assert"
)
func Test_sanitizeVersion(t *testing.T) {
testCases := []struct {
desc string
input string
expected string
}{
{
desc: "ampersand",
input: " te&st",
expected: "test",
},
{
desc: "pipe",
input: " te|st",
expected: "test",
},
{
desc: "version",
input: "v1.2.3",
expected: "v1.2.3",
},
{
desc: "branch",
input: "feat/test",
expected: "feat/test",
},
{
desc: "branch",
input: "value --key",
expected: "valuekey",
},
{
desc: "hash",
input: "cd8b1177",
expected: "cd8b1177",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
v := sanitizeVersion(test.input)
assert.Equal(t, test.expected, v)
})
}
}
================================================
FILE: pkg/commands/internal/configuration.go
================================================
package internal
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"go.yaml.in/yaml/v3"
)
const base = ".custom-gcl"
const defaultBinaryName = "custom-gcl"
// Configuration represents the configuration file.
type Configuration struct {
// golangci-lint version.
Version string `yaml:"version"`
// Name of the binary.
Name string `yaml:"name,omitempty"`
// Destination is the path to a directory to store the binary.
Destination string `yaml:"destination,omitempty"`
// Plugins information.
Plugins []*Plugin `yaml:"plugins,omitempty"`
}
// Validate checks and clean the configuration.
func (c *Configuration) Validate() error {
if strings.TrimSpace(c.Version) == "" {
return errors.New("root field 'version' is required")
}
if strings.TrimSpace(c.Name) == "" {
c.Name = defaultBinaryName
}
if len(c.Plugins) == 0 {
return errors.New("no plugins defined")
}
for _, plugin := range c.Plugins {
if strings.TrimSpace(plugin.Module) == "" {
return errors.New("field 'module' is required")
}
if strings.TrimSpace(plugin.Import) == "" {
plugin.Import = plugin.Module
}
if strings.TrimSpace(plugin.Path) == "" && strings.TrimSpace(plugin.Version) == "" {
return errors.New("missing information: 'version' or 'path' should be provided")
}
if strings.TrimSpace(plugin.Path) != "" && strings.TrimSpace(plugin.Version) != "" {
return errors.New("invalid configuration: 'version' and 'path' should not be provided at the same time")
}
if strings.TrimSpace(plugin.Path) == "" {
continue
}
abs, err := filepath.Abs(plugin.Path)
if err != nil {
return err
}
plugin.Path = abs
}
return nil
}
// Plugin represents information about a plugin.
type Plugin struct {
// Module name.
Module string `yaml:"module"`
// Import to use.
Import string `yaml:"import,omitempty"`
// Version of the module.
// Only for module available through a Go proxy.
Version string `yaml:"version,omitempty"`
// Path to the local module.
// Only for local module.
Path string `yaml:"path,omitempty"`
}
func LoadConfiguration() (*Configuration, error) {
configFilePath, err := findConfigurationFile()
if err != nil {
return nil, fmt.Errorf("file %s not found: %w", configFilePath, err)
}
file, err := os.Open(configFilePath)
if err != nil {
return nil, fmt.Errorf("file %s open: %w", configFilePath, err)
}
defer func() { _ = file.Close() }()
var cfg Configuration
err = yaml.NewDecoder(file).Decode(&cfg)
if err != nil {
return nil, fmt.Errorf("YAML decoding: %w", err)
}
return &cfg, nil
}
func findConfigurationFile() (string, error) {
entries, err := os.ReadDir(".")
if err != nil {
return "", fmt.Errorf("read directory: %w", err)
}
for _, entry := range entries {
ext := filepath.Ext(entry.Name())
switch strings.ToLower(strings.TrimPrefix(ext, ".")) {
case "yml", "yaml", "json":
if isConf(ext, entry.Name()) {
return entry.Name(), nil
}
}
}
return "", errors.New("configuration file not found")
}
func isConf(ext, name string) bool {
return base+ext == name
}
================================================
FILE: pkg/commands/internal/configuration_test.go
================================================
package internal
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestConfiguration_Validate(t *testing.T) {
testCases := []struct {
desc string
cfg *Configuration
}{
{
desc: "version",
cfg: &Configuration{
Version: "v1.57.0",
Plugins: []*Plugin{
{
Module: "example.org/foo/bar",
Import: "example.org/foo/bar/test",
Version: "v1.2.3",
},
},
},
},
{
desc: "path",
cfg: &Configuration{
Version: "v1.57.0",
Plugins: []*Plugin{
{
Module: "example.org/foo/bar",
Import: "example.org/foo/bar/test",
Path: "/my/path",
},
},
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.cfg.Validate()
require.NoError(t, err)
})
}
}
func TestConfiguration_Validate_error(t *testing.T) {
testCases := []struct {
desc string
cfg *Configuration
expected string
}{
{
desc: "missing version",
cfg: &Configuration{},
expected: "root field 'version' is required",
},
{
desc: "no plugins",
cfg: &Configuration{
Version: "v1.57.0",
},
expected: "no plugins defined",
},
{
desc: "missing module",
cfg: &Configuration{
Version: "v1.57.0",
Plugins: []*Plugin{
{
Module: "",
Import: "example.org/foo/bar/test",
Version: "v1.2.3",
Path: "/my/path",
},
},
},
expected: "field 'module' is required",
},
{
desc: "module version and path",
cfg: &Configuration{
Version: "v1.57.0",
Plugins: []*Plugin{
{
Module: "example.org/foo/bar",
Import: "example.org/foo/bar/test",
Version: "v1.2.3",
Path: "/my/path",
},
},
},
expected: "invalid configuration: 'version' and 'path' should not be provided at the same time",
},
{
desc: "no module version and path",
cfg: &Configuration{
Version: "v1.57.0",
Plugins: []*Plugin{
{
Module: "example.org/foo/bar",
Import: "example.org/foo/bar/test",
},
},
},
expected: "missing information: 'version' or 'path' should be provided",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.cfg.Validate()
assert.EqualError(t, err, test.expected)
})
}
}
================================================
FILE: pkg/commands/internal/dirhash.go
================================================
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package internal
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"golang.org/x/mod/sumdb/dirhash"
)
// Slightly modified copy of [dirhash.HashDir].
// https://github.com/golang/mod/blob/v0.28.0/sumdb/dirhash/hash.go#L67-L79
func hashDir(dir, prefix string, hash dirhash.Hash) (string, error) {
files, err := dirFiles(dir, prefix)
if err != nil {
return "", err
}
osOpen := func(name string) (io.ReadCloser, error) {
return os.Open(filepath.Join(dir, strings.TrimPrefix(name, prefix)))
}
return hash(files, osOpen)
}
// Modified copy of [dirhash.DirFiles].
// https://github.com/golang/mod/blob/v0.28.0/sumdb/dirhash/hash.go#L81-L109
// And adapted to globally follows the rules from https://github.com/golang/mod/blob/v0.28.0/zip/zip.go
func dirFiles(dir, prefix string) ([]string, error) {
var files []string
dir = filepath.Clean(dir)
err := filepath.Walk(dir, func(file string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
if dir == file {
// Don't skip the top-level directory.
return nil
}
switch info.Name() {
// Skip vendor and node directories.
case "vendor", "node_modules":
return filepath.SkipDir
// Skip VCS directories.
case ".bzr", ".git", ".hg", ".svn":
return filepath.SkipDir
}
// Skip submodules (directories containing go.mod files).
if goModInfo, err := os.Lstat(filepath.Join(dir, "go.mod")); err == nil && !goModInfo.IsDir() {
return filepath.SkipDir
}
return nil
}
if file == dir {
return fmt.Errorf("%s is not a directory", dir)
}
if !info.Mode().IsRegular() {
return nil
}
rel := file
if dir != "." {
rel = file[len(dir)+1:]
}
f := filepath.Join(prefix, rel)
files = append(files, filepath.ToSlash(f))
return nil
})
if err != nil {
return nil, err
}
return files, nil
}
================================================
FILE: pkg/commands/internal/imports.go
================================================
package internal
import (
"bytes"
"fmt"
"go/format"
"os"
"path/filepath"
"text/template"
)
const importsTemplate = `
package main
import (
{{range .Imports -}}
_ "{{.}}"
{{end -}}
)
`
func (b Builder) updatePluginsFile() error {
importsDest := filepath.Join(b.repo, "cmd", "golangci-lint", "plugins.go")
info, err := os.Stat(importsDest)
if err != nil {
return fmt.Errorf("file %s not found: %w", importsDest, err)
}
source, err := generateImports(b.cfg)
if err != nil {
return fmt.Errorf("generate imports: %w", err)
}
b.log.Infof("generated imports info %s:\n%s\n", importsDest, source)
err = os.WriteFile(filepath.Clean(importsDest), source, info.Mode())
if err != nil {
return fmt.Errorf("write file %s: %w", importsDest, err)
}
return nil
}
func generateImports(cfg *Configuration) ([]byte, error) {
impTmpl, err := template.New("plugins.go").Parse(importsTemplate)
if err != nil {
return nil, fmt.Errorf("parse template: %w", err)
}
var imps []string
for _, plugin := range cfg.Plugins {
imps = append(imps, plugin.Import)
}
buf := &bytes.Buffer{}
err = impTmpl.Execute(buf, map[string]any{"Imports": imps})
if err != nil {
return nil, fmt.Errorf("execute template: %w", err)
}
source, err := format.Source(buf.Bytes())
if err != nil {
return nil, fmt.Errorf("format source: %w", err)
}
return source, nil
}
================================================
FILE: pkg/commands/internal/imports_test.go
================================================
package internal
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_generateImports(t *testing.T) {
cfg := &Configuration{
Version: "v1.57.0",
Plugins: []*Plugin{
{
Module: "example.org/foo/bar",
Import: "example.org/foo/bar/test",
Version: "v1.2.3",
},
{
Module: "example.com/foo/bar",
Import: "example.com/foo/bar/test",
Path: "/my/path",
},
},
}
data, err := generateImports(cfg)
require.NoError(t, err)
expected, err := os.ReadFile(filepath.Join("testdata", "imports.go"))
require.NoError(t, err)
assert.Equal(t, expected, data)
}
================================================
FILE: pkg/commands/internal/migrate/cloner/cloner.go
================================================
package main
import (
"bytes"
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"log"
"os"
"path/filepath"
"reflect"
"strings"
"golang.org/x/tools/imports"
)
const newPkgName = "versiontwo"
const (
srcDir = "./pkg/config"
dstDir = "./pkg/commands/internal/migrate/versiontwo"
)
func main() {
stat, err := os.Stat(srcDir)
if err != nil {
log.Fatal(err)
}
if !stat.IsDir() {
log.Fatalf("%s is not a directory", srcDir)
}
_ = os.RemoveAll(dstDir)
err = processPackage(srcDir, dstDir)
if err != nil {
log.Fatalf("Processing package error: %v", err)
}
}
func processPackage(srcDir, dstDir string) error {
return filepath.Walk(srcDir, func(srcPath string, _ os.FileInfo, err error) error {
if err != nil {
return err
}
if skipFile(srcPath) {
return nil
}
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, srcPath, nil, parser.AllErrors)
if err != nil {
return fmt.Errorf("parsing %s: %w", srcPath, err)
}
processFile(file)
return writeNewFile(fset, file, srcPath, dstDir)
})
}
func skipFile(path string) bool {
if !strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "_test.go") {
return true
}
switch filepath.Base(path) {
case "base_loader.go", "loader.go":
return true
default:
return false
}
}
func processFile(file *ast.File) {
file.Name.Name = newPkgName
var newDecls []ast.Decl
for _, decl := range file.Decls {
d, ok := decl.(*ast.GenDecl)
if !ok {
continue
}
switch d.Tok {
case token.CONST, token.VAR:
continue
case token.TYPE:
for _, spec := range d.Specs {
typeSpec, ok := spec.(*ast.TypeSpec)
if !ok {
continue
}
structType, ok := typeSpec.Type.(*ast.StructType)
if !ok {
continue
}
processStructFields(structType)
}
default:
// noop
}
newDecls = append(newDecls, decl)
}
file.Decls = newDecls
}
func processStructFields(structType *ast.StructType) {
var newFields []*ast.Field
for _, field := range structType.Fields.List {
if len(field.Names) > 0 && !field.Names[0].IsExported() {
continue
}
if field.Tag == nil {
continue
}
field.Type = convertType(field.Type)
field.Tag.Value = convertStructTag(field.Tag.Value)
newFields = append(newFields, field)
}
structType.Fields.List = newFields
}
func convertType(expr ast.Expr) ast.Expr {
ident, ok := expr.(*ast.Ident)
if !ok {
return expr
}
switch ident.Name {
case "bool", "string", "uint", "uint8", "uint16", "uint32", "uint64", "int", "int8", "int16", "int32", "int64", "float32", "float64":
return &ast.StarExpr{X: ident}
default:
return expr
}
}
func convertStructTag(value string) string {
structTag := reflect.StructTag(strings.Trim(value, "`"))
key := structTag.Get("mapstructure")
if key == ",squash" {
return wrapStructTag(`yaml:",inline"`)
}
return wrapStructTag(fmt.Sprintf(`yaml:"%[1]s,omitempty" toml:"%[1]s,multiline,omitempty"`, key))
}
func wrapStructTag(s string) string {
return "`" + s + "`"
}
func writeNewFile(fset *token.FileSet, file *ast.File, srcPath, dstDir string) error {
var buf bytes.Buffer
buf.WriteString("// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.\n\n")
err := printer.Fprint(&buf, fset, file)
if err != nil {
return fmt.Errorf("printing %s: %w", srcPath, err)
}
dstPath := filepath.Join(dstDir, filepath.Base(srcPath))
_ = os.MkdirAll(filepath.Dir(dstPath), os.ModePerm)
formatted, err := imports.Process(dstPath, buf.Bytes(), nil)
if err != nil {
return fmt.Errorf("formatting %s: %w", dstPath, err)
}
//nolint:gosec,mnd // The permission is right.
err = os.WriteFile(dstPath, formatted, 0o644)
if err != nil {
return fmt.Errorf("writing file %s: %w", dstPath, err)
}
return nil
}
================================================
FILE: pkg/commands/internal/migrate/fakeloader/config.go
================================================
package fakeloader
// Config implements [config.BaseConfig].
// This only the stub for the real file loader.
type Config struct {
Version string `mapstructure:"version"`
cfgDir string // Path to the directory containing golangci-lint config file.
}
func NewConfig() *Config {
return &Config{}
}
// SetConfigDir sets the path to directory that contains golangci-lint config file.
func (c *Config) SetConfigDir(dir string) {
c.cfgDir = dir
}
func (*Config) IsInternalTest() bool {
return false
}
================================================
FILE: pkg/commands/internal/migrate/fakeloader/fakeloader.go
================================================
package fakeloader
import (
"fmt"
"os"
"github.com/go-viper/mapstructure/v2"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
// Load is used to keep case of configuration.
// Viper serialize raw map keys in lowercase, this is a problem with the configuration of some linters.
func Load(srcPath string, old any) error {
file, err := os.Open(srcPath)
if err != nil {
return fmt.Errorf("open file: %w", err)
}
defer func() { _ = file.Close() }()
raw := map[string]any{}
err = parser.Decode(file, raw)
if err != nil {
return err
}
// NOTE: this is inspired by viper internals.
cc := &mapstructure.DecoderConfig{
Result: old,
WeaklyTypedInput: true,
DecodeHook: config.DecodeHookFunc(),
}
decoder, err := mapstructure.NewDecoder(cc)
if err != nil {
return fmt.Errorf("constructing mapstructure decoder: %w", err)
}
err = decoder.Decode(raw)
if err != nil {
return fmt.Errorf("decoding configuration file: %w", err)
}
return nil
}
================================================
FILE: pkg/commands/internal/migrate/migrate.go
================================================
package migrate
import (
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
)
func ToConfig(old *versionone.Config) *versiontwo.Config {
return &versiontwo.Config{
Version: ptr.Pointer("2"),
Linters: toLinters(old),
Formatters: toFormatters(old),
Issues: toIssues(old),
Output: toOutput(old),
Severity: toSeverity(old),
Run: toRun(old),
}
}
================================================
FILE: pkg/commands/internal/migrate/migrate_formatters.go
================================================
package migrate
import (
"slices"
"strings"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
)
func toFormatters(old *versionone.Config) versiontwo.Formatters {
enable := ProcessEffectiveFormatters(old.Linters)
var paths []string
if len(enable) > 0 {
paths = slices.Concat(old.Issues.ExcludeFiles, old.Issues.ExcludeDirs)
}
if old.Issues.UseDefaultExcludeDirs == nil || ptr.Deref(old.Issues.UseDefaultExcludeDirs) {
paths = append(paths, "third_party$", "builtin$", "examples$")
}
paths = append(paths, toFormattersPathsFromRules(old.Issues)...)
return versiontwo.Formatters{
Enable: enable,
Settings: versiontwo.FormatterSettings{
Gci: toGciSettings(old.LintersSettings.Gci),
GoFmt: toGoFmtSettings(old.LintersSettings.GoFmt),
GoFumpt: toGoFumptSettings(old.LintersSettings.GoFumpt),
GoImports: toGoImportsSettings(old.LintersSettings.GoImports),
},
Exclusions: versiontwo.FormatterExclusions{
Generated: toExclusionGenerated(old.Issues.ExcludeGenerated),
Paths: paths,
},
}
}
func toFormattersPathsFromRules(old versionone.Issues) []string {
var results []string
for _, rule := range old.ExcludeRules {
allNames := convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters))
names := onlyFormatterNames(allNames)
if len(names) == 0 {
continue
}
if ptr.Deref(rule.Path) == "" {
continue
}
results = append(results, ptr.Deref(rule.Path))
}
return results
}
func toGciSettings(old versionone.GciSettings) versiontwo.GciSettings {
return versiontwo.GciSettings{
Sections: old.Sections,
NoInlineComments: old.NoInlineComments,
NoPrefixComments: old.NoPrefixComments,
CustomOrder: old.CustomOrder,
NoLexOrder: old.NoLexOrder,
}
}
func toGoFmtSettings(old versionone.GoFmtSettings) versiontwo.GoFmtSettings {
settings := versiontwo.GoFmtSettings{
Simplify: old.Simplify,
}
for _, rule := range old.RewriteRules {
settings.RewriteRules = append(settings.RewriteRules, versiontwo.GoFmtRewriteRule{
Pattern: rule.Pattern,
Replacement: rule.Replacement,
})
}
return settings
}
func toGoFumptSettings(old versionone.GoFumptSettings) versiontwo.GoFumptSettings {
return versiontwo.GoFumptSettings{
ModulePath: old.ModulePath,
ExtraRules: old.ExtraRules,
}
}
func toGoImportsSettings(old versionone.GoImportsSettings) versiontwo.GoImportsSettings {
var localPrefixes []string
prefixes := ptr.Deref(old.LocalPrefixes)
if prefixes != "" {
localPrefixes = strings.Split(prefixes, ",")
}
return versiontwo.GoImportsSettings{
LocalPrefixes: localPrefixes,
}
}
================================================
FILE: pkg/commands/internal/migrate/migrate_issues.go
================================================
package migrate
import (
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
)
func toIssues(old *versionone.Config) versiontwo.Issues {
return versiontwo.Issues{
MaxIssuesPerLinter: old.Issues.MaxIssuesPerLinter,
MaxSameIssues: old.Issues.MaxSameIssues,
UniqByLine: old.Issues.UniqByLine,
DiffFromRevision: old.Issues.DiffFromRevision,
DiffFromMergeBase: old.Issues.DiffFromMergeBase,
DiffPatchFilePath: old.Issues.DiffPatchFilePath,
WholeFiles: old.Issues.WholeFiles,
Diff: old.Issues.Diff,
NeedFix: old.Issues.NeedFix,
}
}
================================================
FILE: pkg/commands/internal/migrate/migrate_linter_names.go
================================================
package migrate
import (
"cmp"
"slices"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
)
type LinterInfo struct {
Name string `json:"name"`
Presets []string `json:"inPresets"`
Slow bool `json:"isSlow,omitempty"`
Default bool `json:"enabledByDefault,omitempty"`
AlternativeNames []string `json:"alternativeNames,omitempty"`
}
func (l *LinterInfo) isName(name string) bool {
if name == l.Name {
return true
}
return slices.Contains(l.AlternativeNames, name)
}
func (l *LinterInfo) hasPresets(names []string) bool {
for _, name := range names {
if slices.Contains(l.Presets, name) {
return true
}
}
return false
}
func ProcessEffectiveLinters(old versionone.Linters) (enable, disable []string) {
switch {
case ptr.Deref(old.DisableAll):
return disableAllFilter(old), nil
case ptr.Deref(old.EnableAll):
return nil, enableAllFilter(old)
default:
return defaultLintersFilter(old)
}
}
func ProcessEffectiveFormatters(old versionone.Linters) []string {
enabled, disabled := ProcessEffectiveLinters(old)
if ptr.Deref(old.EnableAll) {
var formatterNames []string
for _, f := range getAllFormatterNames() {
if !slices.Contains(disabled, f) {
formatterNames = append(formatterNames, f)
}
}
return formatterNames
}
return onlyFormatterNames(enabled)
}
// disableAllFilter generates the value of `enable` when `disable-all` is `true`.
func disableAllFilter(old versionone.Linters) []string {
// Note:
// - disable-all + enable-all
// => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L38)
// - disable-all + disable
// => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L47)
// if disable-all -> presets fast enable
// - presets fast enable: (presets - [slow]) + enable => effective enable + none
// - presets fast: presets - slow => effective enable + none
// - presets fast enable: presets + enable => effective enable + none
// - enable => effective enable + none
// - fast => nothing
// - fast enable: enable => effective enable + none
// (presets - [slow]) + enable => effective enable + none
names := toNames(
slices.Concat(
filter(
allLinters(), onlyPresets(old), keepFast(old), // presets - [slow]
),
allEnabled(old, allLinters()), // + enable
),
)
return slices.Concat(names, unknownLinterNames(old.Enable, allLinters()))
}
// enableAllFilter generates the value of `disable` when `enable-all` is `true`.
func enableAllFilter(old versionone.Linters) []string {
// Note:
// - enable-all + disable-all
// => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L38)
// - enable-all + enable + fast=false
// => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L52)
// - enable-all + enable + fast=true
// => possible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L51)
// if enable-all -> presets fast enable disable
// - presets fast enable disable: all - fast - enable + disable => effective disable + all
// - presets fast disable: all - fast + disable => effective disable + all
// - presets fast: all - fast => effective disable + all
// - presets disable: disable => effective disable + all
// - disable => effective disable + all
// - fast: all - fast => effective disable + all
// - fast disable: all - fast + disable => effective disable + all
// all - [fast] - enable + disable => effective disable + all
names := toNames(
slices.Concat(
removeLinters(
filter(
allLinters(), keepSlow(old), // all - fast
),
allEnabled(old, allLinters()), // - enable
),
allDisabled(old, allLinters()), // + disable
),
)
return slices.Concat(names, unknownLinterNames(old.Disable, allLinters()))
}
// defaultLintersFilter generates the values of `enable` and `disable` when using default linters.
func defaultLintersFilter(old versionone.Linters) (enable, disable []string) {
// Note:
// - a linter cannot be inside `enable` and `disable` in the same configuration
// => https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L66
// if default -> presets fast disable
// - presets > fast > disable > enable => effective enable + disable + standard
// - (default - fast) - enable + disable => effective disable
// - presets - slow + enable - default - [effective disable] => effective enable
// - presets + fast + disable => effective enable + disable + standard
// - (default - fast) + disable => effective disable
// - presets - slow - default - [effective disable] => effective enable
// - presets + fast + enable
// - (default - fast) - enable => effective disable
// - presets - slow + enable - default - [effective disable] => effective enable
// - presets + fast
// - (default - fast) => effective disable
// - presets - slow - default - [effective disable] => effective enable
// - presets + disable
// - default + disable => effective disable
// - presets - default - [effective disable] => effective enable
// - presets + enable
// - default - enable => effective disable
// - presets + enable - default - [effective disable] => effective enable
// - disable
// - default + disable => effective disable
// - default - [effective disable] => effective enable
// - enable
// - default - enable => effective disable
// - enable - default - [effective disable] => effective enable
// - fast
// - default - fast => effective disable
// - default - [effective disable] => effective enable
// - fast + disable
// - (default - fast) + disable => effective disable
// - default - [effective disable] => effective enable
// - fast + enable
// - (default - fast) - enable => effective disable
// - enable - default - [effective disable] => effective enable
disabledLinters := defaultLintersDisableFilter(old)
enabledLinters := defaultLintersEnableFilter(old, disabledLinters)
enabled := toNames(enabledLinters)
disabled := toNames(disabledLinters)
return slices.Concat(enabled, unknownLinterNames(old.Enable, allLinters())),
slices.Concat(disabled, unknownLinterNames(old.Disable, allLinters()))
}
// defaultLintersEnableFilter generates the value of `enable` when using default linters.
func defaultLintersEnableFilter(old versionone.Linters, effectiveDisabled []LinterInfo) []LinterInfo {
// presets - slow + enable - default - [effective disable] => effective enable
return removeLinters(
filter(
slices.Concat(
filter(
allLinters(), onlyPresets(old), keepFast(old), // presets - slow
),
allEnabled(old, allLinters()), // + enable
),
notDefault, // - default
),
effectiveDisabled, // - [effective disable]
)
}
// defaultLintersDisableFilter generates the value of `disable` when using default linters.
func defaultLintersDisableFilter(old versionone.Linters) []LinterInfo {
// (default - fast) - enable + disable => effective disable
return slices.Concat(
removeLinters(
filter(allLinters(), onlyDefault, keepSlow(old)), // (default - fast)
allEnabled(old, allLinters()), // - enable
),
allDisabled(old, allLinters()), // + disable
)
}
func allLinters() []LinterInfo {
return []LinterInfo{
{
Name: "asasalint",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "asciicheck",
Presets: []string{"bugs", "style"},
},
{
Name: "bidichk",
Presets: []string{"bugs"},
},
{
Name: "bodyclose",
Presets: []string{"performance", "bugs"},
Slow: true,
},
{
Name: "canonicalheader",
Presets: []string{"style"},
Slow: true,
},
{
Name: "containedctx",
Presets: []string{"style"},
Slow: true,
},
{
Name: "contextcheck",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "copyloopvar",
Presets: []string{"style"},
},
{
Name: "cyclop",
Presets: []string{"complexity"},
},
{
Name: "decorder",
Presets: []string{"style"},
},
{
Name: "depguard",
Presets: []string{"style", "import", "module"},
},
{
Name: "dogsled",
Presets: []string{"style"},
},
{
Name: "dupl",
Presets: []string{"style"},
},
{
Name: "dupword",
Presets: []string{"comment"},
},
{
Name: "durationcheck",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "errcheck",
Presets: []string{"bugs", "error"},
Slow: true,
Default: true,
},
{
Name: "errchkjson",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "errname",
Presets: []string{"style"},
Slow: true,
},
{
Name: "errorlint",
Presets: []string{"bugs", "error"},
Slow: true,
},
{
Name: "exhaustive",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "exhaustruct",
Presets: []string{"style", "test"},
Slow: true,
},
{
Name: "exptostd",
Presets: []string{"style"},
Slow: true,
},
{
Name: "forbidigo",
Presets: []string{"style"},
Slow: true,
},
{
Name: "forcetypeassert",
Presets: []string{"style"},
Slow: true,
},
{
Name: "fatcontext",
Presets: []string{"performance"},
Slow: true,
},
{
Name: "funlen",
Presets: []string{"complexity"},
},
{
Name: "gci",
Presets: []string{"format", "import"},
},
{
Name: "ginkgolinter",
Presets: []string{"style"},
Slow: true,
},
{
Name: "gocheckcompilerdirectives",
Presets: []string{"bugs"},
},
{
Name: "gochecknoglobals",
Presets: []string{"style"},
Slow: true,
},
{
Name: "gochecknoinits",
Presets: []string{"style"},
},
{
Name: "gochecksumtype",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "gocognit",
Presets: []string{"complexity"},
},
{
Name: "goconst",
Presets: []string{"style"},
},
{
Name: "gocritic",
Presets: []string{"style", "metalinter"},
Slow: true,
},
{
Name: "gocyclo",
Presets: []string{"complexity"},
},
{
Name: "godot",
Presets: []string{"style", "comment"},
},
{
Name: "godox",
Presets: []string{"style", "comment"},
},
{
Name: "err113",
Presets: []string{"style", "error"},
Slow: true,
AlternativeNames: []string{"goerr113"},
},
{
Name: "gofmt",
Presets: []string{"format"},
},
{
Name: "gofumpt",
Presets: []string{"format"},
},
{
Name: "goheader",
Presets: []string{"style"},
},
{
Name: "goimports",
Presets: []string{"format", "import"},
},
{
Name: "mnd",
Presets: []string{"style"},
AlternativeNames: []string{"gomnd"},
},
{
Name: "gomoddirectives",
Presets: []string{"style", "module"},
},
{
Name: "gomodguard",
Presets: []string{"style", "import", "module"},
},
{
Name: "goprintffuncname",
Presets: []string{"style"},
},
{
Name: "gosec",
Presets: []string{"bugs"},
Slow: true,
AlternativeNames: []string{"gas"},
},
{
Name: "gosimple",
Presets: []string{"style"},
Slow: true,
Default: true,
AlternativeNames: []string{"megacheck"},
},
{
Name: "gosmopolitan",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "govet",
Presets: []string{"bugs", "metalinter"},
Slow: true,
Default: true,
AlternativeNames: []string{"vet", "vetshadow"},
},
{
Name: "grouper",
Presets: []string{"style"},
},
{
Name: "iface",
Presets: []string{"style"},
Slow: true,
},
{
Name: "importas",
Presets: []string{"style"},
Slow: true,
},
{
Name: "inamedparam",
Presets: []string{"style"},
},
{
Name: "ineffassign",
Presets: []string{"unused"},
Default: true,
},
{
Name: "interfacebloat",
Presets: []string{"style"},
},
{
Name: "intrange",
Presets: []string{"style"},
Slow: true,
},
{
Name: "ireturn",
Presets: []string{"style"},
Slow: true,
},
{
Name: "lll",
Presets: []string{"style"},
},
{
Name: "loggercheck",
Presets: []string{"style", "bugs"},
Slow: true,
AlternativeNames: []string{"logrlint"},
},
{
Name: "maintidx",
Presets: []string{"complexity"},
},
{
Name: "makezero",
Presets: []string{"style", "bugs"},
Slow: true,
},
{
Name: "mirror",
Presets: []string{"style"},
Slow: true,
},
{
Name: "misspell",
Presets: []string{"style", "comment"},
},
{
Name: "musttag",
Presets: []string{"style", "bugs"},
Slow: true,
},
{
Name: "nakedret",
Presets: []string{"style"},
},
{
Name: "nestif",
Presets: []string{"complexity"},
},
{
Name: "nilerr",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "nilnesserr",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "nilnil",
Presets: []string{"style"},
Slow: true,
},
{
Name: "nlreturn",
Presets: []string{"style"},
},
{
Name: "noctx",
Presets: []string{"performance", "bugs"},
Slow: true,
},
{
Name: "nonamedreturns",
Presets: []string{"style"},
Slow: true,
},
{
Name: "nosprintfhostport",
Presets: []string{"style"},
},
{
Name: "paralleltest",
Presets: []string{"style", "test"},
Slow: true,
},
{
Name: "perfsprint",
Presets: []string{"performance"},
Slow: true,
},
{
Name: "prealloc",
Presets: []string{"performance"},
},
{
Name: "predeclared",
Presets: []string{"style"},
},
{
Name: "promlinter",
Presets: []string{"style"},
},
{
Name: "protogetter",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "reassign",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "recvcheck",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "revive",
Presets: []string{"style", "metalinter"},
Slow: true,
},
{
Name: "rowserrcheck",
Presets: []string{"bugs", "sql"},
Slow: true,
},
{
Name: "sloglint",
Presets: []string{"style"},
Slow: true,
},
{
Name: "sqlclosecheck",
Presets: []string{"bugs", "sql"},
Slow: true,
},
{
Name: "spancheck",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "staticcheck",
Presets: []string{"bugs", "metalinter"},
Slow: true,
Default: true,
AlternativeNames: []string{"megacheck"},
},
{
Name: "stylecheck",
Presets: []string{"style"},
Slow: true,
},
{
Name: "tagalign",
Presets: []string{"style"},
},
{
Name: "tagliatelle",
Presets: []string{"style"},
Slow: true,
},
{
Name: "testableexamples",
Presets: []string{"test"},
},
{
Name: "testifylint",
Presets: []string{"test", "bugs"},
Slow: true,
},
{
Name: "testpackage",
Presets: []string{"style", "test"},
},
{
Name: "thelper",
Presets: []string{"test"},
Slow: true,
},
{
Name: "tparallel",
Presets: []string{"style", "test"},
Slow: true,
},
{
Name: "unconvert",
Presets: []string{"style"},
Slow: true,
},
{
Name: "unparam",
Presets: []string{"unused"},
Slow: true,
},
{
Name: "unused",
Presets: []string{"unused"},
Slow: true,
Default: true,
AlternativeNames: []string{"megacheck"},
},
{
Name: "usestdlibvars",
Presets: []string{"style"},
},
{
Name: "usetesting",
Presets: []string{"test"},
Slow: true,
},
{
Name: "varnamelen",
Presets: []string{"style"},
Slow: true,
},
{
Name: "wastedassign",
Presets: []string{"style"},
Slow: true,
},
{
Name: "whitespace",
Presets: []string{"style"},
},
{
Name: "wrapcheck",
Presets: []string{"style", "error"},
Slow: true,
},
{
Name: "wsl",
Presets: []string{"style"},
},
{
Name: "zerologlint",
Presets: []string{"bugs"},
Slow: true,
},
{
Name: "nolintlint",
Presets: []string{"style"},
},
}
}
func toNames(linters []LinterInfo) []string {
var results []string
for _, linter := range linters {
results = append(results, linter.Name)
}
return Unique(results)
}
func removeLinters(linters, toRemove []LinterInfo) []LinterInfo {
return slices.DeleteFunc(linters, func(info LinterInfo) bool {
return slices.ContainsFunc(toRemove, func(en LinterInfo) bool {
return info.Name == en.Name
})
})
}
func allEnabled(old versionone.Linters, linters []LinterInfo) []LinterInfo {
var results []LinterInfo
for _, linter := range linters {
if slices.ContainsFunc(old.Enable, linter.isName) {
results = append(results, linter)
}
}
return results
}
func allDisabled(old versionone.Linters, linters []LinterInfo) []LinterInfo {
var results []LinterInfo
for _, linter := range linters {
if slices.ContainsFunc(old.Disable, linter.isName) {
results = append(results, linter)
}
}
return results
}
func filter(linters []LinterInfo, fns ...fnFilter) []LinterInfo {
var results []LinterInfo
for _, linter := range linters {
if mergeFilters(linter, fns) {
results = append(results, linter)
}
}
return results
}
func mergeFilters(linter LinterInfo, fns []fnFilter) bool {
for _, fn := range fns {
if !fn(linter) {
return false
}
}
return true
}
type fnFilter func(linter LinterInfo) bool
func onlyPresets(old versionone.Linters) fnFilter {
return func(linter LinterInfo) bool {
return linter.hasPresets(old.Presets)
}
}
func onlyDefault(linter LinterInfo) bool {
return linter.Default
}
func notDefault(linter LinterInfo) bool {
return !linter.Default
}
func keepFast(old versionone.Linters) fnFilter {
return func(linter LinterInfo) bool {
if !ptr.Deref(old.Fast) {
return true
}
return !linter.Slow
}
}
func keepSlow(old versionone.Linters) fnFilter {
return func(linter LinterInfo) bool {
if !ptr.Deref(old.Fast) {
return false
}
return linter.Slow
}
}
func unknownLinterNames(names []string, linters []LinterInfo) []string {
deprecatedLinters := []string{
"deadcode",
"execinquery",
"exhaustivestruct",
"exportloopref",
"golint",
"ifshort",
"interfacer",
"maligned",
"nosnakecase",
"scopelint",
"structcheck",
"tenv",
"typecheck",
"varcheck",
}
var results []string
for _, name := range names {
found := slices.ContainsFunc(linters, func(l LinterInfo) bool {
return l.isName(name)
})
if !found {
if slices.Contains(deprecatedLinters, name) {
continue
}
results = append(results, name)
}
}
return Unique(results)
}
func convertStaticcheckLinterNames(names []string) []string {
var results []string
for _, name := range names {
if slices.Contains([]string{"stylecheck", "gosimple"}, name) {
results = append(results, "staticcheck")
continue
}
results = append(results, name)
}
return Unique(results)
}
func convertDisabledStaticcheckLinterNames(names []string) []string {
removeStaticcheck := slices.Contains(names, "staticcheck") && slices.Contains(names, "stylecheck") && slices.Contains(names, "gosimple")
var results []string
for _, name := range names {
if removeStaticcheck && slices.Contains([]string{"stylecheck", "gosimple", "staticcheck"}, name) {
results = append(results, "staticcheck")
continue
}
if slices.Contains([]string{"stylecheck", "gosimple"}, name) {
continue
}
results = append(results, name)
}
return Unique(results)
}
func onlyLinterNames(names []string) []string {
formatters := []string{"gci", "gofmt", "gofumpt", "goimports"}
var results []string
for _, name := range names {
if !slices.Contains(formatters, name) {
results = append(results, name)
}
}
return results
}
func onlyFormatterNames(names []string) []string {
formatters := getAllFormatterNames()
var results []string
for _, name := range names {
if slices.Contains(formatters, name) {
results = append(results, name)
}
}
return results
}
func convertAlternativeNames(names []string) []string {
altNames := map[string]string{
"gas": "gosec",
"goerr113": "err113",
"gomnd": "mnd",
"logrlint": "loggercheck",
"megacheck": "staticcheck",
"vet": "govet",
"vetshadow": "govet",
}
var results []string
for _, name := range names {
if name == "typecheck" {
continue
}
if n, ok := altNames[name]; ok {
results = append(results, n)
continue
}
results = append(results, name)
}
return Unique(results)
}
func Unique[S ~[]E, E cmp.Ordered](s S) S {
return slices.Compact(slices.Sorted(slices.Values(s)))
}
func getAllFormatterNames() []string {
return []string{"gci", "gofmt", "gofumpt", "goimports"}
}
================================================
FILE: pkg/commands/internal/migrate/migrate_linter_names_test.go
================================================
package migrate
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
)
func Test_disableAllFilter(t *testing.T) {
testCases := []struct {
desc string
old versionone.Linters
expected []string
}{
{
desc: "no presets, fast",
old: versionone.Linters{
DisableAll: ptr.Pointer(true),
Enable: nil,
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: nil,
},
{
desc: "no presets, fast",
old: versionone.Linters{
DisableAll: ptr.Pointer(true),
Enable: nil,
Fast: ptr.Pointer(true),
Presets: nil,
},
expected: nil,
},
{
desc: "no presets, enable",
old: versionone.Linters{
DisableAll: ptr.Pointer(true),
Enable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: []string{"govet", "lll", "misspell"},
},
{
desc: "fast, no presets, enable",
old: versionone.Linters{
DisableAll: ptr.Pointer(true),
Enable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(true),
Presets: nil,
},
expected: []string{"govet", "lll", "misspell"},
},
{
desc: "presets, enable",
old: versionone.Linters{
DisableAll: ptr.Pointer(true),
Enable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(false),
Presets: []string{"comment", "error", "format"},
},
expected: []string{
"dupword",
"err113",
"errcheck",
"errorlint",
"gci",
"godot",
"godox",
"gofmt",
"gofumpt",
"goimports",
"govet",
"lll",
"misspell",
"wrapcheck",
},
},
{
desc: "presets, enable, fast",
old: versionone.Linters{
DisableAll: ptr.Pointer(true),
Enable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(true),
Presets: []string{"comment", "error", "format"},
},
expected: []string{
"dupword",
"gci",
"godot",
"godox",
"gofmt",
"gofumpt",
"goimports",
"govet",
"lll",
"misspell",
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
results := disableAllFilter(test.old)
assert.Equal(t, test.expected, results)
})
}
}
func Test_enableAllFilter(t *testing.T) {
testCases := []struct {
desc string
old versionone.Linters
expected []string
}{
{
desc: "no options",
old: versionone.Linters{
EnableAll: ptr.Pointer(true),
Disable: nil,
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: nil,
},
{
desc: "presets (ignored)",
old: versionone.Linters{
EnableAll: ptr.Pointer(true),
Disable: nil,
Fast: ptr.Pointer(false),
Presets: []string{"comment", "error", "format"},
},
expected: nil,
},
{
desc: "fast",
old: versionone.Linters{
EnableAll: ptr.Pointer(true),
Disable: nil,
Fast: ptr.Pointer(true),
Presets: nil,
},
expected: []string{"asasalint", "bodyclose", "canonicalheader", "containedctx", "contextcheck", "durationcheck", "err113", "errcheck", "errchkjson", "errname", "errorlint", "exhaustive", "exhaustruct", "exptostd", "fatcontext", "forbidigo", "forcetypeassert", "ginkgolinter", "gochecknoglobals", "gochecksumtype", "gocritic", "gosec", "gosimple", "gosmopolitan", "govet", "iface", "importas", "intrange", "ireturn", "loggercheck", "makezero", "mirror", "musttag", "nilerr", "nilnesserr", "nilnil", "noctx", "nonamedreturns", "paralleltest", "perfsprint", "protogetter", "reassign", "recvcheck", "revive", "rowserrcheck", "sloglint", "spancheck", "sqlclosecheck", "staticcheck", "stylecheck", "tagliatelle", "testifylint", "thelper", "tparallel", "unconvert", "unparam", "unused", "usetesting", "varnamelen", "wastedassign", "wrapcheck", "zerologlint"},
},
{
desc: "disable",
old: versionone.Linters{
EnableAll: ptr.Pointer(true),
Disable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: []string{"govet", "lll", "misspell"},
},
{
desc: "disable, fast",
old: versionone.Linters{
EnableAll: ptr.Pointer(true),
Disable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(true),
Presets: nil,
},
expected: []string{"asasalint", "bodyclose", "canonicalheader", "containedctx", "contextcheck", "durationcheck", "err113", "errcheck", "errchkjson", "errname", "errorlint", "exhaustive", "exhaustruct", "exptostd", "fatcontext", "forbidigo", "forcetypeassert", "ginkgolinter", "gochecknoglobals", "gochecksumtype", "gocritic", "gosec", "gosimple", "gosmopolitan", "govet", "iface", "importas", "intrange", "ireturn", "lll", "loggercheck", "makezero", "mirror", "misspell", "musttag", "nilerr", "nilnesserr", "nilnil", "noctx", "nonamedreturns", "paralleltest", "perfsprint", "protogetter", "reassign", "recvcheck", "revive", "rowserrcheck", "sloglint", "spancheck", "sqlclosecheck", "staticcheck", "stylecheck", "tagliatelle", "testifylint", "thelper", "tparallel", "unconvert", "unparam", "unused", "usetesting", "varnamelen", "wastedassign", "wrapcheck", "zerologlint"},
},
{
desc: "disable, enable, fast",
old: versionone.Linters{
EnableAll: ptr.Pointer(true),
Enable: []string{"canonicalheader", "errname"},
Disable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(true),
Presets: nil,
},
expected: []string{"asasalint", "bodyclose", "containedctx", "contextcheck", "durationcheck", "err113", "errcheck", "errchkjson", "errorlint", "exhaustive", "exhaustruct", "exptostd", "fatcontext", "forbidigo", "forcetypeassert", "ginkgolinter", "gochecknoglobals", "gochecksumtype", "gocritic", "gosec", "gosimple", "gosmopolitan", "govet", "iface", "importas", "intrange", "ireturn", "lll", "loggercheck", "makezero", "mirror", "misspell", "musttag", "nilerr", "nilnesserr", "nilnil", "noctx", "nonamedreturns", "paralleltest", "perfsprint", "protogetter", "reassign", "recvcheck", "revive", "rowserrcheck", "sloglint", "spancheck", "sqlclosecheck", "staticcheck", "stylecheck", "tagliatelle", "testifylint", "thelper", "tparallel", "unconvert", "unparam", "unused", "usetesting", "varnamelen", "wastedassign", "wrapcheck", "zerologlint"},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
results := enableAllFilter(test.old)
assert.Equal(t, test.expected, results)
})
}
}
func Test_defaultLintersDisableFilter(t *testing.T) {
testCases := []struct {
desc string
old versionone.Linters
expected []string
}{
{
desc: "no options",
old: versionone.Linters{
Enable: nil,
Disable: nil,
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: nil,
},
{
desc: "presets (ignored)",
old: versionone.Linters{
Enable: nil,
Disable: nil,
Fast: ptr.Pointer(false),
Presets: []string{"comment", "error", "format"},
},
expected: nil,
},
{
desc: "fast",
old: versionone.Linters{
Enable: nil,
Disable: nil,
Fast: ptr.Pointer(true),
Presets: nil,
},
expected: []string{"errcheck", "gosimple", "govet", "staticcheck", "unused"},
},
{
desc: "enable",
old: versionone.Linters{
Enable: []string{"lll", "misspell", "govet"},
Disable: nil,
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: nil,
},
{
desc: "disable",
old: versionone.Linters{
Enable: nil,
Disable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: []string{"govet", "lll", "misspell"},
},
{
desc: "disable, fast",
old: versionone.Linters{
Enable: nil,
Disable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(true),
Presets: nil,
},
expected: []string{"errcheck", "gosimple", "govet", "lll", "misspell", "staticcheck", "unused"},
},
{
desc: "enable, disable",
old: versionone.Linters{
Enable: []string{"grouper", "importas", "errcheck"},
Disable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: []string{"govet", "lll", "misspell"},
},
{
desc: "enable",
old: versionone.Linters{
Enable: []string{"grouper", "importas", "errcheck"},
Disable: nil,
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: nil,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
results := toNames(defaultLintersDisableFilter(test.old))
assert.Equal(t, test.expected, results)
})
}
}
func Test_defaultLintersEnableFilter(t *testing.T) {
testCases := []struct {
desc string
old versionone.Linters
expected []string
}{
{
desc: "no options",
old: versionone.Linters{
Enable: nil,
Disable: nil,
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: nil,
},
{
desc: "enable",
old: versionone.Linters{
Enable: []string{"grouper", "importas", "errcheck"},
Disable: nil,
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: []string{"grouper", "importas"},
},
{
desc: "enable, disable",
old: versionone.Linters{
Enable: []string{"grouper", "importas", "errcheck"},
Disable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: []string{"grouper", "importas"},
},
{
desc: "disable",
old: versionone.Linters{
Enable: nil,
Disable: []string{"lll", "misspell", "govet"},
Fast: ptr.Pointer(false),
Presets: nil,
},
expected: nil,
},
{
desc: "presets",
old: versionone.Linters{
Enable: nil,
Disable: nil,
Fast: ptr.Pointer(false),
Presets: []string{"comment", "error", "format"},
},
expected: []string{"dupword", "err113", "errorlint", "gci", "godot", "godox", "gofmt", "gofumpt", "goimports", "misspell", "wrapcheck"},
},
{
desc: "presets, fast",
old: versionone.Linters{
Enable: nil,
Disable: nil,
Fast: ptr.Pointer(true),
Presets: []string{"comment", "error", "format"},
},
expected: []string{"dupword", "gci", "godot", "godox", "gofmt", "gofumpt", "goimports", "misspell"},
},
}
// presets - slow + enable - default - [effective disable] => effective enable
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
results := toNames(defaultLintersEnableFilter(test.old, defaultLintersDisableFilter(test.old)))
assert.Equal(t, test.expected, results)
})
}
}
func Test_convertStaticcheckLinterNames(t *testing.T) {
testCases := []struct {
desc string
names []string
expected []string
}{
{
desc: "empty",
names: nil,
expected: nil,
},
{
desc: "no staticcheck linters",
names: []string{"lll", "misspell", "govet"},
expected: []string{"govet", "lll", "misspell"},
},
{
desc: "stylecheck",
names: []string{"lll", "misspell", "govet", "stylecheck"},
expected: []string{"govet", "lll", "misspell", "staticcheck"},
},
{
desc: "gosimple",
names: []string{"lll", "misspell", "govet", "gosimple"},
expected: []string{"govet", "lll", "misspell", "staticcheck"},
},
{
desc: "staticcheck",
names: []string{"lll", "misspell", "govet", "staticcheck"},
expected: []string{"govet", "lll", "misspell", "staticcheck"},
},
{
desc: "staticcheck, stylecheck, gosimple",
names: []string{"lll", "misspell", "govet", "staticcheck", "stylecheck", "gosimple"},
expected: []string{"govet", "lll", "misspell", "staticcheck"},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
results := convertStaticcheckLinterNames(test.names)
assert.Equal(t, test.expected, results)
})
}
}
func Test_unknownLinterNames(t *testing.T) {
testCases := []struct {
desc string
names []string
expected []string
}{
{
desc: "empty",
names: nil,
expected: nil,
},
{
desc: "deprecated",
names: []string{"golint", "structcheck", "varcheck"},
expected: nil,
},
{
desc: "deprecated and unknown",
names: []string{"golint", "structcheck", "varcheck", "a", "b"},
expected: []string{"a", "b"},
},
{
desc: "deprecated and known",
names: []string{"golint", "structcheck", "varcheck", "gosec", "gofmt"},
expected: nil,
},
{
desc: "only unknown",
names: []string{"a", "b", "c"},
expected: []string{"a", "b", "c"},
},
{
desc: "unknown and known",
names: []string{"a", "gosec", "gofmt"},
expected: []string{"a"},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
names := unknownLinterNames(test.names, allLinters())
assert.Equal(t, test.expected, names)
})
}
}
================================================
FILE: pkg/commands/internal/migrate/migrate_linters.go
================================================
package migrate
import (
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
)
func toLinters(old *versionone.Config) versiontwo.Linters {
enable, disable := ProcessEffectiveLinters(old.Linters)
return versiontwo.Linters{
Default: getDefaultName(old.Linters),
Enable: onlyLinterNames(convertStaticcheckLinterNames(enable)),
Disable: onlyLinterNames(convertDisabledStaticcheckLinterNames(disable)),
FastOnly: nil,
Settings: toLinterSettings(old.LintersSettings),
Exclusions: toExclusions(old),
}
}
func getDefaultName(old versionone.Linters) *string {
switch {
case ptr.Deref(old.DisableAll):
return ptr.Pointer("none")
case ptr.Deref(old.EnableAll):
return ptr.Pointer("all")
default:
return nil // standard is the default
}
}
================================================
FILE: pkg/commands/internal/migrate/migrate_linters_exclusions.go
================================================
package migrate
import (
"slices"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/result/processors"
)
func toExclusions(old *versionone.Config) versiontwo.LinterExclusions {
return versiontwo.LinterExclusions{
Generated: toExclusionGenerated(old.Issues.ExcludeGenerated),
Presets: toPresets(old.Issues),
Rules: toExclusionRules(old),
Paths: toExclusionPaths(old.Issues),
}
}
func toExclusionGenerated(excludeGenerated *string) *string {
if excludeGenerated == nil || ptr.Deref(excludeGenerated) == "" {
return ptr.Pointer("lax")
}
if ptr.Deref(excludeGenerated) == "strict" {
return nil
}
return excludeGenerated
}
func toPresets(old versionone.Issues) []string {
if old.UseDefaultExcludes != nil && !ptr.Deref(old.UseDefaultExcludes) {
return nil
}
if len(old.IncludeDefaultExcludes) != 0 {
var pp []string
for p, rules := range processors.LinterExclusionPresets {
found := slices.ContainsFunc(rules, func(rule config.ExcludeRule) bool {
return slices.Contains(old.IncludeDefaultExcludes, rule.InternalReference)
})
if !found {
pp = append(pp, p)
}
}
slices.Sort(pp)
return pp
}
return []string{
config.ExclusionPresetComments,
config.ExclusionPresetCommonFalsePositives,
config.ExclusionPresetLegacy,
config.ExclusionPresetStdErrorHandling,
}
}
func toExclusionRules(old *versionone.Config) []versiontwo.ExcludeRule {
var results []versiontwo.ExcludeRule
for _, rule := range old.Issues.ExcludeRules {
names := onlyLinterNames(convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters)))
if len(rule.Linters) > 0 && len(names) == 0 {
continue
}
results = append(results, versiontwo.ExcludeRule{
BaseRule: versiontwo.BaseRule{
Linters: names,
Path: rule.Path,
PathExcept: rule.PathExcept,
Text: addPrefix(old.Issues, rule.Text),
Source: addPrefix(old.Issues, rule.Source),
},
})
}
for _, pattern := range old.Issues.ExcludePatterns {
results = append(results, versiontwo.ExcludeRule{
BaseRule: versiontwo.BaseRule{
Path: ptr.Pointer(`(.+)\.go$`),
Text: addPrefix(old.Issues, ptr.Pointer(pattern)),
},
})
}
return slices.Concat(results, linterTestExclusions(old.LintersSettings))
}
func addPrefix(old versionone.Issues, s *string) *string {
if s == nil || ptr.Deref(s) == "" {
return s
}
var prefix string
if ptr.Deref(old.ExcludeCaseSensitive) {
prefix = "(?i)"
}
return ptr.Pointer(prefix + ptr.Deref(s))
}
func linterTestExclusions(old versionone.LintersSettings) []versiontwo.ExcludeRule {
var excludedTestLinters []string
if ptr.Deref(old.Asasalint.IgnoreTest) {
excludedTestLinters = append(excludedTestLinters, "asasalint")
}
if ptr.Deref(old.Cyclop.SkipTests) {
excludedTestLinters = append(excludedTestLinters, "cyclop")
}
if ptr.Deref(old.Goconst.IgnoreTests) {
excludedTestLinters = append(excludedTestLinters, "goconst")
}
if ptr.Deref(old.Gosmopolitan.IgnoreTests) {
excludedTestLinters = append(excludedTestLinters, "gosmopolitan")
}
if len(excludedTestLinters) == 0 {
return nil
}
return []versiontwo.ExcludeRule{{
BaseRule: versiontwo.BaseRule{
Linters: excludedTestLinters,
Path: ptr.Pointer(`(.+)_test\.go`),
},
}}
}
func toExclusionPaths(old versionone.Issues) []string {
results := slices.Concat(old.ExcludeFiles, old.ExcludeDirs)
if old.UseDefaultExcludeDirs == nil || ptr.Deref(old.UseDefaultExcludeDirs) {
results = append(results, "third_party$", "builtin$", "examples$")
}
return results
}
================================================
FILE: pkg/commands/internal/migrate/migrate_linters_settings.go
================================================
package migrate
import (
"slices"
"strings"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
)
func toLinterSettings(old versionone.LintersSettings) versiontwo.LintersSettings {
return versiontwo.LintersSettings{
Asasalint: toAsasalintSettings(old.Asasalint),
BiDiChk: toBiDiChkSettings(old.BiDiChk),
CopyLoopVar: toCopyLoopVarSettings(old.CopyLoopVar),
Cyclop: toCyclopSettings(old.Cyclop),
Decorder: toDecorderSettings(old.Decorder),
Depguard: toDepGuardSettings(old.Depguard),
Dogsled: toDogsledSettings(old.Dogsled),
Dupl: toDuplSettings(old.Dupl),
DupWord: toDupWordSettings(old.DupWord),
Errcheck: toErrcheckSettings(old.Errcheck),
ErrChkJSON: toErrChkJSONSettings(old.ErrChkJSON),
ErrorLint: toErrorLintSettings(old.ErrorLint),
Exhaustive: toExhaustiveSettings(old.Exhaustive),
Exhaustruct: toExhaustructSettings(old.Exhaustruct),
Fatcontext: toFatcontextSettings(old.Fatcontext),
Forbidigo: toForbidigoSettings(old.Forbidigo),
Funlen: toFunlenSettings(old.Funlen),
GinkgoLinter: toGinkgoLinterSettings(old.GinkgoLinter),
Gocognit: toGocognitSettings(old.Gocognit),
GoChecksumType: toGoChecksumTypeSettings(old.GoChecksumType),
Goconst: toGoConstSettings(old.Goconst),
Gocritic: toGoCriticSettings(old.Gocritic),
Gocyclo: toGoCycloSettings(old.Gocyclo),
Godot: toGodotSettings(old.Godot),
Godox: toGodoxSettings(old.Godox),
Goheader: toGoHeaderSettings(old.Goheader),
GoModDirectives: toGoModDirectivesSettings(old.GoModDirectives),
Gomodguard: toGoModGuardSettings(old.Gomodguard),
Gosec: toGoSecSettings(old.Gosec),
Gosmopolitan: toGosmopolitanSettings(old.Gosmopolitan),
Govet: toGovetSettings(old.Govet),
Grouper: toGrouperSettings(old.Grouper),
Iface: toIfaceSettings(old.Iface),
ImportAs: toImportAsSettings(old.ImportAs),
Inamedparam: toINamedParamSettings(old.Inamedparam),
InterfaceBloat: toInterfaceBloatSettings(old.InterfaceBloat),
Ireturn: toIreturnSettings(old.Ireturn),
Lll: toLllSettings(old.Lll),
LoggerCheck: toLoggerCheckSettings(old.LoggerCheck),
MaintIdx: toMaintIdxSettings(old.MaintIdx),
Makezero: toMakezeroSettings(old.Makezero),
Misspell: toMisspellSettings(old.Misspell),
Mnd: toMndSettings(old.Mnd),
MustTag: toMustTagSettings(old.MustTag),
Nakedret: toNakedretSettings(old.Nakedret),
Nestif: toNestifSettings(old.Nestif),
NilNil: toNilNilSettings(old.NilNil),
Nlreturn: toNlreturnSettings(old.Nlreturn),
NoLintLint: toNoLintLintSettings(old.NoLintLint),
NoNamedReturns: toNoNamedReturnsSettings(old.NoNamedReturns),
ParallelTest: toParallelTestSettings(old.ParallelTest),
PerfSprint: toPerfSprintSettings(old.PerfSprint),
Prealloc: toPreallocSettings(old.Prealloc),
Predeclared: toPredeclaredSettings(old.Predeclared),
Promlinter: toPromlinterSettings(old.Promlinter),
ProtoGetter: toProtoGetterSettings(old.ProtoGetter),
Reassign: toReassignSettings(old.Reassign),
Recvcheck: toRecvcheckSettings(old.Recvcheck),
Revive: toReviveSettings(old.Revive),
RowsErrCheck: toRowsErrCheckSettings(old.RowsErrCheck),
SlogLint: toSlogLintSettings(old.SlogLint),
Spancheck: toSpancheckSettings(old.Spancheck),
Staticcheck: toStaticCheckSettings(old),
TagAlign: toTagAlignSettings(old.TagAlign),
Tagliatelle: toTagliatelleSettings(old.Tagliatelle),
Testifylint: toTestifylintSettings(old.Testifylint),
Testpackage: toTestpackageSettings(old.Testpackage),
Thelper: toThelperSettings(old.Thelper),
Unconvert: toUnconvertSettings(old.Unconvert),
Unparam: toUnparamSettings(old.Unparam),
Unused: toUnusedSettings(old.Unused),
UseStdlibVars: toUseStdlibVarsSettings(old.UseStdlibVars),
UseTesting: toUseTestingSettings(old.UseTesting),
Varnamelen: toVarnamelenSettings(old.Varnamelen),
Whitespace: toWhitespaceSettings(old.Whitespace),
Wrapcheck: toWrapcheckSettings(old.Wrapcheck),
WSL: toWSLSettings(old.WSL),
Custom: toCustom(old.Custom),
}
}
func toAsasalintSettings(old versionone.AsasalintSettings) versiontwo.AsasalintSettings {
return versiontwo.AsasalintSettings{
Exclude: old.Exclude,
UseBuiltinExclusions: old.UseBuiltinExclusions,
}
}
func toBiDiChkSettings(old versionone.BiDiChkSettings) versiontwo.BiDiChkSettings {
// The values are true be default, but the default are defined after the configuration loading.
// So the serialization doesn't have good results, but it's complex to do better.
return versiontwo.BiDiChkSettings{
LeftToRightEmbedding: old.LeftToRightEmbedding,
RightToLeftEmbedding: old.RightToLeftEmbedding,
PopDirectionalFormatting: old.PopDirectionalFormatting,
LeftToRightOverride: old.LeftToRightOverride,
RightToLeftOverride: old.RightToLeftOverride,
LeftToRightIsolate: old.LeftToRightIsolate,
RightToLeftIsolate: old.RightToLeftIsolate,
FirstStrongIsolate: old.FirstStrongIsolate,
PopDirectionalIsolate: old.PopDirectionalIsolate,
}
}
func toCopyLoopVarSettings(old versionone.CopyLoopVarSettings) versiontwo.CopyLoopVarSettings {
return versiontwo.CopyLoopVarSettings{
CheckAlias: old.CheckAlias,
}
}
func toCyclopSettings(old versionone.Cyclop) versiontwo.CyclopSettings {
return versiontwo.CyclopSettings{
MaxComplexity: old.MaxComplexity,
PackageAverage: old.PackageAverage,
}
}
func toDecorderSettings(old versionone.DecorderSettings) versiontwo.DecorderSettings {
return versiontwo.DecorderSettings{
DecOrder: old.DecOrder,
IgnoreUnderscoreVars: old.IgnoreUnderscoreVars,
DisableDecNumCheck: old.DisableDecNumCheck,
DisableTypeDecNumCheck: old.DisableTypeDecNumCheck,
DisableConstDecNumCheck: old.DisableConstDecNumCheck,
DisableVarDecNumCheck: old.DisableVarDecNumCheck,
DisableDecOrderCheck: old.DisableDecOrderCheck,
DisableInitFuncFirstCheck: old.DisableInitFuncFirstCheck,
}
}
func toDepGuardSettings(old versionone.DepGuardSettings) versiontwo.DepGuardSettings {
settings := versiontwo.DepGuardSettings{}
for k, r := range old.Rules {
if settings.Rules == nil {
settings.Rules = make(map[string]*versiontwo.DepGuardList)
}
list := &versiontwo.DepGuardList{
ListMode: r.ListMode,
Files: r.Files,
Allow: r.Allow,
}
for _, deny := range r.Deny {
list.Deny = append(list.Deny, versiontwo.DepGuardDeny{
Pkg: deny.Pkg,
Desc: deny.Desc,
})
}
settings.Rules[k] = list
}
return settings
}
func toDogsledSettings(old versionone.DogsledSettings) versiontwo.DogsledSettings {
return versiontwo.DogsledSettings{
MaxBlankIdentifiers: old.MaxBlankIdentifiers,
}
}
func toDuplSettings(old versionone.DuplSettings) versiontwo.DuplSettings {
return versiontwo.DuplSettings{
Threshold: old.Threshold,
}
}
func toDupWordSettings(old versionone.DupWordSettings) versiontwo.DupWordSettings {
return versiontwo.DupWordSettings{
Keywords: old.Keywords,
Ignore: old.Ignore,
}
}
func toErrcheckSettings(old versionone.ErrcheckSettings) versiontwo.ErrcheckSettings {
return versiontwo.ErrcheckSettings{
DisableDefaultExclusions: old.DisableDefaultExclusions,
CheckTypeAssertions: old.CheckTypeAssertions,
CheckAssignToBlank: old.CheckAssignToBlank,
ExcludeFunctions: old.ExcludeFunctions,
}
}
func toErrChkJSONSettings(old versionone.ErrChkJSONSettings) versiontwo.ErrChkJSONSettings {
return versiontwo.ErrChkJSONSettings{
CheckErrorFreeEncoding: old.CheckErrorFreeEncoding,
ReportNoExported: old.ReportNoExported,
}
}
func toErrorLintSettings(old versionone.ErrorLintSettings) versiontwo.ErrorLintSettings {
settings := versiontwo.ErrorLintSettings{
Errorf: old.Errorf,
ErrorfMulti: old.ErrorfMulti,
Asserts: old.Asserts,
Comparison: old.Comparison,
}
for _, allowedError := range old.AllowedErrors {
settings.AllowedErrors = append(settings.AllowedErrors, versiontwo.ErrorLintAllowPair{
Err: allowedError.Err,
Fun: allowedError.Fun,
})
}
for _, allowedError := range old.AllowedErrorsWildcard {
settings.AllowedErrorsWildcard = append(settings.AllowedErrorsWildcard, versiontwo.ErrorLintAllowPair{
Err: allowedError.Err,
Fun: allowedError.Fun,
})
}
return settings
}
func toExhaustiveSettings(old versionone.ExhaustiveSettings) versiontwo.ExhaustiveSettings {
return versiontwo.ExhaustiveSettings{
Check: old.Check,
DefaultSignifiesExhaustive: old.DefaultSignifiesExhaustive,
IgnoreEnumMembers: old.IgnoreEnumMembers,
IgnoreEnumTypes: old.IgnoreEnumTypes,
PackageScopeOnly: old.PackageScopeOnly,
ExplicitExhaustiveMap: old.ExplicitExhaustiveMap,
ExplicitExhaustiveSwitch: old.ExplicitExhaustiveSwitch,
DefaultCaseRequired: old.DefaultCaseRequired,
}
}
func toExhaustructSettings(old versionone.ExhaustructSettings) versiontwo.ExhaustructSettings {
return versiontwo.ExhaustructSettings{
Include: old.Include,
Exclude: old.Exclude,
}
}
func toFatcontextSettings(old versionone.FatcontextSettings) versiontwo.FatcontextSettings {
return versiontwo.FatcontextSettings{
CheckStructPointers: old.CheckStructPointers,
}
}
func toForbidigoSettings(old versionone.ForbidigoSettings) versiontwo.ForbidigoSettings {
settings := versiontwo.ForbidigoSettings{
ExcludeGodocExamples: old.ExcludeGodocExamples,
AnalyzeTypes: old.AnalyzeTypes,
}
for _, pattern := range old.Forbid {
if pattern.Pattern == nil && pattern.Msg == nil && pattern.Package == nil {
buffer, err := pattern.MarshalString()
if err != nil {
// impossible case
panic(err)
}
settings.Forbid = append(settings.Forbid, versiontwo.ForbidigoPattern{
Pattern: ptr.Pointer(string(buffer)),
})
continue
}
settings.Forbid = append(settings.Forbid, versiontwo.ForbidigoPattern{
Pattern: pattern.Pattern,
Package: pattern.Package,
Msg: pattern.Msg,
})
}
return settings
}
func toFunlenSettings(old versionone.FunlenSettings) versiontwo.FunlenSettings {
return versiontwo.FunlenSettings{
Lines: old.Lines,
Statements: old.Statements,
IgnoreComments: old.IgnoreComments,
}
}
func toGinkgoLinterSettings(old versionone.GinkgoLinterSettings) versiontwo.GinkgoLinterSettings {
return versiontwo.GinkgoLinterSettings{
SuppressLenAssertion: old.SuppressLenAssertion,
SuppressNilAssertion: old.SuppressNilAssertion,
SuppressErrAssertion: old.SuppressErrAssertion,
SuppressCompareAssertion: old.SuppressCompareAssertion,
SuppressAsyncAssertion: old.SuppressAsyncAssertion,
SuppressTypeCompareWarning: old.SuppressTypeCompareWarning,
ForbidFocusContainer: old.ForbidFocusContainer,
AllowHaveLenZero: old.AllowHaveLenZero,
ForceExpectTo: old.ForceExpectTo,
ValidateAsyncIntervals: old.ValidateAsyncIntervals,
ForbidSpecPollution: old.ForbidSpecPollution,
ForceSucceedForFuncs: old.ForceSucceedForFuncs,
}
}
func toGocognitSettings(old versionone.GocognitSettings) versiontwo.GocognitSettings {
return versiontwo.GocognitSettings{
MinComplexity: old.MinComplexity,
}
}
func toGoChecksumTypeSettings(old versionone.GoChecksumTypeSettings) versiontwo.GoChecksumTypeSettings {
return versiontwo.GoChecksumTypeSettings{
DefaultSignifiesExhaustive: old.DefaultSignifiesExhaustive,
IncludeSharedInterfaces: old.IncludeSharedInterfaces,
}
}
func toGoConstSettings(old versionone.GoConstSettings) versiontwo.GoConstSettings {
return versiontwo.GoConstSettings{
IgnoreStrings: old.IgnoreStrings,
MatchWithConstants: old.MatchWithConstants,
MinStringLen: old.MinStringLen,
MinOccurrencesCount: old.MinOccurrencesCount,
ParseNumbers: old.ParseNumbers,
NumberMin: old.NumberMin,
NumberMax: old.NumberMax,
IgnoreCalls: old.IgnoreCalls,
}
}
func toGoCriticSettings(old versionone.GoCriticSettings) versiontwo.GoCriticSettings {
settings := versiontwo.GoCriticSettings{
Go: old.Go,
DisableAll: old.DisableAll,
EnabledChecks: old.EnabledChecks,
EnableAll: old.EnableAll,
DisabledChecks: old.DisabledChecks,
EnabledTags: old.EnabledTags,
DisabledTags: old.DisabledTags,
}
for k, checkSettings := range old.SettingsPerCheck {
if settings.SettingsPerCheck == nil {
settings.SettingsPerCheck = make(map[string]versiontwo.GoCriticCheckSettings)
}
if k != "ruleguard" {
settings.SettingsPerCheck[k] = versiontwo.GoCriticCheckSettings(checkSettings)
continue
}
gccs := versiontwo.GoCriticCheckSettings{}
for sk, value := range checkSettings {
if sk != "rules" {
gccs[sk] = value
continue
}
if rules, ok := value.(string); ok {
gccs[sk] = strings.ReplaceAll(rules, "${configDir}", "${base-path}")
}
}
settings.SettingsPerCheck[k] = gccs
}
return settings
}
func toGoCycloSettings(old versionone.GoCycloSettings) versiontwo.GoCycloSettings {
return versiontwo.GoCycloSettings{
MinComplexity: old.MinComplexity,
}
}
func toGodotSettings(old versionone.GodotSettings) versiontwo.GodotSettings {
return versiontwo.GodotSettings{
Scope: old.Scope,
Exclude: old.Exclude,
Capital: old.Capital,
Period: old.Period,
}
}
func toGodoxSettings(old versionone.GodoxSettings) versiontwo.GodoxSettings {
return versiontwo.GodoxSettings{
Keywords: old.Keywords,
}
}
func toGoHeaderSettings(old versionone.GoHeaderSettings) versiontwo.GoHeaderSettings {
return versiontwo.GoHeaderSettings{
Values: old.Values,
Template: old.Template,
TemplatePath: old.TemplatePath,
}
}
func toGoModDirectivesSettings(old versionone.GoModDirectivesSettings) versiontwo.GoModDirectivesSettings {
return versiontwo.GoModDirectivesSettings{
ReplaceAllowList: old.ReplaceAllowList,
ReplaceLocal: old.ReplaceLocal,
ExcludeForbidden: old.ExcludeForbidden,
RetractAllowNoExplanation: old.RetractAllowNoExplanation,
ToolchainForbidden: old.ToolchainForbidden,
ToolchainPattern: old.ToolchainPattern,
ToolForbidden: old.ToolForbidden,
GoDebugForbidden: old.GoDebugForbidden,
GoVersionPattern: old.GoVersionPattern,
}
}
func toGoModGuardSettings(old versionone.GoModGuardSettings) versiontwo.GoModGuardSettings {
blocked := versiontwo.GoModGuardBlocked{
LocalReplaceDirectives: old.Blocked.LocalReplaceDirectives,
}
for _, version := range old.Blocked.Modules {
data := map[string]versiontwo.GoModGuardModule{}
for k, v := range version {
data[k] = versiontwo.GoModGuardModule{
Recommendations: v.Recommendations,
Reason: v.Reason,
}
}
blocked.Modules = append(blocked.Modules, data)
}
for _, version := range old.Blocked.Versions {
data := map[string]versiontwo.GoModGuardVersion{}
for k, v := range version {
data[k] = versiontwo.GoModGuardVersion{
Version: v.Version,
Reason: v.Reason,
}
}
blocked.Versions = append(blocked.Versions, data)
}
return versiontwo.GoModGuardSettings{
Allowed: versiontwo.GoModGuardAllowed{
Modules: old.Allowed.Modules,
Domains: old.Allowed.Domains,
},
Blocked: blocked,
}
}
func toGoSecSettings(old versionone.GoSecSettings) versiontwo.GoSecSettings {
return versiontwo.GoSecSettings{
Includes: old.Includes,
Excludes: old.Excludes,
Severity: old.Severity,
Confidence: old.Confidence,
Config: old.Config,
Concurrency: old.Concurrency,
}
}
func toGosmopolitanSettings(old versionone.GosmopolitanSettings) versiontwo.GosmopolitanSettings {
return versiontwo.GosmopolitanSettings{
AllowTimeLocal: old.AllowTimeLocal,
EscapeHatches: old.EscapeHatches,
WatchForScripts: old.WatchForScripts,
}
}
func toGovetSettings(old versionone.GovetSettings) versiontwo.GovetSettings {
return versiontwo.GovetSettings{
Go: old.Go,
Enable: old.Enable,
Disable: old.Disable,
EnableAll: old.EnableAll,
DisableAll: old.DisableAll,
Settings: old.Settings,
}
}
func toGrouperSettings(old versionone.GrouperSettings) versiontwo.GrouperSettings {
return versiontwo.GrouperSettings{
ConstRequireSingleConst: old.ConstRequireSingleConst,
ConstRequireGrouping: old.ConstRequireGrouping,
ImportRequireSingleImport: old.ImportRequireSingleImport,
ImportRequireGrouping: old.ImportRequireGrouping,
TypeRequireSingleType: old.TypeRequireSingleType,
TypeRequireGrouping: old.TypeRequireGrouping,
VarRequireSingleVar: old.VarRequireSingleVar,
VarRequireGrouping: old.VarRequireGrouping,
}
}
func toIfaceSettings(old versionone.IfaceSettings) versiontwo.IfaceSettings {
return versiontwo.IfaceSettings{
Enable: old.Enable,
Settings: old.Settings,
}
}
func toImportAsSettings(old versionone.ImportAsSettings) versiontwo.ImportAsSettings {
settings := versiontwo.ImportAsSettings{
NoUnaliased: old.NoUnaliased,
NoExtraAliases: old.NoExtraAliases,
}
for _, alias := range old.Alias {
settings.Alias = append(settings.Alias, versiontwo.ImportAsAlias{
Pkg: alias.Pkg,
Alias: alias.Alias,
})
}
return settings
}
func toINamedParamSettings(old versionone.INamedParamSettings) versiontwo.INamedParamSettings {
return versiontwo.INamedParamSettings{
SkipSingleParam: old.SkipSingleParam,
}
}
func toInterfaceBloatSettings(old versionone.InterfaceBloatSettings) versiontwo.InterfaceBloatSettings {
return versiontwo.InterfaceBloatSettings{
Max: old.Max,
}
}
func toIreturnSettings(old versionone.IreturnSettings) versiontwo.IreturnSettings {
return versiontwo.IreturnSettings{
Allow: old.Allow,
Reject: old.Reject,
}
}
func toLllSettings(old versionone.LllSettings) versiontwo.LllSettings {
return versiontwo.LllSettings{
LineLength: old.LineLength,
TabWidth: old.TabWidth,
}
}
func toLoggerCheckSettings(old versionone.LoggerCheckSettings) versiontwo.LoggerCheckSettings {
return versiontwo.LoggerCheckSettings{
Kitlog: old.Kitlog,
Klog: old.Klog,
Logr: old.Logr,
Slog: old.Slog,
Zap: old.Zap,
RequireStringKey: old.RequireStringKey,
NoPrintfLike: old.NoPrintfLike,
Rules: old.Rules,
}
}
func toMaintIdxSettings(old versionone.MaintIdxSettings) versiontwo.MaintIdxSettings {
return versiontwo.MaintIdxSettings{
Under: old.Under,
}
}
func toMakezeroSettings(old versionone.MakezeroSettings) versiontwo.MakezeroSettings {
return versiontwo.MakezeroSettings{
Always: old.Always,
}
}
func toMisspellSettings(old versionone.MisspellSettings) versiontwo.MisspellSettings {
settings := versiontwo.MisspellSettings{
Mode: old.Mode,
Locale: old.Locale,
IgnoreRules: old.IgnoreWords,
}
for _, word := range old.ExtraWords {
settings.ExtraWords = append(settings.ExtraWords, versiontwo.MisspellExtraWords{
Typo: word.Typo,
Correction: word.Correction,
})
}
return settings
}
func toMndSettings(old versionone.MndSettings) versiontwo.MndSettings {
return versiontwo.MndSettings{
Checks: old.Checks,
IgnoredNumbers: old.IgnoredNumbers,
IgnoredFiles: old.IgnoredFiles,
IgnoredFunctions: old.IgnoredFunctions,
}
}
func toMustTagSettings(old versionone.MustTagSettings) versiontwo.MustTagSettings {
settings := versiontwo.MustTagSettings{}
for _, function := range old.Functions {
settings.Functions = append(settings.Functions, versiontwo.MustTagFunction{
Name: function.Name,
Tag: function.Tag,
ArgPos: function.ArgPos,
})
}
return settings
}
func toNakedretSettings(old versionone.NakedretSettings) versiontwo.NakedretSettings {
return versiontwo.NakedretSettings{
MaxFuncLines: old.MaxFuncLines,
}
}
func toNestifSettings(old versionone.NestifSettings) versiontwo.NestifSettings {
return versiontwo.NestifSettings{
MinComplexity: old.MinComplexity,
}
}
func toNilNilSettings(old versionone.NilNilSettings) versiontwo.NilNilSettings {
return versiontwo.NilNilSettings{
DetectOpposite: old.DetectOpposite,
CheckedTypes: old.CheckedTypes,
}
}
func toNlreturnSettings(old versionone.NlreturnSettings) versiontwo.NlreturnSettings {
return versiontwo.NlreturnSettings{
BlockSize: old.BlockSize,
}
}
func toNoLintLintSettings(old versionone.NoLintLintSettings) versiontwo.NoLintLintSettings {
return versiontwo.NoLintLintSettings{
RequireExplanation: old.RequireExplanation,
RequireSpecific: old.RequireSpecific,
AllowNoExplanation: old.AllowNoExplanation,
AllowUnused: old.AllowUnused,
}
}
func toNoNamedReturnsSettings(old versionone.NoNamedReturnsSettings) versiontwo.NoNamedReturnsSettings {
return versiontwo.NoNamedReturnsSettings{
ReportErrorInDefer: old.ReportErrorInDefer,
}
}
func toParallelTestSettings(old versionone.ParallelTestSettings) versiontwo.ParallelTestSettings {
return versiontwo.ParallelTestSettings{
Go: nil,
IgnoreMissing: old.IgnoreMissing,
IgnoreMissingSubtests: old.IgnoreMissingSubtests,
}
}
func toPerfSprintSettings(old versionone.PerfSprintSettings) versiontwo.PerfSprintSettings {
return versiontwo.PerfSprintSettings{
IntegerFormat: old.IntegerFormat,
IntConversion: old.IntConversion,
ErrorFormat: old.ErrorFormat,
ErrError: old.ErrError,
ErrorF: old.ErrorF,
StringFormat: old.StringFormat,
SprintF1: old.SprintF1,
StrConcat: old.StrConcat,
BoolFormat: old.BoolFormat,
HexFormat: old.HexFormat,
}
}
func toPreallocSettings(old versionone.PreallocSettings) versiontwo.PreallocSettings {
return versiontwo.PreallocSettings{
Simple: old.Simple,
RangeLoops: old.RangeLoops,
ForLoops: old.ForLoops,
}
}
func toPredeclaredSettings(old versionone.PredeclaredSettings) versiontwo.PredeclaredSettings {
var ignore []string
if ptr.Deref(old.Ignore) != "" {
ignore = strings.Split(ptr.Deref(old.Ignore), ",")
}
return versiontwo.PredeclaredSettings{
Ignore: ignore,
Qualified: old.Qualified,
}
}
func toPromlinterSettings(old versionone.PromlinterSettings) versiontwo.PromlinterSettings {
return versiontwo.PromlinterSettings{
Strict: old.Strict,
DisabledLinters: old.DisabledLinters,
}
}
func toProtoGetterSettings(old versionone.ProtoGetterSettings) versiontwo.ProtoGetterSettings {
return versiontwo.ProtoGetterSettings{
SkipGeneratedBy: old.SkipGeneratedBy,
SkipFiles: old.SkipFiles,
SkipAnyGenerated: old.SkipAnyGenerated,
ReplaceFirstArgInAppend: old.ReplaceFirstArgInAppend,
}
}
func toReassignSettings(old versionone.ReassignSettings) versiontwo.ReassignSettings {
return versiontwo.ReassignSettings{
Patterns: old.Patterns,
}
}
func toRecvcheckSettings(old versionone.RecvcheckSettings) versiontwo.RecvcheckSettings {
return versiontwo.RecvcheckSettings{
DisableBuiltin: old.DisableBuiltin,
Exclusions: old.Exclusions,
}
}
func toReviveSettings(old versionone.ReviveSettings) versiontwo.ReviveSettings {
settings := versiontwo.ReviveSettings{
MaxOpenFiles: old.MaxOpenFiles,
Confidence: old.Confidence,
Severity: old.Severity,
EnableAllRules: old.EnableAllRules,
ErrorCode: old.ErrorCode,
WarningCode: old.WarningCode,
}
for _, rule := range old.Rules {
settings.Rules = append(settings.Rules, versiontwo.ReviveRule{
Name: rule.Name,
Arguments: rule.Arguments,
Severity: rule.Severity,
Disabled: rule.Disabled,
Exclude: rule.Exclude,
})
}
for _, directive := range old.Directives {
settings.Directives = append(settings.Directives, versiontwo.ReviveDirective{
Name: directive.Name,
Severity: directive.Severity,
})
}
return settings
}
func toRowsErrCheckSettings(old versionone.RowsErrCheckSettings) versiontwo.RowsErrCheckSettings {
return versiontwo.RowsErrCheckSettings{
Packages: old.Packages,
}
}
func toSlogLintSettings(old versionone.SlogLintSettings) versiontwo.SlogLintSettings {
return versiontwo.SlogLintSettings{
NoMixedArgs: old.NoMixedArgs,
KVOnly: old.KVOnly,
AttrOnly: old.AttrOnly,
NoGlobal: old.NoGlobal,
Context: old.Context,
StaticMsg: old.StaticMsg,
NoRawKeys: old.NoRawKeys,
KeyNamingCase: old.KeyNamingCase,
ForbiddenKeys: old.ForbiddenKeys,
ArgsOnSepLines: old.ArgsOnSepLines,
}
}
func toSpancheckSettings(old versionone.SpancheckSettings) versiontwo.SpancheckSettings {
return versiontwo.SpancheckSettings{
Checks: old.Checks,
IgnoreCheckSignatures: old.IgnoreCheckSignatures,
ExtraStartSpanSignatures: old.ExtraStartSpanSignatures,
}
}
func toStaticCheckSettings(old versionone.LintersSettings) versiontwo.StaticCheckSettings {
var checks []string
for _, check := range slices.Concat(old.Staticcheck.Checks, old.Stylecheck.Checks, old.Gosimple.Checks) {
if check == "*" {
checks = append(checks, "all")
continue
}
checks = append(checks, check)
}
checks = Unique(checks)
slices.SortFunc(checks, func(a, b string) int {
if a == "all" {
return -1
}
if b == "all" {
return 1
}
return strings.Compare(a, b)
})
return versiontwo.StaticCheckSettings{
Checks: checks,
Initialisms: old.Stylecheck.Initialisms,
DotImportWhitelist: old.Stylecheck.DotImportWhitelist,
HTTPStatusCodeWhitelist: old.Stylecheck.HTTPStatusCodeWhitelist,
}
}
func toTagAlignSettings(old versionone.TagAlignSettings) versiontwo.TagAlignSettings {
return versiontwo.TagAlignSettings{
Align: old.Align,
Sort: old.Sort,
Order: old.Order,
Strict: old.Strict,
}
}
func toTagliatelleSettings(old versionone.TagliatelleSettings) versiontwo.TagliatelleSettings {
tcase := versiontwo.TagliatelleCase{
TagliatelleBase: versiontwo.TagliatelleBase{
Rules: old.Case.Rules,
UseFieldName: old.Case.UseFieldName,
IgnoredFields: old.Case.IgnoredFields,
},
Overrides: []versiontwo.TagliatelleOverrides{},
}
for k, rule := range old.Case.ExtendedRules {
if tcase.ExtendedRules == nil {
tcase.ExtendedRules = make(map[string]versiontwo.TagliatelleExtendedRule)
}
tcase.ExtendedRules[k] = versiontwo.TagliatelleExtendedRule{
Case: rule.Case,
ExtraInitialisms: rule.ExtraInitialisms,
InitialismOverrides: rule.InitialismOverrides,
}
}
return versiontwo.TagliatelleSettings{Case: tcase}
}
func toTestifylintSettings(old versionone.TestifylintSettings) versiontwo.TestifylintSettings {
return versiontwo.TestifylintSettings{
EnableAll: old.EnableAll,
DisableAll: old.DisableAll,
EnabledCheckers: old.EnabledCheckers,
DisabledCheckers: old.DisabledCheckers,
BoolCompare: versiontwo.TestifylintBoolCompare{
IgnoreCustomTypes: old.BoolCompare.IgnoreCustomTypes,
},
ExpectedActual: versiontwo.TestifylintExpectedActual{
ExpVarPattern: old.ExpectedActual.ExpVarPattern,
},
Formatter: versiontwo.TestifylintFormatter{
CheckFormatString: old.Formatter.CheckFormatString,
RequireFFuncs: old.Formatter.RequireFFuncs,
},
GoRequire: versiontwo.TestifylintGoRequire{
IgnoreHTTPHandlers: old.GoRequire.IgnoreHTTPHandlers,
},
RequireError: versiontwo.TestifylintRequireError{
FnPattern: old.RequireError.FnPattern,
},
SuiteExtraAssertCall: versiontwo.TestifylintSuiteExtraAssertCall{
Mode: old.SuiteExtraAssertCall.Mode,
},
}
}
func toTestpackageSettings(old versionone.TestpackageSettings) versiontwo.TestpackageSettings {
return versiontwo.TestpackageSettings{
SkipRegexp: old.SkipRegexp,
AllowPackages: old.AllowPackages,
}
}
func toThelperSettings(old versionone.ThelperSettings) versiontwo.ThelperSettings {
return versiontwo.ThelperSettings{
Test: versiontwo.ThelperOptions{
First: old.Test.First,
Name: old.Test.Name,
Begin: old.Test.Begin,
},
Fuzz: versiontwo.ThelperOptions{
First: old.Fuzz.First,
Name: old.Fuzz.Name,
Begin: old.Fuzz.Begin,
},
Benchmark: versiontwo.ThelperOptions{
First: old.Benchmark.First,
Name: old.Benchmark.Name,
Begin: old.Benchmark.Begin,
},
TB: versiontwo.ThelperOptions{
First: old.TB.First,
Name: old.TB.Name,
Begin: old.TB.Begin,
},
}
}
func toUnconvertSettings(old versionone.UnconvertSettings) versiontwo.UnconvertSettings {
return versiontwo.UnconvertSettings{
FastMath: old.FastMath,
Safe: old.Safe,
}
}
func toUnparamSettings(old versionone.UnparamSettings) versiontwo.UnparamSettings {
return versiontwo.UnparamSettings{
CheckExported: old.CheckExported,
}
}
func toUnusedSettings(old versionone.UnusedSettings) versiontwo.UnusedSettings {
return versiontwo.UnusedSettings{
FieldWritesAreUses: old.FieldWritesAreUses,
PostStatementsAreReads: old.PostStatementsAreReads,
ExportedFieldsAreUsed: old.ExportedFieldsAreUsed,
ParametersAreUsed: old.ParametersAreUsed,
LocalVariablesAreUsed: old.LocalVariablesAreUsed,
GeneratedIsUsed: old.GeneratedIsUsed,
}
}
func toUseStdlibVarsSettings(old versionone.UseStdlibVarsSettings) versiontwo.UseStdlibVarsSettings {
return versiontwo.UseStdlibVarsSettings{
HTTPMethod: old.HTTPMethod,
HTTPStatusCode: old.HTTPStatusCode,
TimeWeekday: old.TimeWeekday,
TimeMonth: old.TimeMonth,
TimeLayout: old.TimeLayout,
CryptoHash: old.CryptoHash,
DefaultRPCPath: old.DefaultRPCPath,
SQLIsolationLevel: old.SQLIsolationLevel,
TLSSignatureScheme: old.TLSSignatureScheme,
ConstantKind: old.ConstantKind,
}
}
func toUseTestingSettings(old versionone.UseTestingSettings) versiontwo.UseTestingSettings {
return versiontwo.UseTestingSettings{
ContextBackground: old.ContextBackground,
ContextTodo: old.ContextTodo,
OSChdir: old.OSChdir,
OSMkdirTemp: old.OSMkdirTemp,
OSSetenv: old.OSSetenv,
OSTempDir: old.OSTempDir,
OSCreateTemp: old.OSCreateTemp,
}
}
func toVarnamelenSettings(old versionone.VarnamelenSettings) versiontwo.VarnamelenSettings {
return versiontwo.VarnamelenSettings{
MaxDistance: old.MaxDistance,
MinNameLength: old.MinNameLength,
CheckReceiver: old.CheckReceiver,
CheckReturn: old.CheckReturn,
CheckTypeParam: old.CheckTypeParam,
IgnoreNames: old.IgnoreNames,
IgnoreTypeAssertOk: old.IgnoreTypeAssertOk,
IgnoreMapIndexOk: old.IgnoreMapIndexOk,
IgnoreChanRecvOk: old.IgnoreChanRecvOk,
IgnoreDecls: old.IgnoreDecls,
}
}
func toWhitespaceSettings(old versionone.WhitespaceSettings) versiontwo.WhitespaceSettings {
return versiontwo.WhitespaceSettings{
MultiIf: old.MultiIf,
MultiFunc: old.MultiFunc,
}
}
func toWrapcheckSettings(old versionone.WrapcheckSettings) versiontwo.WrapcheckSettings {
return versiontwo.WrapcheckSettings{
ExtraIgnoreSigs: old.ExtraIgnoreSigs,
IgnoreSigs: old.IgnoreSigs,
IgnoreSigRegexps: old.IgnoreSigRegexps,
IgnorePackageGlobs: old.IgnorePackageGlobs,
IgnoreInterfaceRegexps: old.IgnoreInterfaceRegexps,
}
}
func toWSLSettings(old versionone.WSLSettings) versiontwo.WSLv4Settings {
return versiontwo.WSLv4Settings{
StrictAppend: old.StrictAppend,
AllowAssignAndCallCuddle: old.AllowAssignAndCallCuddle,
AllowAssignAndAnythingCuddle: old.AllowAssignAndAnythingCuddle,
AllowMultiLineAssignCuddle: old.AllowMultiLineAssignCuddle,
ForceCaseTrailingWhitespaceLimit: old.ForceCaseTrailingWhitespaceLimit,
AllowTrailingComment: old.AllowTrailingComment,
AllowSeparatedLeadingComment: old.AllowSeparatedLeadingComment,
AllowCuddleDeclaration: old.AllowCuddleDeclaration,
AllowCuddleWithCalls: old.AllowCuddleWithCalls,
AllowCuddleWithRHS: old.AllowCuddleWithRHS,
ForceCuddleErrCheckAndAssign: old.ForceCuddleErrCheckAndAssign,
ErrorVariableNames: old.ErrorVariableNames,
ForceExclusiveShortDeclarations: old.ForceExclusiveShortDeclarations,
}
}
func toCustom(old map[string]versionone.CustomLinterSettings) map[string]versiontwo.CustomLinterSettings {
if old == nil {
return nil
}
settings := map[string]versiontwo.CustomLinterSettings{}
for k, s := range old {
settings[k] = versiontwo.CustomLinterSettings{
Type: s.Type,
Path: s.Path,
Description: s.Description,
OriginalURL: s.OriginalURL,
Settings: s.Settings,
}
}
return settings
}
================================================
FILE: pkg/commands/internal/migrate/migrate_output.go
================================================
package migrate
import (
"slices"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
)
func toOutput(old *versionone.Config) versiontwo.Output {
formats := versiontwo.Formats{}
oldFormats := cleanIncompatibleFormats(old.Output.Formats, "colored-line-number", "line-number")
oldFormats = cleanIncompatibleFormats(oldFormats, "colored-tab", "tab")
oldFormats = cleanIncompatibleFormats(oldFormats, "junit-xml-extended", "junit-xml")
for _, format := range oldFormats {
switch ptr.Deref(format.Format) {
case "colored-line-number":
formats.Text.PrintLinterName = old.Output.PrintLinterName
formats.Text.PrintIssuedLine = old.Output.PrintIssuedLine
formats.Text.Colors = nil // color is true by default (flags).
formats.Text.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "line-number":
formats.Text.PrintLinterName = old.Output.PrintLinterName
formats.Text.PrintIssuedLine = old.Output.PrintIssuedLine
formats.Text.Colors = ptr.Pointer(false)
formats.Text.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "json":
formats.JSON.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "colored-tab":
formats.Tab.PrintLinterName = old.Output.PrintLinterName
formats.Tab.Colors = nil // Colors is true by default (flags).
formats.Tab.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "tab":
formats.Tab.PrintLinterName = old.Output.PrintLinterName
formats.Tab.Colors = ptr.Pointer(false)
formats.Tab.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "html":
formats.HTML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "checkstyle":
formats.Checkstyle.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "code-climate":
formats.CodeClimate.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "junit-xml":
formats.JUnitXML.Extended = nil // Extended is false by default.
formats.JUnitXML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "junit-xml-extended":
formats.JUnitXML.Extended = ptr.Pointer(true)
formats.JUnitXML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "github-actions":
// Ignored
case "teamcity":
formats.TeamCity.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
case "sarif":
formats.Sarif.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
}
}
return versiontwo.Output{
Formats: formats,
SortOrder: old.Output.SortOrder,
PathPrefix: old.Output.PathPrefix,
ShowStats: nil, // Enforce the new default. (nil -> omitempty -> true)
}
}
func defaultFormatPath(p string) string {
if p == "" {
return "stdout"
}
return p
}
func cleanIncompatibleFormats(old versionone.OutputFormats, f1, f2 string) versionone.OutputFormats {
index1 := slices.IndexFunc(old, func(format versionone.OutputFormat) bool {
return ptr.Deref(format.Format) == f1
})
index2 := slices.IndexFunc(old, func(format versionone.OutputFormat) bool {
return ptr.Deref(format.Format) == f2
})
if index1 >= 0 && index2 >= 0 {
return slices.Delete(old, index2, index2+1)
}
return old
}
================================================
FILE: pkg/commands/internal/migrate/migrate_run.go
================================================
package migrate
import (
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
)
func toRun(old *versionone.Config) versiontwo.Run {
var relativePathMode *string
if ptr.Deref(old.Run.RelativePathMode) != "cfg" {
// cfg is the new default.
relativePathMode = old.Run.RelativePathMode
}
var concurrency *int
if ptr.Deref(old.Run.Concurrency) != 0 {
// 0 is the new default
concurrency = old.Run.Concurrency
}
return versiontwo.Run{
Timeout: 0, // Enforce new default.
Concurrency: concurrency,
Go: old.Run.Go,
RelativePathMode: relativePathMode,
BuildTags: old.Run.BuildTags,
ModulesDownloadMode: old.Run.ModulesDownloadMode,
ExitCodeIfIssuesFound: old.Run.ExitCodeIfIssuesFound,
AnalyzeTests: old.Run.AnalyzeTests,
AllowParallelRunners: old.Run.AllowParallelRunners,
AllowSerialRunners: old.Run.AllowSerialRunners,
}
}
================================================
FILE: pkg/commands/internal/migrate/migrate_severity.go
================================================
package migrate
import (
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
)
func toSeverity(old *versionone.Config) versiontwo.Severity {
var rules []versiontwo.SeverityRule
for _, rule := range old.Severity.Rules {
names := convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters))
if len(rule.Linters) > 0 && len(names) == 0 {
continue
}
rules = append(rules, versiontwo.SeverityRule{
BaseRule: versiontwo.BaseRule{
Linters: names,
Path: rule.Path,
PathExcept: rule.PathExcept,
Text: rule.Text,
Source: rule.Source,
},
Severity: rule.Severity,
})
}
return versiontwo.Severity{
Default: old.Severity.Default,
Rules: rules,
}
}
================================================
FILE: pkg/commands/internal/migrate/migrate_test.go
================================================
package migrate
import (
"bytes"
"io/fs"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
)
type fakeFile struct {
bytes.Buffer
name string
}
func newFakeFile(name string) *fakeFile {
return &fakeFile{name: name}
}
func (f *fakeFile) Name() string {
return f.name
}
func TestToConfig(t *testing.T) {
var testFiles []string
err := filepath.WalkDir("testdata", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
if strings.Contains(path, ".golden.") {
return nil
}
testFiles = append(testFiles, path)
return nil
})
require.NoError(t, err)
for _, fileIn := range testFiles {
t.Run(fileIn, func(t *testing.T) {
t.Parallel()
ext := filepath.Ext(fileIn)
fileGolden := strings.TrimSuffix(fileIn, ext) + ".golden" + ext
testFile(t, fileIn, fileGolden, false)
})
}
}
func testFile(t *testing.T, in, golden string, update bool) {
t.Helper()
old := versionone.NewConfig()
// Fake load of the configuration.
// IMPORTANT: The default values from flags are not set.
err := fakeloader.Load(in, old)
require.NoError(t, err)
if update {
updateGolden(t, golden, old)
}
buf := newFakeFile("test" + filepath.Ext(golden))
err = parser.Encode(ToConfig(old), buf)
require.NoError(t, err)
expected, err := os.ReadFile(golden)
require.NoError(t, err)
switch filepath.Ext(golden) {
case ".yml":
assert.YAMLEq(t, string(expected), buf.String())
case ".json":
assert.JSONEq(t, string(expected), buf.String())
case ".toml":
assert.Equal(t, string(expected), buf.String())
default:
require.Failf(t, "unsupported extension: %s", golden)
}
}
func updateGolden(t *testing.T, golden string, old *versionone.Config) {
t.Helper()
fileOut, err := os.Create(golden)
require.NoError(t, err)
defer func() {
_ = fileOut.Close()
}()
err = parser.Encode(ToConfig(old), fileOut)
require.NoError(t, err)
}
================================================
FILE: pkg/commands/internal/migrate/parser/parser.go
================================================
package parser
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"path/filepath"
"strings"
"github.com/pelletier/go-toml/v2"
"go.yaml.in/yaml/v3"
)
type File interface {
io.ReadWriter
Name() string
}
// Decode decodes a file into data.
// The choice of the decoder is based on the file extension.
func Decode(file File, data any) error {
ext := filepath.Ext(file.Name())
switch strings.ToLower(ext) {
case ".yaml", ".yml", ".json":
err := yaml.NewDecoder(file).Decode(data)
if err != nil && !errors.Is(err, io.EOF) {
return fmt.Errorf("YAML decode file %s: %w", file.Name(), err)
}
case ".toml":
err := toml.NewDecoder(file).Decode(&data)
if err != nil {
return fmt.Errorf("TOML decode file %s: %w", file.Name(), err)
}
default:
return fmt.Errorf("unsupported file type: %s", ext)
}
return nil
}
// Encode encodes data into a file.
// The choice of the encoder is based on the file extension.
func Encode(data any, dstFile File) error {
ext := filepath.Ext(dstFile.Name())
switch strings.ToLower(ext) {
case ".yml", ".yaml":
encoder := yaml.NewEncoder(dstFile)
encoder.SetIndent(2)
return encoder.Encode(data)
case ".toml":
encoder := toml.NewEncoder(dstFile)
return encoder.Encode(data)
case ".json":
// The JSON encoder converts empty struct to `{}` instead of nothing (even with omitempty JSON struct tags).
// So we need to use the YAML encoder as bridge to create JSON file.
var buf bytes.Buffer
err := yaml.NewEncoder(&buf).Encode(data)
if err != nil {
return err
}
raw := map[string]any{}
err = yaml.NewDecoder(&buf).Decode(raw)
if err != nil {
return err
}
encoder := json.NewEncoder(dstFile)
encoder.SetIndent("", " ")
return encoder.Encode(raw)
default:
return fmt.Errorf("unsupported file type: %s", ext)
}
}
================================================
FILE: pkg/commands/internal/migrate/ptr/ptr.go
================================================
package ptr
func Deref[T any](v *T) T {
if v == nil {
var zero T
return zero
}
return *v
}
func Pointer[T any](v T) *T { return &v }
================================================
FILE: pkg/commands/internal/migrate/testdata/json/empty.golden.json
================================================
{
"formatters": {
"exclusions": {
"generated": "lax",
"paths": [
"third_party$",
"builtin$",
"examples$"
]
}
},
"linters": {
"exclusions": {
"generated": "lax",
"paths": [
"third_party$",
"builtin$",
"examples$"
],
"presets": [
"comments",
"common-false-positives",
"legacy",
"std-error-handling"
]
}
},
"version": "2"
}
================================================
FILE: pkg/commands/internal/migrate/testdata/json/empty.json
================================================
================================================
FILE: pkg/commands/internal/migrate/testdata/toml/empty.golden.toml
================================================
version = '2'
[linters]
[linters.exclusions]
generated = 'lax'
presets = [
'comments',
'common-false-positives',
'legacy',
'std-error-handling'
]
paths = [
'third_party$',
'builtin$',
'examples$'
]
[formatters]
[formatters.exclusions]
generated = 'lax'
paths = [
'third_party$',
'builtin$',
'examples$'
]
================================================
FILE: pkg/commands/internal/migrate/testdata/toml/empty.toml
================================================
================================================
FILE: pkg/commands/internal/migrate/testdata/toml/linters-settings_goheader.golden.toml
================================================
version = '2'
[linters]
[linters.settings]
[linters.settings.goheader]
template = """
Put here copyright header template for source code files
For example:
Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
{{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the \"License\");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an \"AS IS\" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
"""
template-path = '/path/to/my/template.tmpl'
[linters.settings.goheader.values]
[linters.settings.goheader.values.const]
COMPANY = 'MY COMPANY'
[linters.settings.goheader.values.regexp]
AUTHOR = '.*@mycompany\.com'
================================================
FILE: pkg/commands/internal/migrate/testdata/toml/linters-settings_goheader.toml
================================================
[issues]
# Only to not generate unrelated elements inside golden.
exclude-use-default = false
# Only to not generate unrelated elements inside golden.
exclude-generated = "strict"
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default = false
[linters-settings]
[linters-settings.goheader]
template = """
Put here copyright header template for source code files
For example:
Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
{{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
"""
template-path = "/path/to/my/template.tmpl"
[linters-settings.goheader.values]
[linters-settings.goheader.values.const]
COMPANY = "MY COMPANY"
[linters-settings.goheader.values.regexp]
AUTHOR = ".*@mycompany\\.com"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/empty.golden.yml
================================================
version: "2"
linters:
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- third_party$
- builtin$
- examples$
formatters:
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/empty.yml
================================================
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_01_a.golden.yml
================================================
version: "2"
linters:
exclusions:
paths:
- .*\.my\.go$
- lib/bad.go
- src/external_libs
- autogenerated_by_my_lib
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_01_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-dirs:
- src/external_libs
- autogenerated_by_my_lib
exclude-files:
- ".*\\.my\\.go$"
- lib/bad.go
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_01_b.golden.yml
================================================
version: "2"
linters:
exclusions:
paths:
- .*\.my\.go$
- lib/bad.go
- src/external_libs
- autogenerated_by_my_lib
formatters:
enable:
- gofmt
exclusions:
paths:
- .*\.my\.go$
- lib/bad.go
- src/external_libs
- autogenerated_by_my_lib
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_01_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-dirs:
- src/external_libs
- autogenerated_by_my_lib
exclude-files:
- ".*\\.my\\.go$"
- lib/bad.go
linters:
enable:
- gofmt
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_02_a.golden.yml
================================================
version: "2"
linters:
exclusions:
rules:
- path: (.+)\.go$
text: abcdef
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_02_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-case-sensitive: false
exclude:
- abcdef
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_02_b.golden.yml
================================================
version: "2"
linters:
exclusions:
rules:
- path: (.+)\.go$
text: (?i)abcdef
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_02_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-case-sensitive: true
exclude:
- abcdef
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_04_a.golden.yml
================================================
version: "2"
linters:
exclusions:
rules:
- linters:
- dupl
- errcheck
- gocyclo
- gosec
path: _test\.go
- linters:
- staticcheck
path-except: _test\.go
- linters:
- gosec
path: internal/hmac/
text: weak cryptographic primitive
- linters:
- staticcheck
text: 'SA9003:'
- linters:
- staticcheck
text: 'ST1006:'
- linters:
- staticcheck
text: 'S1033:'
- linters:
- lll
source: '^//go:generate '
- linters:
- err113
source: foo
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_04_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-case-sensitive: false
exclude-rules:
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- path-except: _test\.go
linters:
- staticcheck
- stylecheck
- gosimple
- path: internal/hmac/
text: "weak cryptographic primitive"
linters:
- gosec
- linters:
- staticcheck
text: "SA9003:"
- linters:
- stylecheck
text: "ST1006:"
- linters:
- gosimple
text: "S1033:"
- linters:
- lll
source: "^//go:generate "
- linters:
- goerr113
source: "foo"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_04_b.golden.yml
================================================
version: "2"
linters:
exclusions:
rules:
- linters:
- dupl
- errcheck
- gocyclo
- gosec
path: _test\.go
- linters:
- staticcheck
path-except: _test\.go
- linters:
- gosec
path: internal/hmac/
text: (?i)weak cryptographic primitive
- linters:
- staticcheck
text: '(?i)SA9003:'
- linters:
- staticcheck
text: '(?i)ST1006:'
- linters:
- staticcheck
text: '(?i)S1033:'
- linters:
- lll
source: '(?i)^//go:generate '
- linters:
- err113
source: (?i)foo
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_04_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-case-sensitive: true
exclude-rules:
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- path-except: _test\.go
linters:
- staticcheck
- stylecheck
- gosimple
- path: internal/hmac/
text: "weak cryptographic primitive"
linters:
- gosec
- linters:
- staticcheck
text: "SA9003:"
- linters:
- stylecheck
text: "ST1006:"
- linters:
- gosimple
text: "S1033:"
- linters:
- lll
source: "^//go:generate "
- linters:
- goerr113
source: "foo"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_04_c.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_04_c.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-case-sensitive: true
exclude-rules:
- path: _test\.go
linters:
- typecheck
- path-except: _test\.go
linters:
- typecheck
- path: internal/hmac/
text: "weak cryptographic primitive"
linters:
- typecheck
- linters:
- typecheck
text: "SA9003:"
- linters:
- typecheck
source: "foo"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_05_a.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_05_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-generated: strict
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_05_b.golden.yml
================================================
version: "2"
linters:
exclusions:
generated: disable
formatters:
exclusions:
generated: disable
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_05_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-generated: disable
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_05_c.golden.yml
================================================
version: "2"
linters:
exclusions:
generated: lax
formatters:
exclusions:
generated: lax
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_05_c.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-generated: lax
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_a.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-use-default: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_b.golden.yml
================================================
version: "2"
linters:
exclusions:
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-use-default: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_c.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_c.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-use-default: true
# all
include:
- EXC0001
- EXC0002
- EXC0003
- EXC0004
- EXC0005
- EXC0006
- EXC0007
- EXC0008
- EXC0009
- EXC0010
- EXC0011
- EXC0012
- EXC0013
- EXC0014
- EXC0015
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_d.golden.yml
================================================
version: "2"
linters:
exclusions:
presets:
- common-false-positives
- legacy
- std-error-handling
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_d.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-use-default: true
# Related to comments
include:
- EXC0014
- EXC0015
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_e.golden.yml
================================================
version: "2"
linters:
exclusions:
presets:
- comments
- common-false-positives
- std-error-handling
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_e.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-use-default: true
# Related to legacy
include:
- EXC0005
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_f.golden.yml
================================================
version: "2"
linters:
exclusions:
presets:
- comments
- common-false-positives
- legacy
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_f.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-use-default: true
# Related to std-error-handling
include:
- EXC0001
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_g.golden.yml
================================================
version: "2"
linters:
exclusions:
presets:
- comments
- legacy
- std-error-handling
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_g.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-use-default: true
# Related to common-false-positives
include:
- EXC0006
- EXC0007
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_h.golden.yml
================================================
version: "2"
linters:
exclusions:
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_06_h.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_07_a.golden.yml
================================================
version: "2"
linters:
exclusions:
paths:
- third_party$
- builtin$
- examples$
formatters:
exclusions:
paths:
- third_party$
- builtin$
- examples$
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_07_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
exclude-dirs-use-default: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_07_b.golden.yml
================================================
version: "2"
linters:
default: none
exclusions:
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- goimports
exclusions:
paths:
- third_party$
- builtin$
- examples$
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_07_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
exclude-dirs-use-default: true
linters:
disable-all: true
enable:
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_08_a.golden.yml
================================================
version: "2"
issues:
max-issues-per-linter: 0
max-same-issues: 0
uniq-by-line: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_08_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
uniq-by-line: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_08_b.golden.yml
================================================
version: "2"
issues:
max-issues-per-linter: 66
uniq-by-line: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_08_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
max-issues-per-linter: 66
uniq-by-line: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_09_a.golden.yml
================================================
version: "2"
issues:
new-from-rev: HEAD
new-from-merge-base: main
new-from-patch: path/to/patch/file
whole-files: true
new: true
fix: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_09_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
new: true
new-from-merge-base: main
new-from-rev: HEAD
new-from-patch: path/to/patch/file
whole-files: true
fix: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_09_b.golden.yml
================================================
version: "2"
issues:
new-from-rev: ""
new-from-merge-base: ""
new-from-patch: ""
whole-files: false
new: false
fix: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_09_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
new: false
new-from-merge-base: ''
new-from-rev: ''
new-from-patch: ''
whole-files: false
fix: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_10.golden.yml
================================================
version: "2"
linters:
default: none
formatters:
enable:
- goimports
exclusions:
paths:
- \.(generated\.deepcopy|pb)\.go$
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/issues_10.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
exclude-rules:
- path: "\\.(generated\\.deepcopy|pb)\\.go$"
linters:
- goimports
linters:
disable-all: true
enable:
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_asasalint.golden.yml
================================================
version: "2"
linters:
settings:
asasalint:
exclude:
- Append
- \.Wrapf
use-builtin-exclusions: false
exclusions:
rules:
- linters:
- asasalint
path: (.+)_test\.go
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_asasalint.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
asasalint:
exclude:
- Append
- \.Wrapf
use-builtin-exclusions: false
ignore-test: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_bidichk.golden.yml
================================================
version: "2"
linters:
settings:
bidichk:
left-to-right-embedding: true
right-to-left-embedding: false
pop-directional-formatting: false
left-to-right-override: false
right-to-left-override: false
left-to-right-isolate: false
right-to-left-isolate: false
first-strong-isolate: false
pop-directional-isolate: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_bidichk.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
bidichk:
left-to-right-embedding: true
right-to-left-embedding: false
pop-directional-formatting: false
left-to-right-override: false
right-to-left-override: false
left-to-right-isolate: false
right-to-left-isolate: false
first-strong-isolate: false
pop-directional-isolate: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_copyloopvar.golden.yml
================================================
version: "2"
linters:
settings:
copyloopvar:
check-alias: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_copyloopvar.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
copyloopvar:
check-alias: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_custom.golden.yml
================================================
version: "2"
linters:
settings:
custom:
example:
type: module
path: /path/to/example.so
description: This is an example usage of a plugin linter.
original-url: github.com/golangci/example-linter
settings:
foo: bar
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_custom.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
custom:
example:
type: module
path: /path/to/example.so
description: This is an example usage of a plugin linter.
original-url: github.com/golangci/example-linter
settings:
foo: bar
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_cyclop.golden.yml
================================================
version: "2"
linters:
settings:
cyclop:
max-complexity: 10
package-average: 0.5
exclusions:
rules:
- linters:
- cyclop
path: (.+)_test\.go
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_cyclop.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
cyclop:
max-complexity: 10
package-average: 0.5
skip-tests: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_decorder.golden.yml
================================================
version: "2"
linters:
settings:
decorder:
dec-order:
- type
- const
- var
- func
ignore-underscore-vars: false
disable-dec-num-check: false
disable-type-dec-num-check: false
disable-const-dec-num-check: false
disable-var-dec-num-check: false
disable-dec-order-check: false
disable-init-func-first-check: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_decorder.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
decorder:
dec-order:
- type
- const
- var
- func
ignore-underscore-vars: false
disable-dec-order-check: false
disable-init-func-first-check: false
disable-dec-num-check: false
disable-type-dec-num-check: false
disable-const-dec-num-check: false
disable-var-dec-num-check: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_depguard.golden.yml
================================================
version: "2"
linters:
settings:
depguard:
rules:
main:
list-mode: lax
files:
- '!**/*_a _file.go'
allow:
- $gostd
- github.com/OpenPeeDeeP
deny:
- pkg: math/rand$
desc: use math/rand/v2
- pkg: github.com/sirupsen/logrus
desc: not allowed
- pkg: github.com/pkg/errors
desc: Should be replaced by standard lib errors package
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_depguard.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
depguard:
rules:
main:
list-mode: lax
files:
- "!**/*_a _file.go"
allow:
- $gostd
- github.com/OpenPeeDeeP
deny:
- pkg: "math/rand$"
desc: use math/rand/v2
- pkg: "github.com/sirupsen/logrus"
desc: not allowed
- pkg: "github.com/pkg/errors"
desc: Should be replaced by standard lib errors package
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_dogsled.golden.yml
================================================
version: "2"
linters:
settings:
dogsled:
max-blank-identifiers: 3
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_dogsled.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
dogsled:
max-blank-identifiers: 3
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_dupl.golden.yml
================================================
version: "2"
linters:
settings:
dupl:
threshold: 100
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_dupl.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
dupl:
threshold: 100
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_dupword.golden.yml
================================================
version: "2"
linters:
settings:
dupword:
keywords:
- the
- and
- a
ignore:
- 0C0C
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_dupword.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
dupword:
keywords:
- "the"
- "and"
- "a"
ignore:
- "0C0C"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_errcheck.golden.yml
================================================
version: "2"
linters:
settings:
errcheck:
disable-default-exclusions: true
check-type-assertions: true
check-blank: true
exclude-functions:
- io/ioutil.ReadFile
- io.Copy(*bytes.Buffer)
- io.Copy(os.Stdout)
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_errcheck.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
errcheck:
check-type-assertions: true
check-blank: true
disable-default-exclusions: true
exclude-functions:
- io/ioutil.ReadFile
- io.Copy(*bytes.Buffer)
- io.Copy(os.Stdout)
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_errchkjson.golden.yml
================================================
version: "2"
linters:
settings:
errchkjson:
check-error-free-encoding: true
report-no-exported: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_errchkjson.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
errchkjson:
check-error-free-encoding: true
report-no-exported: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_errorlint.golden.yml
================================================
version: "2"
linters:
settings:
errorlint:
errorf: false
errorf-multi: false
asserts: false
comparison: false
allowed-errors:
- err: io.EOF
fun: example.com/pkg.Read
allowed-errors-wildcard:
- err: example.com/pkg.ErrMagic
fun: example.com/pkg.Magic
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_errorlint.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
errorlint:
errorf: false
errorf-multi: false
asserts: false
comparison: false
allowed-errors:
- err: "io.EOF"
fun: "example.com/pkg.Read"
allowed-errors-wildcard:
- err: "example.com/pkg.ErrMagic"
fun: "example.com/pkg.Magic"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_exhaustive.golden.yml
================================================
version: "2"
linters:
settings:
exhaustive:
check:
- switch
- map
default-signifies-exhaustive: true
ignore-enum-members: Example.+
ignore-enum-types: Example.+
package-scope-only: true
explicit-exhaustive-map: true
explicit-exhaustive-switch: true
default-case-required: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_exhaustive.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
exhaustive:
check:
- switch
- map
check-generated: true
default-signifies-exhaustive: true
ignore-enum-members: "Example.+"
ignore-enum-types: "Example.+"
package-scope-only: true
explicit-exhaustive-switch: true
explicit-exhaustive-map: true
default-case-required: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_exhaustruct.golden.yml
================================================
version: "2"
linters:
settings:
exhaustruct:
include:
- .+\.Test
- example\.com/package\.ExampleStruct[\d]{1,2}
exclude:
- .+/cobra\.Command$
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_exhaustruct.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
exhaustruct:
include:
- '.+\.Test'
- 'example\.com/package\.ExampleStruct[\d]{1,2}'
exclude:
- '.+/cobra\.Command$'
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_fatcontext.golden.yml
================================================
version: "2"
linters:
settings:
fatcontext:
check-struct-pointers: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_fatcontext.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
fatcontext:
check-struct-pointers: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_forbidigo.golden.yml
================================================
version: "2"
linters:
settings:
forbidigo:
forbid:
- pattern: ^print(ln)?$
- pattern: ^fmt\.Print.*$
msg: Do not commit print statements.
- pattern: fmt\.Print.*(# Do not commit print statements\.)?
- pattern: ^spew\.(ConfigState\.)?Dump$
- pattern: ^v1.Dump$
pkg: ^example.com/pkg/api/v1$
- pkg: ^github.com/howeyc/gopass$
msg: github.com/howeyc/gopass is archived, use golang.org/x/term instead
exclude-godoc-examples: false
analyze-types: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_forbidigo.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
forbidigo:
forbid:
- ^print(ln)?$
- p: ^fmt\.Print.*$
msg: Do not commit print statements.
- 'fmt\.Print.*(# Do not commit print statements\.)?'
- ^spew\.(ConfigState\.)?Dump$
- p: ^v1.Dump$
pkg: ^example.com/pkg/api/v1$
- pkg: ^github.com/howeyc/gopass$
msg: "github.com/howeyc/gopass is archived, use golang.org/x/term instead"
exclude-godoc-examples: false
analyze-types: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_funlen.golden.yml
================================================
version: "2"
linters:
settings:
funlen:
lines: -1
statements: -1
ignore-comments: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_funlen.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
funlen:
lines: -1
statements: -1
ignore-comments: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gci.golden.yml
================================================
version: "2"
formatters:
settings:
gci:
sections:
- standard
- default
- prefix(github.com/org/project)
- blank
- dot
- alias
- localmodule
no-inline-comments: true
no-prefix-comments: true
custom-order: true
no-lex-order: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gci.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gci:
sections:
- standard
- default
- prefix(github.com/org/project)
- blank
- dot
- alias
- localmodule
no-inline-comments: true
no-prefix-comments: true
skip-generated: false
custom-order: true
no-lex-order: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_ginkgolinter.golden.yml
================================================
version: "2"
linters:
settings:
ginkgolinter:
suppress-len-assertion: true
suppress-nil-assertion: true
suppress-err-assertion: true
suppress-compare-assertion: true
suppress-async-assertion: true
suppress-type-compare-assertion: true
forbid-focus-container: true
allow-havelen-zero: true
force-expect-to: true
validate-async-intervals: true
forbid-spec-pollution: true
force-succeed: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_ginkgolinter.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
ginkgolinter:
suppress-len-assertion: true
suppress-nil-assertion: true
suppress-err-assertion: true
suppress-compare-assertion: true
suppress-async-assertion: true
suppress-type-compare-assertion: true
forbid-focus-container: true
allow-havelen-zero: true
force-expect-to: true
validate-async-intervals: true
forbid-spec-pollution: true
force-succeed: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gochecksumtype.golden.yml
================================================
version: "2"
linters:
settings:
gochecksumtype:
default-signifies-exhaustive: false
include-shared-interfaces: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gochecksumtype.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gochecksumtype:
default-signifies-exhaustive: false
include-shared-interfaces: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gocognit.golden.yml
================================================
version: "2"
linters:
settings:
gocognit:
min-complexity: 10
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gocognit.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gocognit:
min-complexity: 10
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_goconst.golden.yml
================================================
version: "2"
linters:
settings:
goconst:
ignore-strings: foo.+
match-constant: false
min-len: 2
min-occurrences: 2
numbers: true
min: 2
max: 2
ignore-calls: false
exclusions:
rules:
- linters:
- goconst
path: (.+)_test\.go
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_goconst.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
goconst:
min-len: 2
min-occurrences: 2
ignore-tests: true
match-constant: false
numbers: true
min: 2
max: 2
ignore-calls: false
ignore-strings: 'foo.+'
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gocritic.golden.yml
================================================
version: "2"
linters:
settings:
gocritic:
disable-all: true
enabled-checks:
- appendAssign
- appendCombine
- argOrder
- assignOp
- badCall
- badCond
- badLock
- badRegexp
- badSorting
- badSyncOnceFunc
- boolExprSimplify
- builtinShadow
- builtinShadowDecl
- captLocal
- caseOrder
- codegenComment
- commentFormatting
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deferInLoop
- deferUnlambda
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupImport
- dupSubExpr
- dynamicFmtString
- elseif
- emptyDecl
- emptyFallthrough
- emptyStringTest
- equalFold
- evalOrder
- exitAfterDefer
- exposedSyncMutex
- externalErrorReassign
- filepathJoin
- flagDeref
- flagName
- hexLiteral
- httpNoBody
- hugeParam
- ifElseChain
- importShadow
- indexAlloc
- initClause
- mapKey
- methodExprCall
- nestingReduce
- newDeref
- nilValReturn
- octalLiteral
- offBy1
- paramTypeCombine
- preferDecodeRune
- preferFilepathJoin
- preferFprint
- preferStringWriter
- preferWriteByte
- ptrToRefParam
- rangeAppendAll
- rangeExprCopy
- rangeValCopy
- redundantSprint
- regexpMust
- regexpPattern
- regexpSimplify
- returnAfterHttpError
- ruleguard
- singleCaseSwitch
- sliceClear
- sloppyLen
- sloppyReassign
- sloppyTypeAssert
- sortSlice
- sprintfQuotedString
- sqlQuery
- stringConcatSimplify
- stringXbytes
- stringsCompare
- switchTrue
- syncMapLoadAndDelete
- timeExprSimplify
- todoCommentWithoutDetail
- tooManyResultsChecker
- truncateCmp
- typeAssertChain
- typeDefFirst
- typeSwitchVar
- typeUnparen
- uncheckedInlineErr
- underef
- unlabelStmt
- unlambda
- unnamedResult
- unnecessaryBlock
- unnecessaryDefer
- unslice
- valSwap
- weakCond
- whyNoLint
- wrapperFunc
- yodaStyleExpr
enable-all: true
disabled-checks:
- appendAssign
- appendCombine
- argOrder
- assignOp
- badCall
- badCond
- badLock
- badRegexp
- badSorting
- badSyncOnceFunc
- boolExprSimplify
- builtinShadow
- builtinShadowDecl
- captLocal
- caseOrder
- codegenComment
- commentFormatting
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deferInLoop
- deferUnlambda
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupImport
- dupSubExpr
- dynamicFmtString
- elseif
- emptyDecl
- emptyFallthrough
- emptyStringTest
- equalFold
- evalOrder
- exitAfterDefer
- exposedSyncMutex
- externalErrorReassign
- filepathJoin
- flagDeref
- flagName
- hexLiteral
- httpNoBody
- hugeParam
- ifElseChain
- importShadow
- indexAlloc
- initClause
- mapKey
- methodExprCall
- nestingReduce
- newDeref
- nilValReturn
- octalLiteral
- offBy1
- paramTypeCombine
- preferDecodeRune
- preferFilepathJoin
- preferFprint
- preferStringWriter
- preferWriteByte
- ptrToRefParam
- rangeAppendAll
- rangeExprCopy
- rangeValCopy
- redundantSprint
- regexpMust
- regexpPattern
- regexpSimplify
- returnAfterHttpError
- ruleguard
- singleCaseSwitch
- sliceClear
- sloppyLen
- sloppyReassign
- sloppyTypeAssert
- sortSlice
- sprintfQuotedString
- sqlQuery
- stringConcatSimplify
- stringXbytes
- stringsCompare
- switchTrue
- syncMapLoadAndDelete
- timeExprSimplify
- todoCommentWithoutDetail
- tooManyResultsChecker
- truncateCmp
- typeAssertChain
- typeDefFirst
- typeSwitchVar
- typeUnparen
- uncheckedInlineErr
- underef
- unlabelStmt
- unlambda
- unnamedResult
- unnecessaryBlock
- unnecessaryDefer
- unslice
- valSwap
- weakCond
- whyNoLint
- wrapperFunc
- yodaStyleExpr
enabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
disabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
settings:
captLocal:
paramsOnly: false
commentedOutCode:
minLength: 50
elseif:
skipBalanced: false
hugeParam:
sizeThreshold: 70
ifElseChain:
minThreshold: 4
nestingReduce:
bodyWidth: 4
rangeExprCopy:
sizeThreshold: 516
skipTestFuncs: false
rangeValCopy:
sizeThreshold: 32
skipTestFuncs: false
ruleguard:
debug: emptyDecl
disable: myGroupName,#myTagName
enable: myGroupName,#myTagName
failOn: dsl,import
rules: ${base-path}/ruleguard/rules-*.go,${base-path}/myrule1.go
tooManyResultsChecker:
maxResults: 10
truncateCmp:
skipArchDependent: false
underef:
skipRecvDeref: false
unnamedResult:
checkExported: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gocritic.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gocritic:
disable-all: true
enabled-checks:
- appendAssign
- appendCombine
- argOrder
- assignOp
- badCall
- badCond
- badLock
- badRegexp
- badSorting
- badSyncOnceFunc
- boolExprSimplify
- builtinShadow
- builtinShadowDecl
- captLocal
- caseOrder
- codegenComment
- commentFormatting
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deferInLoop
- deferUnlambda
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupImport
- dupSubExpr
- dynamicFmtString
- elseif
- emptyDecl
- emptyFallthrough
- emptyStringTest
- equalFold
- evalOrder
- exitAfterDefer
- exposedSyncMutex
- externalErrorReassign
- filepathJoin
- flagDeref
- flagName
- hexLiteral
- httpNoBody
- hugeParam
- ifElseChain
- importShadow
- indexAlloc
- initClause
- mapKey
- methodExprCall
- nestingReduce
- newDeref
- nilValReturn
- octalLiteral
- offBy1
- paramTypeCombine
- preferDecodeRune
- preferFilepathJoin
- preferFprint
- preferStringWriter
- preferWriteByte
- ptrToRefParam
- rangeAppendAll
- rangeExprCopy
- rangeValCopy
- redundantSprint
- regexpMust
- regexpPattern
- regexpSimplify
- returnAfterHttpError
- ruleguard
- singleCaseSwitch
- sliceClear
- sloppyLen
- sloppyReassign
- sloppyTypeAssert
- sortSlice
- sprintfQuotedString
- sqlQuery
- stringConcatSimplify
- stringXbytes
- stringsCompare
- switchTrue
- syncMapLoadAndDelete
- timeExprSimplify
- todoCommentWithoutDetail
- tooManyResultsChecker
- truncateCmp
- typeAssertChain
- typeDefFirst
- typeSwitchVar
- typeUnparen
- uncheckedInlineErr
- underef
- unlabelStmt
- unlambda
- unnamedResult
- unnecessaryBlock
- unnecessaryDefer
- unslice
- valSwap
- weakCond
- whyNoLint
- wrapperFunc
- yodaStyleExpr
enable-all: true
disabled-checks:
- appendAssign
- appendCombine
- argOrder
- assignOp
- badCall
- badCond
- badLock
- badRegexp
- badSorting
- badSyncOnceFunc
- boolExprSimplify
- builtinShadow
- builtinShadowDecl
- captLocal
- caseOrder
- codegenComment
- commentFormatting
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deferInLoop
- deferUnlambda
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupImport
- dupSubExpr
- dynamicFmtString
- elseif
- emptyDecl
- emptyFallthrough
- emptyStringTest
- equalFold
- evalOrder
- exitAfterDefer
- exposedSyncMutex
- externalErrorReassign
- filepathJoin
- flagDeref
- flagName
- hexLiteral
- httpNoBody
- hugeParam
- ifElseChain
- importShadow
- indexAlloc
- initClause
- mapKey
- methodExprCall
- nestingReduce
- newDeref
- nilValReturn
- octalLiteral
- offBy1
- paramTypeCombine
- preferDecodeRune
- preferFilepathJoin
- preferFprint
- preferStringWriter
- preferWriteByte
- ptrToRefParam
- rangeAppendAll
- rangeExprCopy
- rangeValCopy
- redundantSprint
- regexpMust
- regexpPattern
- regexpSimplify
- returnAfterHttpError
- ruleguard
- singleCaseSwitch
- sliceClear
- sloppyLen
- sloppyReassign
- sloppyTypeAssert
- sortSlice
- sprintfQuotedString
- sqlQuery
- stringConcatSimplify
- stringXbytes
- stringsCompare
- switchTrue
- syncMapLoadAndDelete
- timeExprSimplify
- todoCommentWithoutDetail
- tooManyResultsChecker
- truncateCmp
- typeAssertChain
- typeDefFirst
- typeSwitchVar
- typeUnparen
- uncheckedInlineErr
- underef
- unlabelStmt
- unlambda
- unnamedResult
- unnecessaryBlock
- unnecessaryDefer
- unslice
- valSwap
- weakCond
- whyNoLint
- wrapperFunc
- yodaStyleExpr
enabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
disabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
settings:
captLocal:
paramsOnly: false
commentedOutCode:
minLength: 50
elseif:
skipBalanced: false
hugeParam:
sizeThreshold: 70
ifElseChain:
minThreshold: 4
nestingReduce:
bodyWidth: 4
rangeExprCopy:
sizeThreshold: 516
skipTestFuncs: false
rangeValCopy:
sizeThreshold: 32
skipTestFuncs: false
ruleguard:
debug: 'emptyDecl'
failOn: dsl,import
rules: '${configDir}/ruleguard/rules-*.go,${configDir}/myrule1.go'
enable: "myGroupName,#myTagName"
disable: "myGroupName,#myTagName"
tooManyResultsChecker:
maxResults: 10
truncateCmp:
skipArchDependent: false
underef:
skipRecvDeref: false
unnamedResult:
checkExported: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gocyclo.golden.yml
================================================
version: "2"
linters:
settings:
gocyclo:
min-complexity: 10
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gocyclo.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gocyclo:
min-complexity: 10
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_godot.golden.yml
================================================
version: "2"
linters:
settings:
godot:
scope: toplevel
exclude:
- '^fixme:'
- '^todo:'
capital: true
period: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_godot.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
godot:
scope: toplevel
exclude:
- "^fixme:"
- "^todo:"
period: false
capital: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_godox.golden.yml
================================================
version: "2"
linters:
settings:
godox:
keywords:
- NOTE
- OPTIMIZE
- HACK
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_godox.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
godox:
keywords:
- NOTE
- OPTIMIZE
- HACK
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gofmt.golden.yml
================================================
version: "2"
formatters:
settings:
gofmt:
simplify: false
rewrite-rules:
- pattern: interface{}
replacement: any
- pattern: a[b:len(a)]
replacement: a[b:]
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gofmt.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gofmt:
simplify: false
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
- pattern: 'a[b:len(a)]'
replacement: 'a[b:]'
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gofumpt.golden.yml
================================================
version: "2"
formatters:
settings:
gofumpt:
module-path: github.com/org/project
extra-rules: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gofumpt.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gofumpt:
module-path: github.com/org/project
extra-rules: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_goheader.golden.yml
================================================
version: "2"
linters:
settings:
goheader:
values:
const:
COMPANY: MY COMPANY
regexp:
AUTHOR: .*@mycompany\.com
template: |-
Put here copyright header template for source code files
For example:
Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
{{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
template-path: /path/to/my/template.tmpl
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_goheader.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
goheader:
values:
const:
COMPANY: MY COMPANY
regexp:
AUTHOR: .*@mycompany\.com
template: |-
Put here copyright header template for source code files
For example:
Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
{{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
template-path: /path/to/my/template.tmpl
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_goimports.golden.yml
================================================
version: "2"
formatters:
settings:
goimports:
local-prefixes:
- github.com/org/project
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_goimports.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
goimports:
local-prefixes: github.com/org/project
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gomoddirectives.golden.yml
================================================
version: "2"
linters:
settings:
gomoddirectives:
replace-allow-list:
- launchpad.net/gocheck
replace-local: true
exclude-forbidden: true
retract-allow-no-explanation: true
toolchain-forbidden: true
toolchain-pattern: go1\.23\.\d+$
tool-forbidden: true
go-debug-forbidden: true
go-version-pattern: \d\.\d+(\.0)?
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gomoddirectives.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gomoddirectives:
replace-local: true
replace-allow-list:
- launchpad.net/gocheck
retract-allow-no-explanation: true
exclude-forbidden: true
toolchain-forbidden: true
toolchain-pattern: 'go1\.23\.\d+$'
tool-forbidden: true
go-debug-forbidden: true
go-version-pattern: '\d\.\d+(\.0)?'
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gomodguard.golden.yml
================================================
version: "2"
linters:
settings:
gomodguard:
allowed:
modules:
- gopkg.in/yaml.v2
domains:
- golang.org
blocked:
modules:
- github.com/uudashr/go-module:
recommendations:
- golang.org/x/mod
reason: '`mod` is the official go.mod parser library.'
versions:
- github.com/mitchellh/go-homedir:
version: < 1.1.0
reason: testing if blocked version constraint works.
local-replace-directives: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gomodguard.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gomodguard:
allowed:
modules:
- gopkg.in/yaml.v2
domains:
- golang.org
blocked:
modules:
- github.com/uudashr/go-module:
recommendations:
- golang.org/x/mod
reason: "`mod` is the official go.mod parser library."
versions:
- github.com/mitchellh/go-homedir:
version: "< 1.1.0"
reason: "testing if blocked version constraint works."
local_replace_directives: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gosec.golden.yml
================================================
version: "2"
linters:
settings:
gosec:
includes:
- G101
- G102
- G103
- G104
- G106
- G107
- G108
- G109
- G110
- G111
- G112
- G113
- G114
- G115
- G201
- G202
- G203
- G204
- G301
- G302
- G303
- G304
- G305
- G306
- G307
- G401
- G402
- G403
- G404
- G405
- G406
- G501
- G502
- G503
- G504
- G505
- G506
- G507
- G601
- G602
excludes:
- G101
- G102
- G103
- G104
- G106
- G107
- G108
- G109
- G110
- G111
- G112
- G113
- G114
- G115
- G201
- G202
- G203
- G204
- G301
- G302
- G303
- G304
- G305
- G306
- G307
- G401
- G402
- G403
- G404
- G405
- G406
- G501
- G502
- G503
- G504
- G505
- G506
- G507
- G601
- G602
severity: medium
confidence: medium
config:
G101:
entropy_threshold: "80.0"
ignore_entropy: false
pattern: (?i)example
per_char_threshold: "3.0"
truncate: "32"
G104:
fmt:
- Fscanf
G111:
pattern: custom\.Dir\(\)
G301: "0750"
G302: "0600"
G306: "0600"
global:
'#nosec': '#my-custom-nosec'
audit: true
nosec: true
show-ignored: true
concurrency: 12
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gosec.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gosec:
includes:
- G101
- G102
- G103
- G104
- G106
- G107
- G108
- G109
- G110
- G111
- G112
- G113
- G114
- G115
- G201
- G202
- G203
- G204
- G301
- G302
- G303
- G304
- G305
- G306
- G307
- G401
- G402
- G403
- G404
- G405
- G406
- G501
- G502
- G503
- G504
- G505
- G506
- G507
- G601
- G602
excludes:
- G101
- G102
- G103
- G104
- G106
- G107
- G108
- G109
- G110
- G111
- G112
- G113
- G114
- G115
- G201
- G202
- G203
- G204
- G301
- G302
- G303
- G304
- G305
- G306
- G307
- G401
- G402
- G403
- G404
- G405
- G406
- G501
- G502
- G503
- G504
- G505
- G506
- G507
- G601
- G602
exclude-generated: true
severity: medium
confidence: medium
concurrency: 12
config:
global:
nosec: true
"#nosec": "#my-custom-nosec"
show-ignored: true
audit: true
G101:
pattern: "(?i)example"
ignore_entropy: false
entropy_threshold: "80.0"
per_char_threshold: "3.0"
truncate: "32"
G104:
fmt:
- Fscanf
G111:
pattern: "custom\\.Dir\\(\\)"
G301: "0750"
G302: "0600"
G306: "0600"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gosimple.golden.yml
================================================
version: "2"
linters:
settings:
staticcheck:
checks:
- S1000
- S1001
- S1002
- S1003
- S1004
- S1005
- S1006
- S1007
- S1008
- S1009
- S1010
- S1011
- S1012
- S1016
- S1017
- S1018
- S1019
- S1020
- S1021
- S1023
- S1024
- S1025
- S1028
- S1029
- S1030
- S1031
- S1032
- S1033
- S1034
- S1035
- S1036
- S1037
- S1038
- S1039
- S1040
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gosimple.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gosimple:
checks:
- S1000
- S1001
- S1002
- S1003
- S1004
- S1005
- S1006
- S1007
- S1008
- S1009
- S1010
- S1011
- S1012
- S1016
- S1017
- S1018
- S1019
- S1020
- S1021
- S1023
- S1024
- S1025
- S1028
- S1029
- S1030
- S1031
- S1032
- S1033
- S1034
- S1035
- S1036
- S1037
- S1038
- S1039
- S1040
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gosmopolitan.golden.yml
================================================
version: "2"
linters:
settings:
gosmopolitan:
allow-time-local: true
escape-hatches:
- github.com/nicksnyder/go-i18n/v2/i18n.Message
- example.com/your/project/i18n/markers.Raw
- example.com/your/project/i18n/markers.OK
- example.com/your/project/i18n/markers.TODO
- command-line-arguments.Simple
watch-for-scripts:
- Devanagari
- Han
- Hangul
- Hiragana
- Katakana
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_gosmopolitan.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
gosmopolitan:
allow-time-local: true
escape-hatches:
- 'github.com/nicksnyder/go-i18n/v2/i18n.Message'
- 'example.com/your/project/i18n/markers.Raw'
- 'example.com/your/project/i18n/markers.OK'
- 'example.com/your/project/i18n/markers.TODO'
- 'command-line-arguments.Simple'
ignore-tests: false
watch-for-scripts:
- Devanagari
- Han
- Hangul
- Hiragana
- Katakana
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_govet.golden.yml
================================================
version: "2"
linters:
settings:
govet:
enable:
- appends
- asmdecl
- assign
- atomic
- atomicalign
- bools
- buildtag
- cgocall
- composites
- copylocks
- deepequalerrors
- defers
- directive
- errorsas
- fieldalignment
- findcall
- framepointer
- httpresponse
- ifaceassert
- loopclosure
- lostcancel
- nilfunc
- nilness
- printf
- reflectvaluecompare
- shadow
- shift
- sigchanyzer
- slog
- sortslice
- stdmethods
- stdversion
- stringintconv
- structtag
- testinggoroutine
- tests
- timeformat
- unmarshal
- unreachable
- unsafeptr
- unusedresult
- unusedwrite
- waitgroup
disable:
- appends
- asmdecl
- assign
- atomic
- atomicalign
- bools
- buildtag
- cgocall
- composites
- copylocks
- deepequalerrors
- defers
- directive
- errorsas
- fieldalignment
- findcall
- framepointer
- httpresponse
- ifaceassert
- loopclosure
- lostcancel
- nilfunc
- nilness
- printf
- reflectvaluecompare
- shadow
- shift
- sigchanyzer
- slog
- sortslice
- stdmethods
- stdversion
- stringintconv
- structtag
- testinggoroutine
- tests
- timeformat
- unmarshal
- unreachable
- unsafeptr
- unusedresult
- unusedwrite
- waitgroup
enable-all: true
disable-all: true
settings:
printf:
funcs:
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
shadow:
strict: true
unusedresult:
funcs:
- pkg.MyFunc
stringmethods:
- MyMethod
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_govet.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
govet:
disable-all: true
enable:
- appends
- asmdecl
- assign
- atomic
- atomicalign
- bools
- buildtag
- cgocall
- composites
- copylocks
- deepequalerrors
- defers
- directive
- errorsas
- fieldalignment
- findcall
- framepointer
- httpresponse
- ifaceassert
- loopclosure
- lostcancel
- nilfunc
- nilness
- printf
- reflectvaluecompare
- shadow
- shift
- sigchanyzer
- slog
- sortslice
- stdmethods
- stdversion
- stringintconv
- structtag
- testinggoroutine
- tests
- timeformat
- unmarshal
- unreachable
- unsafeptr
- unusedresult
- unusedwrite
- waitgroup
enable-all: true
disable:
- appends
- asmdecl
- assign
- atomic
- atomicalign
- bools
- buildtag
- cgocall
- composites
- copylocks
- deepequalerrors
- defers
- directive
- errorsas
- fieldalignment
- findcall
- framepointer
- httpresponse
- ifaceassert
- loopclosure
- lostcancel
- nilfunc
- nilness
- printf
- reflectvaluecompare
- shadow
- shift
- sigchanyzer
- slog
- sortslice
- stdmethods
- stdversion
- stringintconv
- structtag
- testinggoroutine
- tests
- timeformat
- unmarshal
- unreachable
- unsafeptr
- unusedresult
- unusedwrite
- waitgroup
settings:
printf:
funcs:
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
shadow:
strict: true
unusedresult:
funcs:
- pkg.MyFunc
stringmethods:
- MyMethod
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_grouper.golden.yml
================================================
version: "2"
linters:
settings:
grouper:
const-require-single-const: true
const-require-grouping: true
import-require-single-import: true
import-require-grouping: true
type-require-single-type: true
type-require-grouping: true
var-require-single-var: true
var-require-grouping: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_grouper.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
grouper:
const-require-single-const: true
const-require-grouping: true
import-require-single-import: true
import-require-grouping: true
type-require-single-type: true
type-require-grouping: true
var-require-single-var: true
var-require-grouping: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_iface.golden.yml
================================================
version: "2"
linters:
settings:
iface:
enable:
- identical
- unused
- opaque
settings:
unused:
exclude:
- github.com/example/log
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_iface.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
iface:
enable:
- identical
- unused
- opaque
settings:
unused:
exclude:
- github.com/example/log
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_importas.golden.yml
================================================
version: "2"
linters:
settings:
importas:
alias:
- pkg: knative.dev/serving/pkg/apis/serving/v1
alias: servingv1
- pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
alias: autoscalingv1alpha1
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
alias: $1$2
- pkg: errors
alias: ""
no-unaliased: true
no-extra-aliases: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_importas.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
importas:
no-unaliased: true
no-extra-aliases: true
alias:
- pkg: knative.dev/serving/pkg/apis/serving/v1
alias: servingv1
- pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
alias: autoscalingv1alpha1
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
alias: $1$2
- pkg: errors
alias: ""
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_inamedparam.golden.yml
================================================
version: "2"
linters:
settings:
inamedparam:
skip-single-param: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_inamedparam.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
inamedparam:
skip-single-param: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_interfacebloat.golden.yml
================================================
version: "2"
linters:
settings:
interfacebloat:
max: 5
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_interfacebloat.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
interfacebloat:
max: 5
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_ireturn.golden.yml
================================================
version: "2"
linters:
settings:
ireturn:
allow:
- anon
- (or|er)$
reject:
- github.com\/user\/package\/v4\.Type
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_ireturn.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
ireturn:
allow:
- anon
- (or|er)$
reject:
- github.com\/user\/package\/v4\.Type
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_lll.golden.yml
================================================
version: "2"
linters:
settings:
lll:
line-length: 120
tab-width: 1
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_lll.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
lll:
line-length: 120
tab-width: 1
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_loggercheck.golden.yml
================================================
version: "2"
linters:
settings:
loggercheck:
kitlog: false
klog: false
logr: false
slog: false
zap: false
require-string-key: true
no-printf-like: true
rules:
- k8s.io/klog/v2.InfoS
- (github.com/go-logr/logr.Logger).Error
- (*go.uber.org/zap.SugaredLogger).With
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_loggercheck.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
loggercheck:
kitlog: false
klog: false
logr: false
slog: false
zap: false
require-string-key: true
no-printf-like: true
rules:
- k8s.io/klog/v2.InfoS
- (github.com/go-logr/logr.Logger).Error
- (*go.uber.org/zap.SugaredLogger).With
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_maintidx.golden.yml
================================================
version: "2"
linters:
settings:
maintidx:
under: 100
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_maintidx.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
maintidx:
under: 100
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_makezero.golden.yml
================================================
version: "2"
linters:
settings:
makezero:
always: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_makezero.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
makezero:
always: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_misspell.golden.yml
================================================
version: "2"
linters:
settings:
misspell:
mode: restricted
locale: US
extra-words:
- typo: iff
correction: if
- typo: cancelation
correction: cancellation
ignore-rules:
- someword
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_misspell.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
misspell:
locale: US
ignore-words:
- someword
extra-words:
- typo: "iff"
correction: "if"
- typo: "cancelation"
correction: "cancellation"
mode: restricted
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_mnd.golden.yml
================================================
version: "2"
linters:
settings:
mnd:
checks:
- argument
- case
- condition
- operation
- return
- assign
ignored-numbers:
- "0666"
- "0755"
- "42"
ignored-files:
- magic1_.+\.go$
ignored-functions:
- ^math\.
- ^http\.StatusText$
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_mnd.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
mnd:
checks:
- argument
- case
- condition
- operation
- return
- assign
ignored-numbers:
- '0666'
- '0755'
- '42'
ignored-files:
- 'magic1_.+\.go$'
ignored-functions:
- '^math\.'
- '^http\.StatusText$'
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_musttag.golden.yml
================================================
version: "2"
linters:
settings:
musttag:
functions:
- name: github.com/hashicorp/hcl/v2/hclsimple.DecodeFile
tag: hcl
arg-pos: 2
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_musttag.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
musttag:
functions:
- name: github.com/hashicorp/hcl/v2/hclsimple.DecodeFile
tag: hcl
arg-pos: 2
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret.golden.yml
================================================
version: "2"
linters:
settings:
nakedret:
max-func-lines: 31
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
nakedret:
max-func-lines: 31
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret_zero.golden.yml
================================================
version: "2"
linters:
settings:
nakedret:
max-func-lines: 0
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret_zero.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
nakedret:
max-func-lines: 0
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nestif.golden.yml
================================================
version: "2"
linters:
settings:
nestif:
min-complexity: 4
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nestif.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
nestif:
min-complexity: 4
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nilnil.golden.yml
================================================
version: "2"
linters:
settings:
nilnil:
detect-opposite: true
checked-types:
- chan
- func
- iface
- map
- ptr
- uintptr
- unsafeptr
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nilnil.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
nilnil:
detect-opposite: true
checked-types:
- chan
- func
- iface
- map
- ptr
- uintptr
- unsafeptr
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nlreturn.golden.yml
================================================
version: "2"
linters:
settings:
nlreturn:
block-size: 2
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nlreturn.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
nlreturn:
block-size: 2
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nolintlint.golden.yml
================================================
version: "2"
linters:
settings:
nolintlint:
require-explanation: true
require-specific: true
allow-unused: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nolintlint.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
nolintlint:
allow-unused: true
allow-no-explanation: [ ]
require-explanation: true
require-specific: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nonamedreturns.golden.yml
================================================
version: "2"
linters:
settings:
nonamedreturns:
report-error-in-defer: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_nonamedreturns.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
nonamedreturns:
report-error-in-defer: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_paralleltest.golden.yml
================================================
version: "2"
linters:
settings:
paralleltest:
ignore-missing: true
ignore-missing-subtests: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_paralleltest.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
paralleltest:
ignore-missing: true
ignore-missing-subtests: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_perfsprint.golden.yml
================================================
version: "2"
linters:
settings:
perfsprint:
integer-format: false
int-conversion: false
error-format: false
err-error: true
errorf: false
string-format: false
sprintf1: false
strconcat: false
bool-format: false
hex-format: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_perfsprint.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
perfsprint:
integer-format: false
int-conversion: false
error-format: false
err-error: true
errorf: false
string-format: false
sprintf1: false
strconcat: false
bool-format: false
hex-format: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_prealloc.golden.yml
================================================
version: "2"
linters:
settings:
prealloc:
simple: false
range-loops: false
for-loops: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_prealloc.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
prealloc:
simple: false
range-loops: false
for-loops: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_predeclared.golden.yml
================================================
version: "2"
linters:
settings:
predeclared:
ignore:
- new
- int
qualified-name: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_predeclared.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
predeclared:
ignore: "new,int"
q: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_promlinter.golden.yml
================================================
version: "2"
linters:
settings:
promlinter:
strict: true
disabled-linters:
- Help
- MetricUnits
- Counter
- HistogramSummaryReserved
- MetricTypeInName
- ReservedChars
- CamelCase
- UnitAbbreviations
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_promlinter.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
promlinter:
strict: true
disabled-linters:
- Help
- MetricUnits
- Counter
- HistogramSummaryReserved
- MetricTypeInName
- ReservedChars
- CamelCase
- UnitAbbreviations
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_protogetter.golden.yml
================================================
version: "2"
linters:
settings:
protogetter:
skip-generated-by:
- protoc-gen-go-my-own-generator
skip-files:
- '*.pb.go'
- '*/vendor/*'
- /full/path/to/file.go
skip-any-generated: true
replace-first-arg-in-append: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_protogetter.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
protogetter:
skip-generated-by: ["protoc-gen-go-my-own-generator"]
skip-files:
- "*.pb.go"
- "*/vendor/*"
- "/full/path/to/file.go"
skip-any-generated: true
replace-first-arg-in-append: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_reassign.golden.yml
================================================
version: "2"
linters:
settings:
reassign:
patterns:
- .*
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_reassign.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
reassign:
patterns:
- ".*"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_recvcheck.golden.yml
================================================
version: "2"
linters:
settings:
recvcheck:
disable-builtin: true
exclusions:
- '*.Value'
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_recvcheck.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
recvcheck:
disable-builtin: true
exclusions:
- "*.Value"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_revive.golden.yml
================================================
version: "2"
linters:
settings:
revive:
max-open-files: 2048
confidence: 0.1
severity: error
enable-all-rules: true
rules:
- name: add-constant
arguments:
- allowFloats: 0.0,0.,1.0,1.,2.0,2.
allowInts: 0,1,2
allowStrs: '""'
maxLitCount: "3"
severity: warning
disabled: false
exclude:
- ""
- name: argument-limit
arguments:
- 4
severity: warning
disabled: false
exclude:
- ""
- name: atomic
severity: warning
disabled: false
exclude:
- ""
- name: banned-characters
arguments:
- Ω
- Σ
- σ
- "7"
severity: warning
disabled: false
exclude:
- ""
- name: bare-return
severity: warning
disabled: false
exclude:
- ""
- name: blank-imports
severity: warning
disabled: false
exclude:
- ""
- name: bool-literal-in-expr
severity: warning
disabled: false
exclude:
- ""
- name: call-to-gc
severity: warning
disabled: false
exclude:
- ""
- name: cognitive-complexity
arguments:
- 7
severity: warning
disabled: false
exclude:
- ""
- name: comment-spacings
arguments:
- mypragma
- otherpragma
severity: warning
disabled: false
exclude:
- ""
- name: comments-density
arguments:
- 15
severity: warning
disabled: false
exclude:
- ""
- name: confusing-naming
severity: warning
disabled: false
exclude:
- ""
- name: confusing-results
severity: warning
disabled: false
exclude:
- ""
- name: constant-logical-expr
severity: warning
disabled: false
exclude:
- ""
- name: context-as-argument
arguments:
- allowTypesBefore: '*testing.T,*github.com/user/repo/testing.Harness'
severity: warning
disabled: false
exclude:
- ""
- name: context-keys-type
severity: warning
disabled: false
exclude:
- ""
- name: cyclomatic
arguments:
- 3
severity: warning
disabled: false
exclude:
- ""
- name: datarace
severity: warning
disabled: false
exclude:
- ""
- name: deep-exit
severity: warning
disabled: false
exclude:
- ""
- name: defer
arguments:
- - call-chain
- loop
severity: warning
disabled: false
exclude:
- ""
- name: dot-imports
severity: warning
disabled: false
exclude:
- ""
- name: duplicated-imports
severity: warning
disabled: false
exclude:
- ""
- name: early-return
arguments:
- preserveScope
- allowJump
severity: warning
disabled: false
exclude:
- ""
- name: empty-block
severity: warning
disabled: false
exclude:
- ""
- name: empty-lines
severity: warning
disabled: false
exclude:
- ""
- name: enforce-map-style
arguments:
- make
severity: warning
disabled: false
exclude:
- ""
- name: enforce-repeated-arg-type-style
arguments:
- short
severity: warning
disabled: false
exclude:
- ""
- name: enforce-slice-style
arguments:
- make
severity: warning
disabled: false
exclude:
- ""
- name: error-naming
severity: warning
disabled: false
exclude:
- ""
- name: error-return
severity: warning
disabled: false
exclude:
- ""
- name: error-strings
arguments:
- xerrors.New
severity: warning
disabled: false
exclude:
- ""
- name: errorf
severity: warning
disabled: false
exclude:
- ""
- name: exported
arguments:
- checkPrivateReceivers
- disableStutteringCheck
- checkPublicInterface
- disableChecksOnFunctions
severity: warning
disabled: false
exclude:
- ""
- name: file-header
arguments:
- This is the text that must appear at the top of source files.
severity: warning
disabled: false
exclude:
- ""
- name: file-length-limit
arguments:
- max: 100
skipBlankLines: true
skipComments: true
severity: warning
disabled: false
exclude:
- ""
- name: filename-format
arguments:
- ^[_a-z][_a-z0-9]*\.go$
severity: warning
disabled: false
exclude:
- ""
- name: flag-parameter
severity: warning
disabled: false
exclude:
- ""
- name: function-length
arguments:
- 10
- 0
severity: warning
disabled: false
exclude:
- ""
- name: function-result-limit
arguments:
- 3
severity: warning
disabled: false
exclude:
- ""
- name: get-return
severity: warning
disabled: false
exclude:
- ""
- name: identical-branches
severity: warning
disabled: false
exclude:
- ""
- name: if-return
severity: warning
disabled: false
exclude:
- ""
- name: import-alias-naming
arguments:
- ^[a-z][a-z0-9]{0,}$
severity: warning
disabled: false
exclude:
- ""
- name: import-shadowing
severity: warning
disabled: false
exclude:
- ""
- name: imports-blocklist
arguments:
- crypto/md5
- crypto/sha1
severity: warning
disabled: false
exclude:
- ""
- name: increment-decrement
severity: warning
disabled: false
exclude:
- ""
- name: indent-error-flow
arguments:
- preserveScope
severity: warning
disabled: false
exclude:
- ""
- name: line-length-limit
arguments:
- 80
severity: warning
disabled: false
exclude:
- ""
- name: max-control-nesting
arguments:
- 3
severity: warning
disabled: false
exclude:
- ""
- name: max-public-structs
arguments:
- 3
severity: warning
disabled: false
exclude:
- ""
- name: modifies-parameter
severity: warning
disabled: false
exclude:
- ""
- name: modifies-value-receiver
severity: warning
disabled: false
exclude:
- ""
- name: nested-structs
severity: warning
disabled: false
exclude:
- ""
- name: optimize-operands-order
severity: warning
disabled: false
exclude:
- ""
- name: package-comments
severity: warning
disabled: false
exclude:
- ""
- name: range
severity: warning
disabled: false
exclude:
- ""
- name: range-val-address
severity: warning
disabled: false
exclude:
- ""
- name: range-val-in-closure
severity: warning
disabled: false
exclude:
- ""
- name: receiver-naming
arguments:
- maxLength: 2
severity: warning
disabled: false
exclude:
- ""
- name: redefines-builtin-id
severity: warning
disabled: false
exclude:
- ""
- name: redundant-build-tag
severity: warning
disabled: false
exclude:
- ""
- name: redundant-import-alias
severity: warning
disabled: false
exclude:
- ""
- name: string-format
arguments:
- - core.WriteError[1].Message
- /^([^A-Z]|$)/
- must not start with a capital letter
- - fmt.Errorf[0]
- /(^|[^\.!?])$/
- must not end in punctuation
- - panic
- /^[^\n]*$/
- must not contain line breaks
severity: warning
disabled: false
exclude:
- ""
- name: string-of-int
severity: warning
disabled: false
exclude:
- ""
- name: struct-tag
arguments:
- json,inline
- bson,outline,gnu
severity: warning
disabled: false
exclude:
- ""
- name: superfluous-else
arguments:
- preserveScope
severity: warning
disabled: false
exclude:
- ""
- name: time-equal
severity: warning
disabled: false
exclude:
- ""
- name: time-naming
severity: warning
disabled: false
exclude:
- ""
- name: unchecked-type-assertion
arguments:
- acceptIgnoredAssertionResult: true
severity: warning
disabled: false
exclude:
- ""
- name: unconditional-recursion
severity: warning
disabled: false
exclude:
- ""
- name: unexported-naming
severity: warning
disabled: false
exclude:
- ""
- name: unexported-return
severity: warning
disabled: false
exclude:
- ""
- name: unhandled-error
arguments:
- fmt.Printf
- myFunction
severity: warning
disabled: false
exclude:
- ""
- name: unnecessary-stmt
severity: warning
disabled: false
exclude:
- ""
- name: unreachable-code
severity: warning
disabled: false
exclude:
- ""
- name: unused-parameter
arguments:
- allowRegex: ^_
severity: warning
disabled: false
exclude:
- ""
- name: unused-receiver
arguments:
- allowRegex: ^_
severity: warning
disabled: false
exclude:
- ""
- name: use-any
severity: warning
disabled: false
exclude:
- ""
- name: use-errors-new
severity: warning
disabled: false
exclude:
- ""
- name: useless-break
severity: warning
disabled: false
exclude:
- ""
- name: var-declaration
severity: warning
disabled: false
exclude:
- ""
- name: var-naming
arguments:
- - ID
- - VM
- - upperCaseConst: true
severity: warning
disabled: false
exclude:
- ""
- name: waitgroup-by-value
severity: warning
disabled: false
exclude:
- ""
directives:
- name: specify-disable-reason
severity: error
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_revive.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
revive:
max-open-files: 2048
ignore-generated-header: true
severity: error
enable-all-rules: true
directives:
- name: specify-disable-reason
severity: error
confidence: 0.1
rules:
- name: add-constant
severity: warning
disabled: false
exclude: [""]
arguments:
- maxLitCount: "3"
allowStrs: '""'
allowInts: "0,1,2"
allowFloats: "0.0,0.,1.0,1.,2.0,2."
- name: argument-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 4 ]
- name: atomic
severity: warning
disabled: false
exclude: [""]
- name: banned-characters
severity: warning
disabled: false
exclude: [""]
arguments: [ "Ω","Σ","σ", "7" ]
- name: bare-return
severity: warning
disabled: false
exclude: [""]
- name: blank-imports
severity: warning
disabled: false
exclude: [""]
- name: bool-literal-in-expr
severity: warning
disabled: false
exclude: [""]
- name: call-to-gc
severity: warning
disabled: false
exclude: [""]
- name: cognitive-complexity
severity: warning
disabled: false
exclude: [""]
arguments: [ 7 ]
- name: comment-spacings
severity: warning
disabled: false
exclude: [""]
arguments:
- mypragma
- otherpragma
- name: comments-density
severity: warning
disabled: false
exclude: [""]
arguments: [ 15 ]
- name: confusing-naming
severity: warning
disabled: false
exclude: [""]
- name: confusing-results
severity: warning
disabled: false
exclude: [""]
- name: constant-logical-expr
severity: warning
disabled: false
exclude: [""]
- name: context-as-argument
severity: warning
disabled: false
exclude: [""]
arguments:
- allowTypesBefore: "*testing.T,*github.com/user/repo/testing.Harness"
- name: context-keys-type
severity: warning
disabled: false
exclude: [""]
- name: cyclomatic
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
- name: datarace
severity: warning
disabled: false
exclude: [""]
- name: deep-exit
severity: warning
disabled: false
exclude: [""]
- name: defer
severity: warning
disabled: false
exclude: [""]
arguments:
- [ "call-chain", "loop" ]
- name: dot-imports
severity: warning
disabled: false
exclude: [""]
arguments: [ ]
- name: duplicated-imports
severity: warning
disabled: false
exclude: [""]
- name: early-return
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserveScope"
- "allowJump"
- name: empty-block
severity: warning
disabled: false
exclude: [""]
- name: empty-lines
severity: warning
disabled: false
exclude: [""]
- name: enforce-map-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "make"
- name: enforce-repeated-arg-type-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "short"
- name: enforce-slice-style
severity: warning
disabled: false
exclude: [""]
arguments:
- "make"
- name: error-naming
severity: warning
disabled: false
exclude: [""]
- name: error-return
severity: warning
disabled: false
exclude: [""]
- name: error-strings
severity: warning
disabled: false
exclude: [""]
arguments:
- "xerrors.New"
- name: errorf
severity: warning
disabled: false
exclude: [""]
- name: exported
severity: warning
disabled: false
exclude: [""]
arguments:
- "checkPrivateReceivers"
- "disableStutteringCheck"
- "checkPublicInterface"
- "disableChecksOnFunctions"
- name: file-header
severity: warning
disabled: false
exclude: [""]
arguments:
- This is the text that must appear at the top of source files.
- name: file-length-limit
severity: warning
disabled: false
exclude: [""]
arguments:
- max: 100
skipComments: true
skipBlankLines: true
- name: filename-format
severity: warning
disabled: false
exclude: [""]
arguments:
- "^[_a-z][_a-z0-9]*\\.go$"
- name: flag-parameter
severity: warning
disabled: false
exclude: [""]
- name: function-length
severity: warning
disabled: false
exclude: [""]
arguments: [ 10, 0 ]
- name: function-result-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
- name: get-return
severity: warning
disabled: false
exclude: [""]
- name: identical-branches
severity: warning
disabled: false
exclude: [""]
- name: if-return
severity: warning
disabled: false
exclude: [""]
- name: import-alias-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- "^[a-z][a-z0-9]{0,}$"
- name: import-shadowing
severity: warning
disabled: false
exclude: [""]
- name: imports-blocklist
severity: warning
disabled: false
exclude: [""]
arguments:
- "crypto/md5"
- "crypto/sha1"
- name: increment-decrement
severity: warning
disabled: false
exclude: [""]
- name: indent-error-flow
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserveScope"
- name: line-length-limit
severity: warning
disabled: false
exclude: [""]
arguments: [ 80 ]
- name: max-control-nesting
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
- name: max-public-structs
severity: warning
disabled: false
exclude: [""]
arguments: [ 3 ]
- name: modifies-parameter
severity: warning
disabled: false
exclude: [""]
- name: modifies-value-receiver
severity: warning
disabled: false
exclude: [""]
- name: nested-structs
severity: warning
disabled: false
exclude: [""]
- name: optimize-operands-order
severity: warning
disabled: false
exclude: [""]
- name: package-comments
severity: warning
disabled: false
exclude: [""]
- name: range
severity: warning
disabled: false
exclude: [""]
- name: range-val-address
severity: warning
disabled: false
exclude: [""]
- name: range-val-in-closure
severity: warning
disabled: false
exclude: [""]
- name: receiver-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- maxLength: 2
- name: redefines-builtin-id
severity: warning
disabled: false
exclude: [""]
- name: redundant-build-tag
severity: warning
disabled: false
exclude: [""]
- name: redundant-import-alias
severity: warning
disabled: false
exclude: [""]
- name: string-format
severity: warning
disabled: false
exclude: [""]
arguments:
- - 'core.WriteError[1].Message'
- '/^([^A-Z]|$)/'
- must not start with a capital letter
- - 'fmt.Errorf[0]'
- '/(^|[^\.!?])$/'
- must not end in punctuation
- - panic
- '/^[^\n]*$/'
- must not contain line breaks
- name: string-of-int
severity: warning
disabled: false
exclude: [""]
- name: struct-tag
severity: warning
disabled: false
exclude: [""]
arguments:
- "json,inline"
- "bson,outline,gnu"
- name: superfluous-else
severity: warning
disabled: false
exclude: [""]
arguments:
- "preserveScope"
- name: time-equal
severity: warning
disabled: false
exclude: [""]
- name: time-naming
severity: warning
disabled: false
exclude: [""]
- name: unchecked-type-assertion
severity: warning
disabled: false
exclude: [""]
arguments:
- acceptIgnoredAssertionResult: true
- name: unconditional-recursion
severity: warning
disabled: false
exclude: [""]
- name: unexported-naming
severity: warning
disabled: false
exclude: [""]
- name: unexported-return
severity: warning
disabled: false
exclude: [""]
- name: unhandled-error
severity: warning
disabled: false
exclude: [""]
arguments:
- "fmt.Printf"
- "myFunction"
- name: unnecessary-stmt
severity: warning
disabled: false
exclude: [""]
- name: unreachable-code
severity: warning
disabled: false
exclude: [""]
- name: unused-parameter
severity: warning
disabled: false
exclude: [""]
arguments:
- allowRegex: "^_"
- name: unused-receiver
severity: warning
disabled: false
exclude: [""]
arguments:
- allowRegex: "^_"
- name: use-any
severity: warning
disabled: false
exclude: [""]
- name: use-errors-new
severity: warning
disabled: false
exclude: [""]
- name: useless-break
severity: warning
disabled: false
exclude: [""]
- name: var-declaration
severity: warning
disabled: false
exclude: [""]
- name: var-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- [ "ID" ]
- [ "VM" ]
- - upperCaseConst: true
- name: waitgroup-by-value
severity: warning
disabled: false
exclude: [""]
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_rowserrcheck.golden.yml
================================================
version: "2"
linters:
settings:
rowserrcheck:
packages:
- github.com/jmoiron/sqlx
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_rowserrcheck.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
rowserrcheck:
packages:
- github.com/jmoiron/sqlx
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_sloglint.golden.yml
================================================
version: "2"
linters:
settings:
sloglint:
no-mixed-args: false
kv-only: true
attr-only: true
no-global: all
context: all
static-msg: true
no-raw-keys: true
key-naming-case: snake
forbidden-keys:
- time
- level
- msg
- source
- foo
args-on-sep-lines: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_sloglint.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
sloglint:
no-mixed-args: false
kv-only: true
attr-only: true
no-global: "all"
context: "all"
static-msg: true
no-raw-keys: true
key-naming-case: snake
forbidden-keys:
- time
- level
- msg
- source
- foo
args-on-sep-lines: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_spancheck.golden.yml
================================================
version: "2"
linters:
settings:
spancheck:
checks:
- end
- record-error
- set-status
ignore-check-signatures:
- telemetry.RecordError
extra-start-span-signatures:
- github.com/user/repo/telemetry/trace.Start:opentelemetry
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_spancheck.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
spancheck:
checks:
- end
- record-error
- set-status
ignore-check-signatures:
- "telemetry.RecordError"
extra-start-span-signatures:
- "github.com/user/repo/telemetry/trace.Start:opentelemetry"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck.golden.yml
================================================
version: "2"
linters:
settings:
staticcheck:
checks:
- SA1000
- SA1001
- SA1002
- SA1003
- SA1004
- SA1005
- SA1006
- SA1007
- SA1008
- SA1010
- SA1011
- SA1012
- SA1013
- SA1014
- SA1015
- SA1016
- SA1017
- SA1018
- SA1019
- SA1020
- SA1021
- SA1023
- SA1024
- SA1025
- SA1026
- SA1027
- SA1028
- SA1029
- SA1030
- SA1031
- SA1032
- SA2000
- SA2001
- SA2002
- SA2003
- SA3000
- SA3001
- SA4000
- SA4001
- SA4003
- SA4004
- SA4005
- SA4006
- SA4008
- SA4009
- SA4010
- SA4011
- SA4012
- SA4013
- SA4014
- SA4015
- SA4016
- SA4017
- SA4018
- SA4019
- SA4020
- SA4021
- SA4022
- SA4023
- SA4024
- SA4025
- SA4026
- SA4027
- SA4028
- SA4029
- SA4030
- SA4031
- SA4032
- SA5000
- SA5001
- SA5002
- SA5003
- SA5004
- SA5005
- SA5007
- SA5008
- SA5009
- SA5010
- SA5011
- SA5012
- SA6000
- SA6001
- SA6002
- SA6003
- SA6005
- SA6006
- SA9001
- SA9002
- SA9003
- SA9004
- SA9005
- SA9006
- SA9007
- SA9008
- SA9009
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
staticcheck:
checks:
- SA1000
- SA1001
- SA1002
- SA1003
- SA1004
- SA1005
- SA1006
- SA1007
- SA1008
- SA1010
- SA1011
- SA1012
- SA1013
- SA1014
- SA1015
- SA1016
- SA1017
- SA1018
- SA1019
- SA1020
- SA1021
- SA1023
- SA1024
- SA1025
- SA1026
- SA1027
- SA1028
- SA1029
- SA1030
- SA1031
- SA1032
- SA2000
- SA2001
- SA2002
- SA2003
- SA3000
- SA3001
- SA4000
- SA4001
- SA4003
- SA4004
- SA4005
- SA4006
- SA4008
- SA4009
- SA4010
- SA4011
- SA4012
- SA4013
- SA4014
- SA4015
- SA4016
- SA4017
- SA4018
- SA4019
- SA4020
- SA4021
- SA4022
- SA4023
- SA4024
- SA4025
- SA4026
- SA4027
- SA4028
- SA4029
- SA4030
- SA4031
- SA4032
- SA5000
- SA5001
- SA5002
- SA5003
- SA5004
- SA5005
- SA5007
- SA5008
- SA5009
- SA5010
- SA5011
- SA5012
- SA6000
- SA6001
- SA6002
- SA6003
- SA6005
- SA6006
- SA9001
- SA9002
- SA9003
- SA9004
- SA9005
- SA9006
- SA9007
- SA9008
- SA9009
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck_merge.golden.yml
================================================
version: "2"
linters:
settings:
staticcheck:
checks:
- all
- -S1000
- -S1001
- -S1002
- -SA1000
- -SA1001
- -SA1002
- -ST1000
- -ST1001
- -ST1003
- S1003
- S1004
- S1005
- S1006
- S1007
- S1008
- S1009
- S1010
- S1011
- S1012
- S1016
- S1017
- S1018
- S1019
- S1020
- S1021
- S1023
- S1024
- S1025
- S1028
- S1029
- S1030
- S1031
- S1032
- S1033
- S1034
- S1035
- S1036
- S1037
- S1038
- S1039
- S1040
- SA1003
- SA1004
- SA1005
- SA1006
- SA1007
- SA1008
- SA1010
- SA1011
- SA1012
- SA1013
- SA1014
- SA1015
- SA1016
- SA1017
- SA1018
- SA1019
- SA1020
- SA1021
- SA1023
- SA1024
- SA1025
- SA1026
- SA1027
- SA1028
- SA1029
- SA1030
- SA1031
- SA1032
- SA2000
- SA2001
- SA2002
- SA2003
- SA3000
- SA3001
- SA4000
- SA4001
- SA4003
- SA4004
- SA4005
- SA4006
- SA4008
- SA4009
- SA4010
- SA4011
- SA4012
- SA4013
- SA4014
- SA4015
- SA4016
- SA4017
- SA4018
- SA4019
- SA4020
- SA4021
- SA4022
- SA4023
- SA4024
- SA4025
- SA4026
- SA4027
- SA4028
- SA4029
- SA4030
- SA4031
- SA4032
- SA5000
- SA5001
- SA5002
- SA5003
- SA5004
- SA5005
- SA5007
- SA5008
- SA5009
- SA5010
- SA5011
- SA5012
- SA6000
- SA6001
- SA6002
- SA6003
- SA6005
- SA6006
- SA9001
- SA9002
- SA9003
- SA9004
- SA9005
- SA9006
- SA9007
- SA9008
- SA9009
- ST1005
- ST1006
- ST1008
- ST1011
- ST1012
- ST1013
- ST1015
- ST1016
- ST1017
- ST1018
- ST1019
- ST1020
- ST1021
- ST1022
- ST1023
initialisms:
- ACL
- API
- ASCII
- CPU
- CSS
- DNS
- EOF
- GUID
- HTML
- HTTP
- HTTPS
- ID
- IP
- JSON
- QPS
- RAM
- RPC
- SLA
- SMTP
- SQL
- SSH
- TCP
- TLS
- TTL
- UDP
- UI
- GID
- UID
- UUID
- URI
- URL
- UTF8
- VM
- XML
- XMPP
- XSRF
- XSS
- SIP
- RTP
- AMQP
- DB
- TS
dot-import-whitelist:
- fmt
http-status-code-whitelist:
- "200"
- "400"
- "404"
- "500"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck_merge.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
staticcheck:
checks:
- all
- '-SA1000'
- '-SA1001'
- '-SA1002'
- SA1003
- SA1004
- SA1005
- SA1006
- SA1007
- SA1008
- SA1010
- SA1011
- SA1012
- SA1013
- SA1014
- SA1015
- SA1016
- SA1017
- SA1018
- SA1019
- SA1020
- SA1021
- SA1023
- SA1024
- SA1025
- SA1026
- SA1027
- SA1028
- SA1029
- SA1030
- SA1031
- SA1032
- SA2000
- SA2001
- SA2002
- SA2003
- SA3000
- SA3001
- SA4000
- SA4001
- SA4003
- SA4004
- SA4005
- SA4006
- SA4008
- SA4009
- SA4010
- SA4011
- SA4012
- SA4013
- SA4014
- SA4015
- SA4016
- SA4017
- SA4018
- SA4019
- SA4020
- SA4021
- SA4022
- SA4023
- SA4024
- SA4025
- SA4026
- SA4027
- SA4028
- SA4029
- SA4030
- SA4031
- SA4032
- SA5000
- SA5001
- SA5002
- SA5003
- SA5004
- SA5005
- SA5007
- SA5008
- SA5009
- SA5010
- SA5011
- SA5012
- SA6000
- SA6001
- SA6002
- SA6003
- SA6005
- SA6006
- SA9001
- SA9002
- SA9003
- SA9004
- SA9005
- SA9006
- SA9007
- SA9008
- SA9009
gosimple:
checks:
- '*'
- '-S1000'
- '-S1001'
- '-S1002'
- S1003
- S1004
- S1005
- S1006
- S1007
- S1008
- S1009
- S1010
- S1011
- S1012
- S1016
- S1017
- S1018
- S1019
- S1020
- S1021
- S1023
- S1024
- S1025
- S1028
- S1029
- S1030
- S1031
- S1032
- S1033
- S1034
- S1035
- S1036
- S1037
- S1038
- S1039
- S1040
stylecheck:
dot-import-whitelist:
- fmt
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ]
http-status-code-whitelist: [ "200", "400", "404", "500" ]
checks:
- all
- '-ST1000'
- '-ST1001'
- '-ST1003'
- ST1005
- ST1006
- ST1008
- ST1011
- ST1012
- ST1013
- ST1015
- ST1016
- ST1017
- ST1018
- ST1019
- ST1020
- ST1021
- ST1022
- ST1023
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_stylecheck.golden.yml
================================================
version: "2"
linters:
settings:
staticcheck:
checks:
- ST1000
- ST1001
- ST1003
- ST1005
- ST1006
- ST1008
- ST1011
- ST1012
- ST1013
- ST1015
- ST1016
- ST1017
- ST1018
- ST1019
- ST1020
- ST1021
- ST1022
- ST1023
initialisms:
- ACL
- API
- ASCII
- CPU
- CSS
- DNS
- EOF
- GUID
- HTML
- HTTP
- HTTPS
- ID
- IP
- JSON
- QPS
- RAM
- RPC
- SLA
- SMTP
- SQL
- SSH
- TCP
- TLS
- TTL
- UDP
- UI
- GID
- UID
- UUID
- URI
- URL
- UTF8
- VM
- XML
- XMPP
- XSRF
- XSS
- SIP
- RTP
- AMQP
- DB
- TS
dot-import-whitelist:
- fmt
http-status-code-whitelist:
- "200"
- "400"
- "404"
- "500"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_stylecheck.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
stylecheck:
dot-import-whitelist:
- fmt
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ]
http-status-code-whitelist: [ "200", "400", "404", "500" ]
checks:
- ST1000
- ST1001
- ST1003
- ST1005
- ST1006
- ST1008
- ST1011
- ST1012
- ST1013
- ST1015
- ST1016
- ST1017
- ST1018
- ST1019
- ST1020
- ST1021
- ST1022
- ST1023
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_tagalign.golden.yml
================================================
version: "2"
linters:
settings:
tagalign:
align: false
sort: false
order:
- json
- yaml
- yml
- toml
- mapstructure
- binding
- validate
strict: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_tagalign.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
tagalign:
align: false
sort: false
order:
- json
- yaml
- yml
- toml
- mapstructure
- binding
- validate
strict: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_tagliatelle.golden.yml
================================================
version: "2"
linters:
settings:
tagliatelle:
case:
rules:
avro: snake
bson: camel
env: upperSnake
envconfig: upperSnake
json: camel
mapstructure: kebab
toml: camel
whatever: snake
xml: camel
yaml: camel
extended-rules:
json:
case: camel
extra-initialisms: true
initialism-overrides:
DB: true
LHS: false
use-field-name: true
ignored-fields:
- Bar
- Foo
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_tagliatelle.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
tagliatelle:
case:
rules:
json: camel
yaml: camel
xml: camel
toml: camel
bson: camel
avro: snake
mapstructure: kebab
env: upperSnake
envconfig: upperSnake
whatever: snake
extended-rules:
json:
case: camel
extra-initialisms: true
initialism-overrides:
DB: true
LHS: false
use-field-name: true
ignored-fields:
- Bar
- Foo
overrides:
-
pkg: foo/bar
rules:
json: snake
xml: pascal
extended-rules:
use-field-name: true
ignored-fields:
- Bar
- Foo
ignore: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_testifylint.golden.yml
================================================
version: "2"
linters:
settings:
testifylint:
enable-all: true
disable-all: true
enable:
- blank-import
- bool-compare
- compares
- contains
- empty
- encoded-compare
- error-is-as
- error-nil
- expected-actual
- float-compare
- formatter
- go-require
- len
- negative-positive
- nil-compare
- regexp
- require-error
- suite-broken-parallel
- suite-dont-use-pkg
- suite-extra-assert-call
- suite-subtest-run
- suite-thelper
- useless-assert
disable:
- blank-import
- bool-compare
- compares
- contains
- empty
- encoded-compare
- error-is-as
- error-nil
- expected-actual
- float-compare
- formatter
- go-require
- len
- negative-positive
- nil-compare
- regexp
- require-error
- suite-broken-parallel
- suite-dont-use-pkg
- suite-extra-assert-call
- suite-subtest-run
- suite-thelper
- useless-assert
bool-compare:
ignore-custom-types: true
expected-actual:
pattern: ^expected
formatter:
check-format-string: false
require-f-funcs: true
go-require:
ignore-http-handlers: true
require-error:
fn-pattern: ^(Errorf?|NoErrorf?)$
suite-extra-assert-call:
mode: require
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_testifylint.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
testifylint:
enable-all: true
disable:
- blank-import
- bool-compare
- compares
- contains
- empty
- encoded-compare
- error-is-as
- error-nil
- expected-actual
- float-compare
- formatter
- go-require
- len
- negative-positive
- nil-compare
- regexp
- require-error
- suite-broken-parallel
- suite-dont-use-pkg
- suite-extra-assert-call
- suite-subtest-run
- suite-thelper
- useless-assert
disable-all: true
enable:
- blank-import
- bool-compare
- compares
- contains
- empty
- encoded-compare
- error-is-as
- error-nil
- expected-actual
- float-compare
- formatter
- go-require
- len
- negative-positive
- nil-compare
- regexp
- require-error
- suite-broken-parallel
- suite-dont-use-pkg
- suite-extra-assert-call
- suite-subtest-run
- suite-thelper
- useless-assert
bool-compare:
ignore-custom-types: true
expected-actual:
pattern: ^expected
formatter:
check-format-string: false
require-f-funcs: true
go-require:
ignore-http-handlers: true
require-error:
fn-pattern: ^(Errorf?|NoErrorf?)$
suite-extra-assert-call:
mode: require
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_testpackage.golden.yml
================================================
version: "2"
linters:
settings:
testpackage:
skip-regexp: (export|internal)_test\.go
allow-packages:
- example
- main
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_testpackage.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
testpackage:
skip-regexp: (export|internal)_test\.go
allow-packages:
- example
- main
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_thelper.golden.yml
================================================
version: "2"
linters:
settings:
thelper:
test:
first: false
name: false
begin: false
fuzz:
first: false
name: false
begin: false
benchmark:
first: false
name: false
begin: false
tb:
first: false
name: false
begin: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_thelper.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
thelper:
test:
first: false
name: false
begin: false
benchmark:
first: false
name: false
begin: false
tb:
first: false
name: false
begin: false
fuzz:
first: false
name: false
begin: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_unconvert.golden.yml
================================================
version: "2"
linters:
settings:
unconvert:
fast-math: true
safe: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_unconvert.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
unconvert:
fast-math: true
safe: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_unparam.golden.yml
================================================
version: "2"
linters:
settings:
unparam:
check-exported: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_unparam.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
unparam:
check-exported: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_unused.golden.yml
================================================
version: "2"
linters:
settings:
unused:
field-writes-are-uses: false
post-statements-are-reads: true
exported-fields-are-used: false
parameters-are-used: false
local-variables-are-used: false
generated-is-used: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_unused.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
unused:
field-writes-are-uses: false
post-statements-are-reads: true
exported-fields-are-used: false
parameters-are-used: false
local-variables-are-used: false
generated-is-used: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_usestdlibvars.golden.yml
================================================
version: "2"
linters:
settings:
usestdlibvars:
http-method: false
http-status-code: false
time-weekday: true
time-month: true
time-layout: true
crypto-hash: true
default-rpc-path: true
sql-isolation-level: true
tls-signature-scheme: true
constant-kind: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_usestdlibvars.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
usestdlibvars:
http-method: false
http-status-code: false
time-weekday: true
time-month: true
time-layout: true
crypto-hash: true
default-rpc-path: true
sql-isolation-level: true
tls-signature-scheme: true
constant-kind: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_usetesting.golden.yml
================================================
version: "2"
linters:
settings:
usetesting:
context-background: false
context-todo: false
os-chdir: false
os-mkdir-temp: false
os-setenv: false
os-temp-dir: true
os-create-temp: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_usetesting.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
usetesting:
os-create-temp: false
os-mkdir-temp: false
os-setenv: false
os-temp-dir: true
os-chdir: false
context-background: false
context-todo: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_varnamelen.golden.yml
================================================
version: "2"
linters:
settings:
varnamelen:
max-distance: 6
min-name-length: 2
check-receiver: true
check-return: true
check-type-param: true
ignore-names:
- err
ignore-type-assert-ok: true
ignore-map-index-ok: true
ignore-chan-recv-ok: true
ignore-decls:
- c echo.Context
- t testing.T
- f *foo.Bar
- e error
- i int
- const C
- T any
- m map[string]int
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_varnamelen.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
varnamelen:
max-distance: 6
min-name-length: 2
check-receiver: true
check-return: true
check-type-param: true
ignore-type-assert-ok: true
ignore-map-index-ok: true
ignore-chan-recv-ok: true
ignore-names:
- err
ignore-decls:
- c echo.Context
- t testing.T
- f *foo.Bar
- e error
- i int
- const C
- T any
- m map[string]int
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_whitespace.golden.yml
================================================
version: "2"
linters:
settings:
whitespace:
multi-if: true
multi-func: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_whitespace.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
whitespace:
multi-if: true
multi-func: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_wrapcheck.golden.yml
================================================
version: "2"
linters:
settings:
wrapcheck:
extra-ignore-sigs:
- .CustomError(
- .SpecificWrap(
ignore-sigs:
- .Errorf(
- errors.New(
- errors.Unwrap(
- errors.Join(
- .Wrap(
- .Wrapf(
- .WithMessage(
- .WithMessagef(
- .WithStack(
ignore-sig-regexps:
- \.New.*Error\(
ignore-package-globs:
- encoding/*
- github.com/pkg/*
ignore-interface-regexps:
- ^(?i)c(?-i)ach(ing|e)
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_wrapcheck.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
wrapcheck:
extra-ignore-sigs:
- .CustomError(
- .SpecificWrap(
ignoreSigs:
- .Errorf(
- errors.New(
- errors.Unwrap(
- errors.Join(
- .Wrap(
- .Wrapf(
- .WithMessage(
- .WithMessagef(
- .WithStack(
ignoreSigRegexps:
- \.New.*Error\(
ignorePackageGlobs:
- encoding/*
- github.com/pkg/*
ignoreInterfaceRegexps:
- ^(?i)c(?-i)ach(ing|e)
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_wsl.golden.yml
================================================
version: "2"
linters:
settings:
wsl:
strict-append: false
allow-assign-and-call: false
allow-assign-and-anything: true
allow-multiline-assign: false
force-case-trailing-whitespace: 1
allow-trailing-comment: true
allow-separated-leading-comment: true
allow-cuddle-declarations: true
allow-cuddle-with-calls:
- Foo
- Bar
allow-cuddle-with-rhs:
- Foo
- Bar
force-err-cuddling: true
error-variable-names:
- foo
force-short-decl-cuddling: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters-settings_wsl.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters-settings:
wsl:
strict-append: false
allow-assign-and-call: false
allow-assign-and-anything: true
allow-multiline-assign: false
force-case-trailing-whitespace: 1
allow-trailing-comment: true
allow-separated-leading-comment: true
allow-cuddle-declarations: true
allow-cuddle-with-calls: [ "Foo", "Bar" ]
allow-cuddle-with-rhs: [ "Foo", "Bar" ]
force-err-cuddling: true
error-variable-names: [ "foo" ]
force-short-decl-cuddling: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_01.golden.yml
================================================
version: "2"
linters:
default: none
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- musttag
- mycustomlinter1
- mycustomlinter2
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_01.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: disable-all + enable
linters:
disable-all: true
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- gci
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- gofmt
- gofumpt
- goheader
- goimports
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosimple
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
- mycustomlinter1
- mycustomlinter2
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_02.golden.yml
================================================
version: "2"
linters:
default: all
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- musttag
- mycustomlinter1
- mycustomlinter2
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_02.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: enable-all + disable
linters:
enable-all: true
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- gci
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- gofmt
- gofumpt
- goheader
- goimports
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosimple
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
- deadcode # Deprecated
- execinquery # Deprecated
- exhaustivestruct # Deprecated
- exportloopref # Deprecated
- golint # Deprecated
- gomnd # Deprecated
- ifshort # Deprecated
- interfacer # Deprecated
- maligned # Deprecated
- nosnakecase # Deprecated
- scopelint # Deprecated
- structcheck # Deprecated
- tenv # Deprecated
- varcheck # Deprecated
- mycustomlinter1
- mycustomlinter2
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_03.golden.yml
================================================
version: "2"
linters:
enable:
- mycustomlinter1
- mycustomlinter2
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- mnd
- mycustomlinter3
- mycustomlinter4
formatters:
enable:
- gofmt
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_03.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: enable + disable
linters:
enable:
- gofmt
- sqlclosecheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
- mycustomlinter1
- mycustomlinter2
disable:
- goimports
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- deadcode # Deprecated
- execinquery # Deprecated
- exhaustivestruct # Deprecated
- exportloopref # Deprecated
- golint # Deprecated
- gomnd # Deprecated
- ifshort # Deprecated
- interfacer # Deprecated
- maligned # Deprecated
- nosnakecase # Deprecated
- scopelint # Deprecated
- structcheck # Deprecated
- tenv # Deprecated
- varcheck # Deprecated
- mycustomlinter3
- mycustomlinter4
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_04.golden.yml
================================================
version: "2"
linters:
default: none
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- gomoddirectives
- gomodguard
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_04.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: disable-all + enable + presets
linters:
disable-all: true
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
presets:
- format
- module
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_05.golden.yml
================================================
version: "2"
linters:
default: all
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_05.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: enable-all + disable + presets
linters:
enable-all: true
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
presets:
- format
- module
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_06.golden.yml
================================================
version: "2"
linters:
enable:
- gomoddirectives
- gomodguard
- mycustomlinter1
- mycustomlinter2
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- mnd
- mycustomlinter3
- mycustomlinter4
formatters:
enable:
- gci
- gofmt
- gofumpt
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_06.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: enable + disable + presets
linters:
enable:
- gofmt
- sqlclosecheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
- mycustomlinter1
- mycustomlinter2
disable:
- goimports
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- deadcode # Deprecated
- execinquery # Deprecated
- exhaustivestruct # Deprecated
- exportloopref # Deprecated
- golint # Deprecated
- gomnd # Deprecated
- ifshort # Deprecated
- interfacer # Deprecated
- maligned # Deprecated
- nosnakecase # Deprecated
- scopelint # Deprecated
- structcheck # Deprecated
- tenv # Deprecated
- varcheck # Deprecated
- mycustomlinter3
- mycustomlinter4
presets:
- format
- module
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_07.golden.yml
================================================
version: "2"
linters:
default: none
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_07.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: disable-all + enable + fast
linters:
fast: true
disable-all: true
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- gci
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- gofmt
- gofumpt
- goheader
- goimports
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosimple
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_08.golden.yml
================================================
version: "2"
linters:
default: all
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- gocritic
- gosec
- gosmopolitan
- govet
- iface
- importas
- intrange
- ireturn
- loggercheck
- makezero
- mirror
- musttag
- nilerr
- nilnesserr
- nilnil
- noctx
- nonamedreturns
- paralleltest
- perfsprint
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagliatelle
- testifylint
- thelper
- tparallel
- unconvert
- unparam
- unused
- usetesting
- varnamelen
- wastedassign
- wrapcheck
- zerologlint
formatters:
enable:
- gofmt
- gofumpt
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_08.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: enable-all + disable + fast
linters:
fast: true
enable-all: true
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- gci
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_09.golden.yml
================================================
version: "2"
linters:
enable:
- mycustomlinter1
- mycustomlinter2
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- errcheck
- govet
- mnd
- mycustomlinter3
- mycustomlinter4
formatters:
enable:
- gofmt
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_09.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: enable + disable + fast
linters:
fast: true
enable:
- gofmt
- sqlclosecheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- varnamelen
- wastedassign
- whitespace
- wrapcheck
- wsl
- zerologlint
- mycustomlinter1
- mycustomlinter2
disable:
- goimports
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- deadcode # Deprecated
- execinquery # Deprecated
- exhaustivestruct # Deprecated
- exportloopref # Deprecated
- golint # Deprecated
- gomnd # Deprecated
- ifshort # Deprecated
- interfacer # Deprecated
- maligned # Deprecated
- nosnakecase # Deprecated
- scopelint # Deprecated
- structcheck # Deprecated
- tenv # Deprecated
- varcheck # Deprecated
- mycustomlinter3
- mycustomlinter4
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_10.golden.yml
================================================
version: "2"
linters:
enable:
- depguard
- gomoddirectives
- gomodguard
disable:
- errcheck
- govet
- staticcheck
- unused
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_10.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
# case: presets + fast
linters:
fast: true
presets:
- format
- metalinter
- module
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_11.golden.yml
================================================
version: "2"
linters:
default: all
formatters:
enable:
- gofmt
- gofumpt
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_11.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters:
enable-all: true
disable:
- typecheck
- gci
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_12.golden.yml
================================================
version: "2"
linters:
default: none
enable:
- govet
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_12.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters:
disable-all: true
enable:
- typecheck
- govet
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_13_a.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_13_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters:
enable:
- staticcheck
disable:
- stylecheck
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_13_b.golden.yml
================================================
version: "2"
linters:
default: all
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_13_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters:
enable-all: true
disable:
- gosimple
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_13_c.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_13_c.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters:
disable:
- stylecheck
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_13_d.golden.yml
================================================
version: "2"
linters:
disable:
- staticcheck
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/linters_13_d.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
linters:
disable:
- staticcheck
- stylecheck
- gosimple
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_a.golden.yml
================================================
version: "2"
output:
formats:
text:
path: stdout
json:
path: stderr
tab:
path: stdout
html:
path: stdout
checkstyle:
path: report.xml
code-climate:
path: stdout
junit-xml:
path: stdout
extended: true
teamcity:
path: stdout
sarif:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-line-number
- format: line-number
- format: json
path: stderr
- format: colored-tab
- format: tab
- format: html
- format: checkstyle
path: report.xml
- format: code-climate
- format: junit-xml
- format: junit-xml-extended
- format: github-actions
- format: teamcity
- format: sarif
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_b.golden.yml
================================================
version: "2"
output:
formats:
text:
path: stdout
print-linter-name: true
print-issued-lines: true
json:
path: stderr
tab:
path: stdout
print-linter-name: true
html:
path: stdout
checkstyle:
path: report.xml
code-climate:
path: stdout
junit-xml:
path: stdout
extended: true
teamcity:
path: stdout
sarif:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-line-number
- format: line-number
- format: json
path: stderr
- format: colored-tab
- format: tab
- format: html
- format: checkstyle
path: report.xml
- format: code-climate
- format: junit-xml
- format: junit-xml-extended
- format: github-actions
- format: teamcity
- format: sarif
print-issued-lines: true
print-linter-name: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_c.golden.yml
================================================
version: "2"
output:
formats:
text:
path: stdout
print-linter-name: false
print-issued-lines: false
json:
path: stderr
tab:
path: stdout
print-linter-name: false
html:
path: stdout
checkstyle:
path: report.xml
code-climate:
path: stdout
junit-xml:
path: stdout
extended: true
teamcity:
path: stdout
sarif:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_c.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-line-number
- format: line-number
- format: json
path: stderr
- format: colored-tab
- format: tab
- format: html
- format: checkstyle
path: report.xml
- format: code-climate
- format: junit-xml
- format: junit-xml-extended
- format: github-actions
- format: teamcity
- format: sarif
print-issued-lines: false
print-linter-name: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_d.golden.yml
================================================
version: "2"
output:
formats:
text:
path: stdout
print-linter-name: false
print-issued-lines: true
json:
path: stderr
tab:
path: stdout
print-linter-name: false
html:
path: stdout
checkstyle:
path: report.xml
code-climate:
path: stdout
junit-xml:
path: stdout
extended: true
teamcity:
path: stdout
sarif:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_d.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-line-number
- format: line-number
- format: json
path: stderr
- format: colored-tab
- format: tab
- format: html
- format: checkstyle
path: report.xml
- format: code-climate
- format: junit-xml
- format: junit-xml-extended
- format: github-actions
- format: teamcity
- format: sarif
print-issued-lines: true
print-linter-name: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_f.golden.yml
================================================
version: "2"
output:
formats:
text:
path: stdout
print-linter-name: true
print-issued-lines: false
json:
path: stderr
tab:
path: stdout
print-linter-name: true
html:
path: stdout
checkstyle:
path: report.xml
code-climate:
path: stdout
junit-xml:
path: stdout
extended: true
teamcity:
path: stdout
sarif:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_f.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-line-number
- format: line-number
- format: json
path: stderr
- format: colored-tab
- format: tab
- format: html
- format: checkstyle
path: report.xml
- format: code-climate
- format: junit-xml
- format: junit-xml-extended
- format: github-actions
- format: teamcity
- format: sarif
print-issued-lines: false
print-linter-name: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_g.golden.yml
================================================
version: "2"
output:
formats:
text:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_g.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-line-number
- format: line-number
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_h.golden.yml
================================================
version: "2"
output:
formats:
text:
path: stdout
colors: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_h.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: line-number
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_i.golden.yml
================================================
version: "2"
output:
formats:
text:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_i.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-line-number
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_j.golden.yml
================================================
version: "2"
output:
formats:
tab:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_j.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-tab
- format: tab
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_k.golden.yml
================================================
version: "2"
output:
formats:
tab:
path: stdout
colors: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_k.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: tab
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_l.golden.yml
================================================
version: "2"
output:
formats:
tab:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_l.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: colored-tab
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_m.golden.yml
================================================
version: "2"
output:
formats:
junit-xml:
path: stdout
extended: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_m.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: junit-xml
- format: junit-xml-extended
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_o.golden.yml
================================================
version: "2"
output:
formats:
junit-xml:
path: stdout
extended: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_o.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: junit-xml-extended
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_p.golden.yml
================================================
version: "2"
output:
formats:
junit-xml:
path: stdout
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_01_p.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
formats:
- format: junit-xml
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_02.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_02.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
print-issued-lines: true
print-linter-name: true
sort-results: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_03.golden.yml
================================================
version: "2"
output:
sort-order:
- linter
- severity
- file
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_03.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
sort-results: true
sort-order:
- linter
- severity
- file
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_04.golden.yml
================================================
version: "2"
output:
path-prefix: foo
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/output_04.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
output:
path-prefix: "foo"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_01.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_01.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
timeout: 5m
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_02_a.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_02_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
relative-path-mode: cfg
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_02_b.golden.yml
================================================
version: "2"
run:
relative-path-mode: gomod
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_02_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
relative-path-mode: gomod
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_03_a.golden.yml
================================================
version: "2"
run:
issues-exit-code: 2
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_03_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
issues-exit-code: 2
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_03_b.golden.yml
================================================
version: "2"
run:
issues-exit-code: 0
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_03_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
issues-exit-code: 0
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_04_a.golden.yml
================================================
version: "2"
run:
tests: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_04_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
tests: false
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_04_b.golden.yml
================================================
version: "2"
run:
tests: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_04_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
tests: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_05.golden.yml
================================================
version: "2"
run:
build-tags:
- mytag
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_05.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
build-tags:
- mytag
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_06.golden.yml
================================================
version: "2"
run:
modules-download-mode: readonly
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_06.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
modules-download-mode: readonly
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_07.golden.yml
================================================
version: "2"
run:
allow-parallel-runners: true
allow-serial-runners: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_07.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
allow-parallel-runners: true
allow-serial-runners: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_08.golden.yml
================================================
version: "2"
run:
go: "1.19"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_08.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
go: '1.19'
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_09_a.golden.yml
================================================
version: "2"
run:
concurrency: 4
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_09_a.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
concurrency: 4
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_09_b.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_09_b.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
concurrency: 0
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_10.golden.yml
================================================
version: "2"
run:
concurrency: 4
go: "1.19"
relative-path-mode: gomod
build-tags:
- mytag
modules-download-mode: readonly
issues-exit-code: 2
tests: false
allow-parallel-runners: true
allow-serial-runners: true
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/run_10.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
run:
timeout: 5m
relative-path-mode: gomod
issues-exit-code: 2
tests: false
build-tags:
- mytag
modules-download-mode: readonly
allow-parallel-runners: true
allow-serial-runners: true
go: '1.19'
concurrency: 4
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/severity_01.golden.yml
================================================
version: "2"
severity:
default: error
rules:
- linters:
- dupl
severity: info
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/severity_01.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
severity:
default-severity: error
case-sensitive: true
rules:
- linters:
- dupl
severity: info
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/severity_02.golden.yml
================================================
version: "2"
severity:
default: error
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/severity_02.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
severity:
default-severity: error
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/severity_03.golden.yml
================================================
version: "2"
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/severity_03.yml
================================================
issues:
# Only to not generate unrelated elements inside golden.
exclude-use-default: false
# Only to not generate unrelated elements inside golden.
exclude-generated: strict
# Only to not generate unrelated elements inside golden.
exclude-dirs-use-default: false
severity:
rules:
- path: _test\.go
severity: info
linters:
- typecheck
- path-except: _test\.go
severity: info
linters:
- typecheck
- path: internal/hmac/
severity: info
text: "weak cryptographic primitive"
linters:
- typecheck
- linters:
- typecheck
text: "SA9003:"
severity: info
- linters:
- typecheck
source: "foo"
severity: info
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/unknown-fields.golden.yml
================================================
version: "2"
linters:
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- third_party$
- builtin$
- examples$
formatters:
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
================================================
FILE: pkg/commands/internal/migrate/testdata/yaml/unknown-fields.yml
================================================
foo:
bar: a
================================================
FILE: pkg/commands/internal/migrate/versionone/base_rule.go
================================================
package versionone
type BaseRule struct {
Linters []string `mapstructure:"linters"`
Path *string `mapstructure:"path"`
PathExcept *string `mapstructure:"path-except"`
Text *string `mapstructure:"text"`
Source *string `mapstructure:"source"`
}
================================================
FILE: pkg/commands/internal/migrate/versionone/config.go
================================================
package versionone
type Config struct {
Version string `mapstructure:"version"` // From v2, to be able to detect already migrated config file.
Run Run `mapstructure:"run"`
Output Output `mapstructure:"output"`
LintersSettings LintersSettings `mapstructure:"linters-settings"`
Linters Linters `mapstructure:"linters"`
Issues Issues `mapstructure:"issues"`
Severity Severity `mapstructure:"severity"`
}
func NewConfig() *Config {
return &Config{}
}
================================================
FILE: pkg/commands/internal/migrate/versionone/doc.go
================================================
// Package versionone contains a modified copy of v1 configuration.
// The structures are altered to use pointer on builtin types.
// The field version is added to enforce the detection of already migrated file.
package versionone
================================================
FILE: pkg/commands/internal/migrate/versionone/issues.go
================================================
package versionone
type Issues struct {
IncludeDefaultExcludes []string `mapstructure:"include"`
ExcludeCaseSensitive *bool `mapstructure:"exclude-case-sensitive"`
ExcludePatterns []string `mapstructure:"exclude"`
ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"`
UseDefaultExcludes *bool `mapstructure:"exclude-use-default"`
ExcludeGenerated *string `mapstructure:"exclude-generated"`
ExcludeFiles []string `mapstructure:"exclude-files"`
ExcludeDirs []string `mapstructure:"exclude-dirs"`
UseDefaultExcludeDirs *bool `mapstructure:"exclude-dirs-use-default"`
MaxIssuesPerLinter *int `mapstructure:"max-issues-per-linter"`
MaxSameIssues *int `mapstructure:"max-same-issues"`
UniqByLine *bool `mapstructure:"uniq-by-line"`
DiffFromRevision *string `mapstructure:"new-from-rev"`
DiffFromMergeBase *string `mapstructure:"new-from-merge-base"`
DiffPatchFilePath *string `mapstructure:"new-from-patch"`
WholeFiles *bool `mapstructure:"whole-files"`
Diff *bool `mapstructure:"new"`
NeedFix *bool `mapstructure:"fix"`
}
type ExcludeRule struct {
BaseRule `mapstructure:",squash"`
}
================================================
FILE: pkg/commands/internal/migrate/versionone/linters.go
================================================
package versionone
type Linters struct {
Enable []string `mapstructure:"enable"`
Disable []string `mapstructure:"disable"`
EnableAll *bool `mapstructure:"enable-all"`
DisableAll *bool `mapstructure:"disable-all"`
Fast *bool `mapstructure:"fast"`
Presets []string `mapstructure:"presets"`
}
================================================
FILE: pkg/commands/internal/migrate/versionone/linters_settings.go
================================================
package versionone
import (
"encoding"
"go.yaml.in/yaml/v3"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
)
type LintersSettings struct {
Asasalint AsasalintSettings `mapstructure:"asasalint"`
BiDiChk BiDiChkSettings `mapstructure:"bidichk"`
CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"`
Cyclop Cyclop `mapstructure:"cyclop"`
Decorder DecorderSettings `mapstructure:"decorder"`
Depguard DepGuardSettings `mapstructure:"depguard"`
Dogsled DogsledSettings `mapstructure:"dogsled"`
Dupl DuplSettings `mapstructure:"dupl"`
DupWord DupWordSettings `mapstructure:"dupword"`
Errcheck ErrcheckSettings `mapstructure:"errcheck"`
ErrChkJSON ErrChkJSONSettings `mapstructure:"errchkjson"`
ErrorLint ErrorLintSettings `mapstructure:"errorlint"`
Exhaustive ExhaustiveSettings `mapstructure:"exhaustive"`
Exhaustruct ExhaustructSettings `mapstructure:"exhaustruct"`
Fatcontext FatcontextSettings `mapstructure:"fatcontext"`
Forbidigo ForbidigoSettings `mapstructure:"forbidigo"`
Funlen FunlenSettings `mapstructure:"funlen"`
GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"`
Gocognit GocognitSettings `mapstructure:"gocognit"`
GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"`
Goconst GoConstSettings `mapstructure:"goconst"`
Gocritic GoCriticSettings `mapstructure:"gocritic"`
Gocyclo GoCycloSettings `mapstructure:"gocyclo"`
Godot GodotSettings `mapstructure:"godot"`
Godox GodoxSettings `mapstructure:"godox"`
Goheader GoHeaderSettings `mapstructure:"goheader"`
GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"`
Gomodguard GoModGuardSettings `mapstructure:"gomodguard"`
Gosec GoSecSettings `mapstructure:"gosec"`
Gosimple StaticCheckSettings `mapstructure:"gosimple"`
Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"`
Govet GovetSettings `mapstructure:"govet"`
Grouper GrouperSettings `mapstructure:"grouper"`
Iface IfaceSettings `mapstructure:"iface"`
ImportAs ImportAsSettings `mapstructure:"importas"`
Inamedparam INamedParamSettings `mapstructure:"inamedparam"`
InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"`
Ireturn IreturnSettings `mapstructure:"ireturn"`
Lll LllSettings `mapstructure:"lll"`
LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"`
MaintIdx MaintIdxSettings `mapstructure:"maintidx"`
Makezero MakezeroSettings `mapstructure:"makezero"`
Misspell MisspellSettings `mapstructure:"misspell"`
Mnd MndSettings `mapstructure:"mnd"`
MustTag MustTagSettings `mapstructure:"musttag"`
Nakedret NakedretSettings `mapstructure:"nakedret"`
Nestif NestifSettings `mapstructure:"nestif"`
NilNil NilNilSettings `mapstructure:"nilnil"`
Nlreturn NlreturnSettings `mapstructure:"nlreturn"`
NoLintLint NoLintLintSettings `mapstructure:"nolintlint"`
NoNamedReturns NoNamedReturnsSettings `mapstructure:"nonamedreturns"`
ParallelTest ParallelTestSettings `mapstructure:"paralleltest"`
PerfSprint PerfSprintSettings `mapstructure:"perfsprint"`
Prealloc PreallocSettings `mapstructure:"prealloc"`
Predeclared PredeclaredSettings `mapstructure:"predeclared"`
Promlinter PromlinterSettings `mapstructure:"promlinter"`
ProtoGetter ProtoGetterSettings `mapstructure:"protogetter"`
Reassign ReassignSettings `mapstructure:"reassign"`
Recvcheck RecvcheckSettings `mapstructure:"recvcheck"`
Revive ReviveSettings `mapstructure:"revive"`
RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"`
SlogLint SlogLintSettings `mapstructure:"sloglint"`
Spancheck SpancheckSettings `mapstructure:"spancheck"`
Staticcheck StaticCheckSettings `mapstructure:"staticcheck"`
Stylecheck StaticCheckSettings `mapstructure:"stylecheck"`
TagAlign TagAlignSettings `mapstructure:"tagalign"`
Tagliatelle TagliatelleSettings `mapstructure:"tagliatelle"`
Tenv TenvSettings `mapstructure:"tenv"`
Testifylint TestifylintSettings `mapstructure:"testifylint"`
Testpackage TestpackageSettings `mapstructure:"testpackage"`
Thelper ThelperSettings `mapstructure:"thelper"`
Unconvert UnconvertSettings `mapstructure:"unconvert"`
Unparam UnparamSettings `mapstructure:"unparam"`
Unused UnusedSettings `mapstructure:"unused"`
UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"`
UseTesting UseTestingSettings `mapstructure:"usetesting"`
Varnamelen VarnamelenSettings `mapstructure:"varnamelen"`
Whitespace WhitespaceSettings `mapstructure:"whitespace"`
Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"`
WSL WSLSettings `mapstructure:"wsl"`
Custom map[string]CustomLinterSettings `mapstructure:"custom"`
Gci GciSettings `mapstructure:"gci"`
GoFmt GoFmtSettings `mapstructure:"gofmt"`
GoFumpt GoFumptSettings `mapstructure:"gofumpt"`
GoImports GoImportsSettings `mapstructure:"goimports"`
}
type AsasalintSettings struct {
Exclude []string `mapstructure:"exclude"`
UseBuiltinExclusions *bool `mapstructure:"use-builtin-exclusions"`
IgnoreTest *bool `mapstructure:"ignore-test"`
}
type BiDiChkSettings struct {
LeftToRightEmbedding *bool `mapstructure:"left-to-right-embedding"`
RightToLeftEmbedding *bool `mapstructure:"right-to-left-embedding"`
PopDirectionalFormatting *bool `mapstructure:"pop-directional-formatting"`
LeftToRightOverride *bool `mapstructure:"left-to-right-override"`
RightToLeftOverride *bool `mapstructure:"right-to-left-override"`
LeftToRightIsolate *bool `mapstructure:"left-to-right-isolate"`
RightToLeftIsolate *bool `mapstructure:"right-to-left-isolate"`
FirstStrongIsolate *bool `mapstructure:"first-strong-isolate"`
PopDirectionalIsolate *bool `mapstructure:"pop-directional-isolate"`
}
type CopyLoopVarSettings struct {
CheckAlias *bool `mapstructure:"check-alias"`
// Deprecated: use CheckAlias
IgnoreAlias *bool `mapstructure:"ignore-alias"`
}
type Cyclop struct {
MaxComplexity *int `mapstructure:"max-complexity"`
PackageAverage *float64 `mapstructure:"package-average"`
SkipTests *bool `mapstructure:"skip-tests"`
}
type DepGuardSettings struct {
Rules map[string]*DepGuardList `mapstructure:"rules"`
}
type DepGuardList struct {
ListMode *string `mapstructure:"list-mode"`
Files []string `mapstructure:"files"`
Allow []string `mapstructure:"allow"`
Deny []DepGuardDeny `mapstructure:"deny"`
}
type DepGuardDeny struct {
Pkg *string `mapstructure:"pkg"`
Desc *string `mapstructure:"desc"`
}
type DecorderSettings struct {
DecOrder []string `mapstructure:"dec-order"`
IgnoreUnderscoreVars *bool `mapstructure:"ignore-underscore-vars"`
DisableDecNumCheck *bool `mapstructure:"disable-dec-num-check"`
DisableTypeDecNumCheck *bool `mapstructure:"disable-type-dec-num-check"`
DisableConstDecNumCheck *bool `mapstructure:"disable-const-dec-num-check"`
DisableVarDecNumCheck *bool `mapstructure:"disable-var-dec-num-check"`
DisableDecOrderCheck *bool `mapstructure:"disable-dec-order-check"`
DisableInitFuncFirstCheck *bool `mapstructure:"disable-init-func-first-check"`
}
type DogsledSettings struct {
MaxBlankIdentifiers *int `mapstructure:"max-blank-identifiers"`
}
type DuplSettings struct {
Threshold *int `mapstructure:"threshold"`
}
type DupWordSettings struct {
Keywords []string `mapstructure:"keywords"`
Ignore []string `mapstructure:"ignore"`
}
type ErrcheckSettings struct {
DisableDefaultExclusions *bool `mapstructure:"disable-default-exclusions"`
CheckTypeAssertions *bool `mapstructure:"check-type-assertions"`
CheckAssignToBlank *bool `mapstructure:"check-blank"`
ExcludeFunctions []string `mapstructure:"exclude-functions"`
// Deprecated: use ExcludeFunctions instead
Exclude *string `mapstructure:"exclude"`
// Deprecated: use ExcludeFunctions instead
Ignore *string `mapstructure:"ignore"`
}
type ErrChkJSONSettings struct {
CheckErrorFreeEncoding *bool `mapstructure:"check-error-free-encoding"`
ReportNoExported *bool `mapstructure:"report-no-exported"`
}
type ErrorLintSettings struct {
Errorf *bool `mapstructure:"errorf"`
ErrorfMulti *bool `mapstructure:"errorf-multi"`
Asserts *bool `mapstructure:"asserts"`
Comparison *bool `mapstructure:"comparison"`
AllowedErrors []ErrorLintAllowPair `mapstructure:"allowed-errors"`
AllowedErrorsWildcard []ErrorLintAllowPair `mapstructure:"allowed-errors-wildcard"`
}
type ErrorLintAllowPair struct {
Err *string `mapstructure:"err"`
Fun *string `mapstructure:"fun"`
}
type ExhaustiveSettings struct {
Check []string `mapstructure:"check"`
CheckGenerated *bool `mapstructure:"check-generated"`
DefaultSignifiesExhaustive *bool `mapstructure:"default-signifies-exhaustive"`
IgnoreEnumMembers *string `mapstructure:"ignore-enum-members"`
IgnoreEnumTypes *string `mapstructure:"ignore-enum-types"`
PackageScopeOnly *bool `mapstructure:"package-scope-only"`
ExplicitExhaustiveMap *bool `mapstructure:"explicit-exhaustive-map"`
ExplicitExhaustiveSwitch *bool `mapstructure:"explicit-exhaustive-switch"`
DefaultCaseRequired *bool `mapstructure:"default-case-required"`
}
type ExhaustructSettings struct {
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
}
type FatcontextSettings struct {
CheckStructPointers *bool `mapstructure:"check-struct-pointers"`
}
type ForbidigoSettings struct {
Forbid []ForbidigoPattern `mapstructure:"forbid"`
ExcludeGodocExamples *bool `mapstructure:"exclude-godoc-examples"`
AnalyzeTypes *bool `mapstructure:"analyze-types"`
}
var _ encoding.TextUnmarshaler = &ForbidigoPattern{}
// ForbidigoPattern corresponds to forbidigo.pattern and adds mapstructure support.
// The YAML field names must match what forbidigo expects.
type ForbidigoPattern struct {
// patternString gets populated when the config contains a *string as entry in ForbidigoSettings.Forbid[]
// because ForbidigoPattern implements encoding.TextUnmarshaler
// and the reader uses the mapstructure.TextUnmarshallerHookFunc as decoder hook.
//
// If the entry is a map, then the other fields are set as usual by mapstructure.
patternString *string
Pattern *string `yaml:"p" mapstructure:"p"`
Package *string `yaml:"pkg,omitempty" mapstructure:"pkg,omitempty"`
Msg *string `yaml:"msg,omitempty" mapstructure:"msg,omitempty"`
}
func (p *ForbidigoPattern) UnmarshalText(text []byte) error {
// Validation happens when instantiating forbidigo.
p.patternString = ptr.Pointer(string(text))
return nil
}
// MarshalString converts the pattern into a *string as needed by forbidigo.NewLinter.
//
// MarshalString is intentionally not called MarshalText,
// although it has the same signature
// because implementing encoding.TextMarshaler led to infinite recursion when yaml.Marshal called MarshalText.
func (p *ForbidigoPattern) MarshalString() ([]byte, error) {
if ptr.Deref(p.patternString) != "" {
return []byte(ptr.Deref(p.patternString)), nil
}
return yaml.Marshal(p)
}
type FunlenSettings struct {
Lines *int `mapstructure:"lines"`
Statements *int `mapstructure:"statements"`
IgnoreComments *bool `mapstructure:"ignore-comments"`
}
type GinkgoLinterSettings struct {
SuppressLenAssertion *bool `mapstructure:"suppress-len-assertion"`
SuppressNilAssertion *bool `mapstructure:"suppress-nil-assertion"`
SuppressErrAssertion *bool `mapstructure:"suppress-err-assertion"`
SuppressCompareAssertion *bool `mapstructure:"suppress-compare-assertion"`
SuppressAsyncAssertion *bool `mapstructure:"suppress-async-assertion"`
SuppressTypeCompareWarning *bool `mapstructure:"suppress-type-compare-assertion"`
ForbidFocusContainer *bool `mapstructure:"forbid-focus-container"`
AllowHaveLenZero *bool `mapstructure:"allow-havelen-zero"`
ForceExpectTo *bool `mapstructure:"force-expect-to"`
ValidateAsyncIntervals *bool `mapstructure:"validate-async-intervals"`
ForbidSpecPollution *bool `mapstructure:"forbid-spec-pollution"`
ForceSucceedForFuncs *bool `mapstructure:"force-succeed"`
}
type GoChecksumTypeSettings struct {
DefaultSignifiesExhaustive *bool `mapstructure:"default-signifies-exhaustive"`
IncludeSharedInterfaces *bool `mapstructure:"include-shared-interfaces"`
}
type GocognitSettings struct {
MinComplexity *int `mapstructure:"min-complexity"`
}
type GoConstSettings struct {
IgnoreStrings *string `mapstructure:"ignore-strings"`
IgnoreTests *bool `mapstructure:"ignore-tests"`
MatchWithConstants *bool `mapstructure:"match-constant"`
MinStringLen *int `mapstructure:"min-len"`
MinOccurrencesCount *int `mapstructure:"min-occurrences"`
ParseNumbers *bool `mapstructure:"numbers"`
NumberMin *int `mapstructure:"min"`
NumberMax *int `mapstructure:"max"`
IgnoreCalls *bool `mapstructure:"ignore-calls"`
}
type GoCriticSettings struct {
Go *string `mapstructure:"-"`
DisableAll *bool `mapstructure:"disable-all"`
EnabledChecks []string `mapstructure:"enabled-checks"`
EnableAll *bool `mapstructure:"enable-all"`
DisabledChecks []string `mapstructure:"disabled-checks"`
EnabledTags []string `mapstructure:"enabled-tags"`
DisabledTags []string `mapstructure:"disabled-tags"`
SettingsPerCheck map[string]GoCriticCheckSettings `mapstructure:"settings"`
}
type GoCriticCheckSettings map[string]any
type GoCycloSettings struct {
MinComplexity *int `mapstructure:"min-complexity"`
}
type GodotSettings struct {
Scope *string `mapstructure:"scope"`
Exclude []string `mapstructure:"exclude"`
Capital *bool `mapstructure:"capital"`
Period *bool `mapstructure:"period"`
// Deprecated: use Scope instead
CheckAll *bool `mapstructure:"check-all"`
}
type GodoxSettings struct {
Keywords []string `mapstructure:"keywords"`
}
type GoHeaderSettings struct {
Values map[string]map[string]string `mapstructure:"values"`
Template *string `mapstructure:"template"`
TemplatePath *string `mapstructure:"template-path"`
}
type GoModDirectivesSettings struct {
ReplaceAllowList []string `mapstructure:"replace-allow-list"`
ReplaceLocal *bool `mapstructure:"replace-local"`
ExcludeForbidden *bool `mapstructure:"exclude-forbidden"`
RetractAllowNoExplanation *bool `mapstructure:"retract-allow-no-explanation"`
ToolchainForbidden *bool `mapstructure:"toolchain-forbidden"`
ToolchainPattern *string `mapstructure:"toolchain-pattern"`
ToolForbidden *bool `mapstructure:"tool-forbidden"`
GoDebugForbidden *bool `mapstructure:"go-debug-forbidden"`
GoVersionPattern *string `mapstructure:"go-version-pattern"`
}
type GoModGuardSettings struct {
Allowed struct {
Modules []string `mapstructure:"modules"`
Domains []string `mapstructure:"domains"`
} `mapstructure:"allowed"`
Blocked struct {
Modules []map[string]struct {
Recommendations []string `mapstructure:"recommendations"`
Reason *string `mapstructure:"reason"`
} `mapstructure:"modules"`
Versions []map[string]struct {
Version *string `mapstructure:"version"`
Reason *string `mapstructure:"reason"`
} `mapstructure:"versions"`
LocalReplaceDirectives *bool `mapstructure:"local_replace_directives"`
} `mapstructure:"blocked"`
}
type GoSecSettings struct {
Includes []string `mapstructure:"includes"`
Excludes []string `mapstructure:"excludes"`
Severity *string `mapstructure:"severity"`
Confidence *string `mapstructure:"confidence"`
ExcludeGenerated *bool `mapstructure:"exclude-generated"`
Config map[string]any `mapstructure:"config"`
Concurrency *int `mapstructure:"concurrency"`
}
type GosmopolitanSettings struct {
AllowTimeLocal *bool `mapstructure:"allow-time-local"`
EscapeHatches []string `mapstructure:"escape-hatches"`
IgnoreTests *bool `mapstructure:"ignore-tests"`
WatchForScripts []string `mapstructure:"watch-for-scripts"`
}
type GovetSettings struct {
Go *string `mapstructure:"-"`
Enable []string `mapstructure:"enable"`
Disable []string `mapstructure:"disable"`
EnableAll *bool `mapstructure:"enable-all"`
DisableAll *bool `mapstructure:"disable-all"`
Settings map[string]map[string]any `mapstructure:"settings"`
// Deprecated: the linter should be enabled inside Enable.
CheckShadowing *bool `mapstructure:"check-shadowing"`
}
type GrouperSettings struct {
ConstRequireSingleConst *bool `mapstructure:"const-require-single-const"`
ConstRequireGrouping *bool `mapstructure:"const-require-grouping"`
ImportRequireSingleImport *bool `mapstructure:"import-require-single-import"`
ImportRequireGrouping *bool `mapstructure:"import-require-grouping"`
TypeRequireSingleType *bool `mapstructure:"type-require-single-type"`
TypeRequireGrouping *bool `mapstructure:"type-require-grouping"`
VarRequireSingleVar *bool `mapstructure:"var-require-single-var"`
VarRequireGrouping *bool `mapstructure:"var-require-grouping"`
}
type IfaceSettings struct {
Enable []string `mapstructure:"enable"`
Settings map[string]map[string]any `mapstructure:"settings"`
}
type ImportAsSettings struct {
Alias []ImportAsAlias `mapstructure:"alias"`
NoUnaliased *bool `mapstructure:"no-unaliased"`
NoExtraAliases *bool `mapstructure:"no-extra-aliases"`
}
type ImportAsAlias struct {
Pkg *string `mapstructure:"pkg"`
Alias *string `mapstructure:"alias"`
}
type INamedParamSettings struct {
SkipSingleParam *bool `mapstructure:"skip-single-param"`
}
type InterfaceBloatSettings struct {
Max *int `mapstructure:"max"`
}
type IreturnSettings struct {
Allow []string `mapstructure:"allow"`
Reject []string `mapstructure:"reject"`
}
type LllSettings struct {
LineLength *int `mapstructure:"line-length"`
TabWidth *int `mapstructure:"tab-width"`
}
type LoggerCheckSettings struct {
Kitlog *bool `mapstructure:"kitlog"`
Klog *bool `mapstructure:"klog"`
Logr *bool `mapstructure:"logr"`
Slog *bool `mapstructure:"slog"`
Zap *bool `mapstructure:"zap"`
RequireStringKey *bool `mapstructure:"require-string-key"`
NoPrintfLike *bool `mapstructure:"no-printf-like"`
Rules []string `mapstructure:"rules"`
}
type MaintIdxSettings struct {
Under *int `mapstructure:"under"`
}
type MakezeroSettings struct {
Always *bool `mapstructure:"always"`
}
type MisspellSettings struct {
Mode *string `mapstructure:"mode"`
Locale *string `mapstructure:"locale"`
ExtraWords []MisspellExtraWords `mapstructure:"extra-words"`
// TODO(ldez): v2 the option must be renamed to `IgnoredRules`.
IgnoreWords []string `mapstructure:"ignore-words"`
}
type MisspellExtraWords struct {
Typo *string `mapstructure:"typo"`
Correction *string `mapstructure:"correction"`
}
type MustTagSettings struct {
Functions []struct {
Name *string `mapstructure:"name"`
Tag *string `mapstructure:"tag"`
ArgPos *int `mapstructure:"arg-pos"`
} `mapstructure:"functions"`
}
type NakedretSettings struct {
MaxFuncLines *uint `mapstructure:"max-func-lines"`
}
type NestifSettings struct {
MinComplexity *int `mapstructure:"min-complexity"`
}
type NilNilSettings struct {
DetectOpposite *bool `mapstructure:"detect-opposite"`
CheckedTypes []string `mapstructure:"checked-types"`
}
type NlreturnSettings struct {
BlockSize *int `mapstructure:"block-size"`
}
type MndSettings struct {
Checks []string `mapstructure:"checks"`
IgnoredNumbers []string `mapstructure:"ignored-numbers"`
IgnoredFiles []string `mapstructure:"ignored-files"`
IgnoredFunctions []string `mapstructure:"ignored-functions"`
}
type NoLintLintSettings struct {
RequireExplanation *bool `mapstructure:"require-explanation"`
RequireSpecific *bool `mapstructure:"require-specific"`
AllowNoExplanation []string `mapstructure:"allow-no-explanation"`
AllowUnused *bool `mapstructure:"allow-unused"`
}
type NoNamedReturnsSettings struct {
ReportErrorInDefer *bool `mapstructure:"report-error-in-defer"`
}
type ParallelTestSettings struct {
Go *string `mapstructure:"-"`
IgnoreMissing *bool `mapstructure:"ignore-missing"`
IgnoreMissingSubtests *bool `mapstructure:"ignore-missing-subtests"`
}
type PerfSprintSettings struct {
IntegerFormat *bool `mapstructure:"integer-format"`
IntConversion *bool `mapstructure:"int-conversion"`
ErrorFormat *bool `mapstructure:"error-format"`
ErrError *bool `mapstructure:"err-error"`
ErrorF *bool `mapstructure:"errorf"`
StringFormat *bool `mapstructure:"string-format"`
SprintF1 *bool `mapstructure:"sprintf1"`
StrConcat *bool `mapstructure:"strconcat"`
BoolFormat *bool `mapstructure:"bool-format"`
HexFormat *bool `mapstructure:"hex-format"`
}
type PreallocSettings struct {
Simple *bool `mapstructure:"simple"`
RangeLoops *bool `mapstructure:"range-loops"`
ForLoops *bool `mapstructure:"for-loops"`
}
type PredeclaredSettings struct {
Ignore *string `mapstructure:"ignore"`
Qualified *bool `mapstructure:"q"`
}
type PromlinterSettings struct {
Strict *bool `mapstructure:"strict"`
DisabledLinters []string `mapstructure:"disabled-linters"`
}
type ProtoGetterSettings struct {
SkipGeneratedBy []string `mapstructure:"skip-generated-by"`
SkipFiles []string `mapstructure:"skip-files"`
SkipAnyGenerated *bool `mapstructure:"skip-any-generated"`
ReplaceFirstArgInAppend *bool `mapstructure:"replace-first-arg-in-append"`
}
type ReassignSettings struct {
Patterns []string `mapstructure:"patterns"`
}
type RecvcheckSettings struct {
DisableBuiltin *bool `mapstructure:"disable-builtin"`
Exclusions []string `mapstructure:"exclusions"`
}
type ReviveSettings struct {
Go *string `mapstructure:"-"`
MaxOpenFiles *int `mapstructure:"max-open-files"`
IgnoreGeneratedHeader *bool `mapstructure:"ignore-generated-header"`
Confidence *float64 `mapstructure:"confidence"`
Severity *string `mapstructure:"severity"`
EnableAllRules *bool `mapstructure:"enable-all-rules"`
Rules []struct {
Name *string `mapstructure:"name"`
Arguments []any `mapstructure:"arguments"`
Severity *string `mapstructure:"severity"`
Disabled *bool `mapstructure:"disabled"`
Exclude []string `mapstructure:"exclude"`
} `mapstructure:"rules"`
ErrorCode *int `mapstructure:"error-code"`
WarningCode *int `mapstructure:"warning-code"`
Directives []struct {
Name *string `mapstructure:"name"`
Severity *string `mapstructure:"severity"`
} `mapstructure:"directives"`
}
type RowsErrCheckSettings struct {
Packages []string `mapstructure:"packages"`
}
type SlogLintSettings struct {
NoMixedArgs *bool `mapstructure:"no-mixed-args"`
KVOnly *bool `mapstructure:"kv-only"`
AttrOnly *bool `mapstructure:"attr-only"`
NoGlobal *string `mapstructure:"no-global"`
Context *string `mapstructure:"context"`
StaticMsg *bool `mapstructure:"static-msg"`
NoRawKeys *bool `mapstructure:"no-raw-keys"`
KeyNamingCase *string `mapstructure:"key-naming-case"`
ForbiddenKeys []string `mapstructure:"forbidden-keys"`
ArgsOnSepLines *bool `mapstructure:"args-on-sep-lines"`
}
type SpancheckSettings struct {
Checks []string `mapstructure:"checks"`
IgnoreCheckSignatures []string `mapstructure:"ignore-check-signatures"`
ExtraStartSpanSignatures []string `mapstructure:"extra-start-span-signatures"`
}
type StaticCheckSettings struct {
Checks []string `mapstructure:"checks"`
Initialisms []string `mapstructure:"initialisms"` // only for stylecheck
DotImportWhitelist []string `mapstructure:"dot-import-whitelist"` // only for stylecheck
HTTPStatusCodeWhitelist []string `mapstructure:"http-status-code-whitelist"` // only for stylecheck
}
type TagAlignSettings struct {
Align *bool `mapstructure:"align"`
Sort *bool `mapstructure:"sort"`
Order []string `mapstructure:"order"`
Strict *bool `mapstructure:"strict"`
}
type TagliatelleSettings struct {
Case TagliatelleCase `mapstructure:"case"`
}
type TagliatelleCase struct {
TagliatelleBase `mapstructure:",squash"`
Overrides []TagliatelleOverrides `mapstructure:"overrides"`
}
type TagliatelleOverrides struct {
TagliatelleBase `mapstructure:",squash"`
Package *string `mapstructure:"pkg"`
Ignore *bool `mapstructure:"ignore"`
}
type TagliatelleBase struct {
Rules map[string]string `mapstructure:"rules"`
ExtendedRules map[string]TagliatelleExtendedRule `mapstructure:"extended-rules"`
UseFieldName *bool `mapstructure:"use-field-name"`
IgnoredFields []string `mapstructure:"ignored-fields"`
}
type TagliatelleExtendedRule struct {
Case *string `mapstructure:"case"`
ExtraInitialisms *bool `mapstructure:"extra-initialisms"`
InitialismOverrides map[string]bool `mapstructure:"initialism-overrides"`
}
type TestifylintSettings struct {
EnableAll *bool `mapstructure:"enable-all"`
DisableAll *bool `mapstructure:"disable-all"`
EnabledCheckers []string `mapstructure:"enable"`
DisabledCheckers []string `mapstructure:"disable"`
BoolCompare struct {
IgnoreCustomTypes *bool `mapstructure:"ignore-custom-types"`
} `mapstructure:"bool-compare"`
ExpectedActual struct {
ExpVarPattern *string `mapstructure:"pattern"`
} `mapstructure:"expected-actual"`
Formatter struct {
CheckFormatString *bool `mapstructure:"check-format-string"`
RequireFFuncs *bool `mapstructure:"require-f-funcs"`
} `mapstructure:"formatter"`
GoRequire struct {
IgnoreHTTPHandlers *bool `mapstructure:"ignore-http-handlers"`
} `mapstructure:"go-require"`
RequireError struct {
FnPattern *string `mapstructure:"fn-pattern"`
} `mapstructure:"require-error"`
SuiteExtraAssertCall struct {
Mode *string `mapstructure:"mode"`
} `mapstructure:"suite-extra-assert-call"`
}
type TestpackageSettings struct {
SkipRegexp *string `mapstructure:"skip-regexp"`
AllowPackages []string `mapstructure:"allow-packages"`
}
type ThelperSettings struct {
Test ThelperOptions `mapstructure:"test"`
Fuzz ThelperOptions `mapstructure:"fuzz"`
Benchmark ThelperOptions `mapstructure:"benchmark"`
TB ThelperOptions `mapstructure:"tb"`
}
type ThelperOptions struct {
First *bool `mapstructure:"first"`
Name *bool `mapstructure:"name"`
Begin *bool `mapstructure:"begin"`
}
type TenvSettings struct {
All *bool `mapstructure:"all"`
}
type UseStdlibVarsSettings struct {
HTTPMethod *bool `mapstructure:"http-method"`
HTTPStatusCode *bool `mapstructure:"http-status-code"`
TimeWeekday *bool `mapstructure:"time-weekday"`
TimeMonth *bool `mapstructure:"time-month"`
TimeLayout *bool `mapstructure:"time-layout"`
CryptoHash *bool `mapstructure:"crypto-hash"`
DefaultRPCPath *bool `mapstructure:"default-rpc-path"`
SQLIsolationLevel *bool `mapstructure:"sql-isolation-level"`
TLSSignatureScheme *bool `mapstructure:"tls-signature-scheme"`
ConstantKind *bool `mapstructure:"constant-kind"`
// Deprecated
OSDevNull *bool `mapstructure:"os-dev-null"`
// Deprecated
SyslogPriority *bool `mapstructure:"syslog-priority"`
}
type UseTestingSettings struct {
ContextBackground *bool `mapstructure:"context-background"`
ContextTodo *bool `mapstructure:"context-todo"`
OSChdir *bool `mapstructure:"os-chdir"`
OSMkdirTemp *bool `mapstructure:"os-mkdir-temp"`
OSSetenv *bool `mapstructure:"os-setenv"`
OSTempDir *bool `mapstructure:"os-temp-dir"`
OSCreateTemp *bool `mapstructure:"os-create-temp"`
}
type UnconvertSettings struct {
FastMath *bool `mapstructure:"fast-math"`
Safe *bool `mapstructure:"safe"`
}
type UnparamSettings struct {
CheckExported *bool `mapstructure:"check-exported"`
Algo *string `mapstructure:"algo"`
}
type UnusedSettings struct {
FieldWritesAreUses *bool `mapstructure:"field-writes-are-uses"`
PostStatementsAreReads *bool `mapstructure:"post-statements-are-reads"`
ExportedFieldsAreUsed *bool `mapstructure:"exported-fields-are-used"`
ParametersAreUsed *bool `mapstructure:"parameters-are-used"`
LocalVariablesAreUsed *bool `mapstructure:"local-variables-are-used"`
GeneratedIsUsed *bool `mapstructure:"generated-is-used"`
// Deprecated
ExportedIsUsed *bool `mapstructure:"exported-is-used"`
}
type VarnamelenSettings struct {
MaxDistance *int `mapstructure:"max-distance"`
MinNameLength *int `mapstructure:"min-name-length"`
CheckReceiver *bool `mapstructure:"check-receiver"`
CheckReturn *bool `mapstructure:"check-return"`
CheckTypeParam *bool `mapstructure:"check-type-param"`
IgnoreNames []string `mapstructure:"ignore-names"`
IgnoreTypeAssertOk *bool `mapstructure:"ignore-type-assert-ok"`
IgnoreMapIndexOk *bool `mapstructure:"ignore-map-index-ok"`
IgnoreChanRecvOk *bool `mapstructure:"ignore-chan-recv-ok"`
IgnoreDecls []string `mapstructure:"ignore-decls"`
}
type WhitespaceSettings struct {
MultiIf *bool `mapstructure:"multi-if"`
MultiFunc *bool `mapstructure:"multi-func"`
}
type WrapcheckSettings struct {
ExtraIgnoreSigs []string `mapstructure:"extra-ignore-sigs"`
// TODO(ldez): v2 the options must be renamed to use hyphen.
IgnoreSigs []string `mapstructure:"ignoreSigs"`
IgnoreSigRegexps []string `mapstructure:"ignoreSigRegexps"`
IgnorePackageGlobs []string `mapstructure:"ignorePackageGlobs"`
IgnoreInterfaceRegexps []string `mapstructure:"ignoreInterfaceRegexps"`
}
type WSLSettings struct {
StrictAppend *bool `mapstructure:"strict-append"`
AllowAssignAndCallCuddle *bool `mapstructure:"allow-assign-and-call"`
AllowAssignAndAnythingCuddle *bool `mapstructure:"allow-assign-and-anything"`
AllowMultiLineAssignCuddle *bool `mapstructure:"allow-multiline-assign"`
ForceCaseTrailingWhitespaceLimit *int `mapstructure:"force-case-trailing-whitespace"`
AllowTrailingComment *bool `mapstructure:"allow-trailing-comment"`
AllowSeparatedLeadingComment *bool `mapstructure:"allow-separated-leading-comment"`
AllowCuddleDeclaration *bool `mapstructure:"allow-cuddle-declarations"`
AllowCuddleWithCalls []string `mapstructure:"allow-cuddle-with-calls"`
AllowCuddleWithRHS []string `mapstructure:"allow-cuddle-with-rhs"`
ForceCuddleErrCheckAndAssign *bool `mapstructure:"force-err-cuddling"`
ErrorVariableNames []string `mapstructure:"error-variable-names"`
ForceExclusiveShortDeclarations *bool `mapstructure:"force-short-decl-cuddling"`
}
// CustomLinterSettings encapsulates the meta-data of a private linter.
type CustomLinterSettings struct {
// Type plugin type.
// It can be `goplugin` or `module`.
Type *string `mapstructure:"type"`
// Path to a plugin *.so file that implements the private linter.
// Only for Go plugin system.
Path *string `mapstructure:"path"`
// Description describes the purpose of the private linter.
Description *string `mapstructure:"description"`
// OriginalURL The URL containing the source code for the private linter.
OriginalURL *string `mapstructure:"original-url"`
// Settings plugin settings only work with linterdb.PluginConstructor symbol.
Settings any `mapstructure:"settings"`
}
type GciSettings struct {
Sections []string `mapstructure:"sections"`
NoInlineComments *bool `mapstructure:"no-inline-comments"`
NoPrefixComments *bool `mapstructure:"no-prefix-comments"`
SkipGenerated *bool `mapstructure:"skip-generated"`
CustomOrder *bool `mapstructure:"custom-order"`
NoLexOrder *bool `mapstructure:"no-lex-order"`
// Deprecated: use Sections instead.
LocalPrefixes *string `mapstructure:"local-prefixes"`
}
type GoFmtSettings struct {
Simplify *bool `mapstructure:"simplify"`
RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"`
}
type GoFmtRewriteRule struct {
Pattern *string `mapstructure:"pattern"`
Replacement *string `mapstructure:"replacement"`
}
type GoFumptSettings struct {
ModulePath *string `mapstructure:"module-path"`
ExtraRules *bool `mapstructure:"extra-rules"`
// Deprecated: use the global `run.go` instead.
LangVersion *string `mapstructure:"lang-version"`
}
type GoImportsSettings struct {
LocalPrefixes *string `mapstructure:"local-prefixes"`
}
================================================
FILE: pkg/commands/internal/migrate/versionone/output.go
================================================
package versionone
import (
"strings"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
)
type Output struct {
Formats OutputFormats `mapstructure:"formats"`
PrintIssuedLine *bool `mapstructure:"print-issued-lines"`
PrintLinterName *bool `mapstructure:"print-linter-name"`
SortResults *bool `mapstructure:"sort-results"`
SortOrder []string `mapstructure:"sort-order"`
PathPrefix *string `mapstructure:"path-prefix"`
ShowStats *bool `mapstructure:"show-stats"`
}
type OutputFormat struct {
Format *string `mapstructure:"format"`
Path *string `mapstructure:"path"`
}
type OutputFormats []OutputFormat
func (p *OutputFormats) UnmarshalText(text []byte) error {
for item := range strings.SplitSeq(string(text), ",") {
format, path, _ := strings.Cut(item, ":")
*p = append(*p, OutputFormat{
Path: ptr.Pointer(path),
Format: ptr.Pointer(format),
})
}
return nil
}
================================================
FILE: pkg/commands/internal/migrate/versionone/run.go
================================================
package versionone
import (
"time"
)
// Run encapsulates the config options for running the linter analysis.
type Run struct {
Timeout time.Duration `mapstructure:"timeout"`
Concurrency *int `mapstructure:"concurrency"`
Go *string `mapstructure:"go"`
RelativePathMode *string `mapstructure:"relative-path-mode"`
BuildTags []string `mapstructure:"build-tags"`
ModulesDownloadMode *string `mapstructure:"modules-download-mode"`
ExitCodeIfIssuesFound *int `mapstructure:"issues-exit-code"`
AnalyzeTests *bool `mapstructure:"tests"`
AllowParallelRunners *bool `mapstructure:"allow-parallel-runners"`
AllowSerialRunners *bool `mapstructure:"allow-serial-runners"`
}
================================================
FILE: pkg/commands/internal/migrate/versionone/severity.go
================================================
package versionone
type Severity struct {
Default *string `mapstructure:"default-severity"`
CaseSensitive *bool `mapstructure:"case-sensitive"`
Rules []SeverityRule `mapstructure:"rules"`
}
type SeverityRule struct {
BaseRule `mapstructure:",squash"`
Severity *string `mapstructure:"severity"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/base_rule.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type BaseRule struct {
Linters []string `yaml:"linters,omitempty" toml:"linters,multiline,omitempty"`
Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"`
PathExcept *string `yaml:"path-except,omitempty" toml:"path-except,multiline,omitempty"`
Text *string `yaml:"text,omitempty" toml:"text,multiline,omitempty"`
Source *string `yaml:"source,omitempty" toml:"source,multiline,omitempty"`
InternalReference *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/config.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type Config struct {
Version *string `yaml:"version,omitempty" toml:"version,multiline,omitempty"`
Run Run `yaml:"run,omitempty" toml:"run,multiline,omitempty"`
Output Output `yaml:"output,omitempty" toml:"output,multiline,omitempty"`
Linters Linters `yaml:"linters,omitempty" toml:"linters,multiline,omitempty"`
Issues Issues `yaml:"issues,omitempty" toml:"issues,multiline,omitempty"`
Severity Severity `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
Formatters Formatters `yaml:"formatters,omitempty" toml:"formatters,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/formatters.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type Formatters struct {
Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
Settings FormatterSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
Exclusions FormatterExclusions `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"`
}
type FormatterExclusions struct {
Generated *string `yaml:"generated,omitempty" toml:"generated,multiline,omitempty"`
Paths []string `yaml:"paths,omitempty" toml:"paths,multiline,omitempty"`
WarnUnused *bool `yaml:"warn-unused,omitempty" toml:"warn-unused,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/formatters_settings.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type FormatterSettings struct {
Gci GciSettings `yaml:"gci,omitempty" toml:"gci,multiline,omitempty"`
GoFmt GoFmtSettings `yaml:"gofmt,omitempty" toml:"gofmt,multiline,omitempty"`
GoFumpt GoFumptSettings `yaml:"gofumpt,omitempty" toml:"gofumpt,multiline,omitempty"`
GoImports GoImportsSettings `yaml:"goimports,omitempty" toml:"goimports,multiline,omitempty"`
GoLines GoLinesSettings `yaml:"golines,omitempty" toml:"golines,multiline,omitempty"`
}
type GciSettings struct {
Sections []string `yaml:"sections,omitempty" toml:"sections,multiline,omitempty"`
NoInlineComments *bool `yaml:"no-inline-comments,omitempty" toml:"no-inline-comments,multiline,omitempty"`
NoPrefixComments *bool `yaml:"no-prefix-comments,omitempty" toml:"no-prefix-comments,multiline,omitempty"`
CustomOrder *bool `yaml:"custom-order,omitempty" toml:"custom-order,multiline,omitempty"`
NoLexOrder *bool `yaml:"no-lex-order,omitempty" toml:"no-lex-order,multiline,omitempty"`
}
type GoFmtSettings struct {
Simplify *bool `yaml:"simplify,omitempty" toml:"simplify,multiline,omitempty"`
RewriteRules []GoFmtRewriteRule `yaml:"rewrite-rules,omitempty" toml:"rewrite-rules,multiline,omitempty"`
}
type GoFmtRewriteRule struct {
Pattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"`
Replacement *string `yaml:"replacement,omitempty" toml:"replacement,multiline,omitempty"`
}
type GoFumptSettings struct {
ModulePath *string `yaml:"module-path,omitempty" toml:"module-path,multiline,omitempty"`
ExtraRules *bool `yaml:"extra-rules,omitempty" toml:"extra-rules,multiline,omitempty"`
LangVersion *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
}
type GoImportsSettings struct {
LocalPrefixes []string `yaml:"local-prefixes,omitempty" toml:"local-prefixes,multiline,omitempty"`
}
type GoLinesSettings struct {
MaxLen *int `yaml:"max-len,omitempty" toml:"max-len,multiline,omitempty"`
TabLen *int `yaml:"tab-len,omitempty" toml:"tab-len,multiline,omitempty"`
ShortenComments *bool `yaml:"shorten-comments,omitempty" toml:"shorten-comments,multiline,omitempty"`
ReformatTags *bool `yaml:"reformat-tags,omitempty" toml:"reformat-tags,multiline,omitempty"`
ChainSplitDots *bool `yaml:"chain-split-dots,omitempty" toml:"chain-split-dots,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/issues.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type Issues struct {
MaxIssuesPerLinter *int `yaml:"max-issues-per-linter,omitempty" toml:"max-issues-per-linter,multiline,omitempty"`
MaxSameIssues *int `yaml:"max-same-issues,omitempty" toml:"max-same-issues,multiline,omitempty"`
UniqByLine *bool `yaml:"uniq-by-line,omitempty" toml:"uniq-by-line,multiline,omitempty"`
DiffFromRevision *string `yaml:"new-from-rev,omitempty" toml:"new-from-rev,multiline,omitempty"`
DiffFromMergeBase *string `yaml:"new-from-merge-base,omitempty" toml:"new-from-merge-base,multiline,omitempty"`
DiffPatchFilePath *string `yaml:"new-from-patch,omitempty" toml:"new-from-patch,multiline,omitempty"`
WholeFiles *bool `yaml:"whole-files,omitempty" toml:"whole-files,multiline,omitempty"`
Diff *bool `yaml:"new,omitempty" toml:"new,multiline,omitempty"`
NeedFix *bool `yaml:"fix,omitempty" toml:"fix,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/linters.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type Linters struct {
Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"`
Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"`
FastOnly *bool `yaml:"fast-only,omitempty" toml:"fast-only,multiline,omitempty"`
Settings LintersSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
Exclusions LinterExclusions `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/linters_exclusions.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type LinterExclusions struct {
Generated *string `yaml:"generated,omitempty" toml:"generated,multiline,omitempty"`
WarnUnused *bool `yaml:"warn-unused,omitempty" toml:"warn-unused,multiline,omitempty"`
Presets []string `yaml:"presets,omitempty" toml:"presets,multiline,omitempty"`
Rules []ExcludeRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
Paths []string `yaml:"paths,omitempty" toml:"paths,multiline,omitempty"`
PathsExcept []string `yaml:"paths-except,omitempty" toml:"paths-except,multiline,omitempty"`
}
type ExcludeRule struct {
BaseRule `yaml:",inline"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/linters_settings.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type LintersSettings struct {
FormatterSettings `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
Asasalint AsasalintSettings `yaml:"asasalint,omitempty" toml:"asasalint,multiline,omitempty"`
BiDiChk BiDiChkSettings `yaml:"bidichk,omitempty" toml:"bidichk,multiline,omitempty"`
CopyLoopVar CopyLoopVarSettings `yaml:"copyloopvar,omitempty" toml:"copyloopvar,multiline,omitempty"`
Cyclop CyclopSettings `yaml:"cyclop,omitempty" toml:"cyclop,multiline,omitempty"`
Decorder DecorderSettings `yaml:"decorder,omitempty" toml:"decorder,multiline,omitempty"`
Depguard DepGuardSettings `yaml:"depguard,omitempty" toml:"depguard,multiline,omitempty"`
Dogsled DogsledSettings `yaml:"dogsled,omitempty" toml:"dogsled,multiline,omitempty"`
Dupl DuplSettings `yaml:"dupl,omitempty" toml:"dupl,multiline,omitempty"`
DupWord DupWordSettings `yaml:"dupword,omitempty" toml:"dupword,multiline,omitempty"`
EmbeddedStructFieldCheck EmbeddedStructFieldCheckSettings `yaml:"embeddedstructfieldcheck,omitempty" toml:"embeddedstructfieldcheck,multiline,omitempty"`
Errcheck ErrcheckSettings `yaml:"errcheck,omitempty" toml:"errcheck,multiline,omitempty"`
ErrChkJSON ErrChkJSONSettings `yaml:"errchkjson,omitempty" toml:"errchkjson,multiline,omitempty"`
ErrorLint ErrorLintSettings `yaml:"errorlint,omitempty" toml:"errorlint,multiline,omitempty"`
Exhaustive ExhaustiveSettings `yaml:"exhaustive,omitempty" toml:"exhaustive,multiline,omitempty"`
Exhaustruct ExhaustructSettings `yaml:"exhaustruct,omitempty" toml:"exhaustruct,multiline,omitempty"`
Fatcontext FatcontextSettings `yaml:"fatcontext,omitempty" toml:"fatcontext,multiline,omitempty"`
Forbidigo ForbidigoSettings `yaml:"forbidigo,omitempty" toml:"forbidigo,multiline,omitempty"`
FuncOrder FuncOrderSettings `yaml:"funcorder,omitempty" toml:"funcorder,multiline,omitempty"`
Funlen FunlenSettings `yaml:"funlen,omitempty" toml:"funlen,multiline,omitempty"`
GinkgoLinter GinkgoLinterSettings `yaml:"ginkgolinter,omitempty" toml:"ginkgolinter,multiline,omitempty"`
Gocognit GocognitSettings `yaml:"gocognit,omitempty" toml:"gocognit,multiline,omitempty"`
GoChecksumType GoChecksumTypeSettings `yaml:"gochecksumtype,omitempty" toml:"gochecksumtype,multiline,omitempty"`
Goconst GoConstSettings `yaml:"goconst,omitempty" toml:"goconst,multiline,omitempty"`
Gocritic GoCriticSettings `yaml:"gocritic,omitempty" toml:"gocritic,multiline,omitempty"`
Gocyclo GoCycloSettings `yaml:"gocyclo,omitempty" toml:"gocyclo,multiline,omitempty"`
Godot GodotSettings `yaml:"godot,omitempty" toml:"godot,multiline,omitempty"`
Godox GodoxSettings `yaml:"godox,omitempty" toml:"godox,multiline,omitempty"`
Goheader GoHeaderSettings `yaml:"goheader,omitempty" toml:"goheader,multiline,omitempty"`
GoModDirectives GoModDirectivesSettings `yaml:"gomoddirectives,omitempty" toml:"gomoddirectives,multiline,omitempty"`
Gomodguard GoModGuardSettings `yaml:"gomodguard,omitempty" toml:"gomodguard,multiline,omitempty"`
Gosec GoSecSettings `yaml:"gosec,omitempty" toml:"gosec,multiline,omitempty"`
Gosmopolitan GosmopolitanSettings `yaml:"gosmopolitan,omitempty" toml:"gosmopolitan,multiline,omitempty"`
Govet GovetSettings `yaml:"govet,omitempty" toml:"govet,multiline,omitempty"`
Grouper GrouperSettings `yaml:"grouper,omitempty" toml:"grouper,multiline,omitempty"`
Iface IfaceSettings `yaml:"iface,omitempty" toml:"iface,multiline,omitempty"`
ImportAs ImportAsSettings `yaml:"importas,omitempty" toml:"importas,multiline,omitempty"`
Inamedparam INamedParamSettings `yaml:"inamedparam,omitempty" toml:"inamedparam,multiline,omitempty"`
InterfaceBloat InterfaceBloatSettings `yaml:"interfacebloat,omitempty" toml:"interfacebloat,multiline,omitempty"`
Ireturn IreturnSettings `yaml:"ireturn,omitempty" toml:"ireturn,multiline,omitempty"`
Lll LllSettings `yaml:"lll,omitempty" toml:"lll,multiline,omitempty"`
LoggerCheck LoggerCheckSettings `yaml:"loggercheck,omitempty" toml:"loggercheck,multiline,omitempty"`
MaintIdx MaintIdxSettings `yaml:"maintidx,omitempty" toml:"maintidx,multiline,omitempty"`
Makezero MakezeroSettings `yaml:"makezero,omitempty" toml:"makezero,multiline,omitempty"`
Misspell MisspellSettings `yaml:"misspell,omitempty" toml:"misspell,multiline,omitempty"`
Mnd MndSettings `yaml:"mnd,omitempty" toml:"mnd,multiline,omitempty"`
MustTag MustTagSettings `yaml:"musttag,omitempty" toml:"musttag,multiline,omitempty"`
Nakedret NakedretSettings `yaml:"nakedret,omitempty" toml:"nakedret,multiline,omitempty"`
Nestif NestifSettings `yaml:"nestif,omitempty" toml:"nestif,multiline,omitempty"`
NilNil NilNilSettings `yaml:"nilnil,omitempty" toml:"nilnil,multiline,omitempty"`
Nlreturn NlreturnSettings `yaml:"nlreturn,omitempty" toml:"nlreturn,multiline,omitempty"`
NoLintLint NoLintLintSettings `yaml:"nolintlint,omitempty" toml:"nolintlint,multiline,omitempty"`
NoNamedReturns NoNamedReturnsSettings `yaml:"nonamedreturns,omitempty" toml:"nonamedreturns,multiline,omitempty"`
ParallelTest ParallelTestSettings `yaml:"paralleltest,omitempty" toml:"paralleltest,multiline,omitempty"`
PerfSprint PerfSprintSettings `yaml:"perfsprint,omitempty" toml:"perfsprint,multiline,omitempty"`
Prealloc PreallocSettings `yaml:"prealloc,omitempty" toml:"prealloc,multiline,omitempty"`
Predeclared PredeclaredSettings `yaml:"predeclared,omitempty" toml:"predeclared,multiline,omitempty"`
Promlinter PromlinterSettings `yaml:"promlinter,omitempty" toml:"promlinter,multiline,omitempty"`
ProtoGetter ProtoGetterSettings `yaml:"protogetter,omitempty" toml:"protogetter,multiline,omitempty"`
Reassign ReassignSettings `yaml:"reassign,omitempty" toml:"reassign,multiline,omitempty"`
Recvcheck RecvcheckSettings `yaml:"recvcheck,omitempty" toml:"recvcheck,multiline,omitempty"`
Revive ReviveSettings `yaml:"revive,omitempty" toml:"revive,multiline,omitempty"`
RowsErrCheck RowsErrCheckSettings `yaml:"rowserrcheck,omitempty" toml:"rowserrcheck,multiline,omitempty"`
SlogLint SlogLintSettings `yaml:"sloglint,omitempty" toml:"sloglint,multiline,omitempty"`
Spancheck SpancheckSettings `yaml:"spancheck,omitempty" toml:"spancheck,multiline,omitempty"`
Staticcheck StaticCheckSettings `yaml:"staticcheck,omitempty" toml:"staticcheck,multiline,omitempty"`
TagAlign TagAlignSettings `yaml:"tagalign,omitempty" toml:"tagalign,multiline,omitempty"`
Tagliatelle TagliatelleSettings `yaml:"tagliatelle,omitempty" toml:"tagliatelle,multiline,omitempty"`
Testifylint TestifylintSettings `yaml:"testifylint,omitempty" toml:"testifylint,multiline,omitempty"`
Testpackage TestpackageSettings `yaml:"testpackage,omitempty" toml:"testpackage,multiline,omitempty"`
Thelper ThelperSettings `yaml:"thelper,omitempty" toml:"thelper,multiline,omitempty"`
Unconvert UnconvertSettings `yaml:"unconvert,omitempty" toml:"unconvert,multiline,omitempty"`
Unparam UnparamSettings `yaml:"unparam,omitempty" toml:"unparam,multiline,omitempty"`
Unused UnusedSettings `yaml:"unused,omitempty" toml:"unused,multiline,omitempty"`
UseStdlibVars UseStdlibVarsSettings `yaml:"usestdlibvars,omitempty" toml:"usestdlibvars,multiline,omitempty"`
UseTesting UseTestingSettings `yaml:"usetesting,omitempty" toml:"usetesting,multiline,omitempty"`
Varnamelen VarnamelenSettings `yaml:"varnamelen,omitempty" toml:"varnamelen,multiline,omitempty"`
Whitespace WhitespaceSettings `yaml:"whitespace,omitempty" toml:"whitespace,multiline,omitempty"`
Wrapcheck WrapcheckSettings `yaml:"wrapcheck,omitempty" toml:"wrapcheck,multiline,omitempty"`
WSL WSLv4Settings `yaml:"wsl,omitempty" toml:"wsl,multiline,omitempty"`
WSLv5 WSLv5Settings `yaml:"wsl_v5,omitempty" toml:"wsl_v5,multiline,omitempty"`
Custom map[string]CustomLinterSettings `yaml:"custom,omitempty" toml:"custom,multiline,omitempty"`
}
type AsasalintSettings struct {
Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"`
UseBuiltinExclusions *bool `yaml:"use-builtin-exclusions,omitempty" toml:"use-builtin-exclusions,multiline,omitempty"`
}
type BiDiChkSettings struct {
LeftToRightEmbedding *bool `yaml:"left-to-right-embedding,omitempty" toml:"left-to-right-embedding,multiline,omitempty"`
RightToLeftEmbedding *bool `yaml:"right-to-left-embedding,omitempty" toml:"right-to-left-embedding,multiline,omitempty"`
PopDirectionalFormatting *bool `yaml:"pop-directional-formatting,omitempty" toml:"pop-directional-formatting,multiline,omitempty"`
LeftToRightOverride *bool `yaml:"left-to-right-override,omitempty" toml:"left-to-right-override,multiline,omitempty"`
RightToLeftOverride *bool `yaml:"right-to-left-override,omitempty" toml:"right-to-left-override,multiline,omitempty"`
LeftToRightIsolate *bool `yaml:"left-to-right-isolate,omitempty" toml:"left-to-right-isolate,multiline,omitempty"`
RightToLeftIsolate *bool `yaml:"right-to-left-isolate,omitempty" toml:"right-to-left-isolate,multiline,omitempty"`
FirstStrongIsolate *bool `yaml:"first-strong-isolate,omitempty" toml:"first-strong-isolate,multiline,omitempty"`
PopDirectionalIsolate *bool `yaml:"pop-directional-isolate,omitempty" toml:"pop-directional-isolate,multiline,omitempty"`
}
type CopyLoopVarSettings struct {
CheckAlias *bool `yaml:"check-alias,omitempty" toml:"check-alias,multiline,omitempty"`
}
type CyclopSettings struct {
MaxComplexity *int `yaml:"max-complexity,omitempty" toml:"max-complexity,multiline,omitempty"`
PackageAverage *float64 `yaml:"package-average,omitempty" toml:"package-average,multiline,omitempty"`
}
type DepGuardSettings struct {
Rules map[string]*DepGuardList `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
}
type DepGuardList struct {
ListMode *string `yaml:"list-mode,omitempty" toml:"list-mode,multiline,omitempty"`
Files []string `yaml:"files,omitempty" toml:"files,multiline,omitempty"`
Allow []string `yaml:"allow,omitempty" toml:"allow,multiline,omitempty"`
Deny []DepGuardDeny `yaml:"deny,omitempty" toml:"deny,multiline,omitempty"`
}
type DepGuardDeny struct {
Pkg *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"`
Desc *string `yaml:"desc,omitempty" toml:"desc,multiline,omitempty"`
}
type DecorderSettings struct {
DecOrder []string `yaml:"dec-order,omitempty" toml:"dec-order,multiline,omitempty"`
IgnoreUnderscoreVars *bool `yaml:"ignore-underscore-vars,omitempty" toml:"ignore-underscore-vars,multiline,omitempty"`
DisableDecNumCheck *bool `yaml:"disable-dec-num-check,omitempty" toml:"disable-dec-num-check,multiline,omitempty"`
DisableTypeDecNumCheck *bool `yaml:"disable-type-dec-num-check,omitempty" toml:"disable-type-dec-num-check,multiline,omitempty"`
DisableConstDecNumCheck *bool `yaml:"disable-const-dec-num-check,omitempty" toml:"disable-const-dec-num-check,multiline,omitempty"`
DisableVarDecNumCheck *bool `yaml:"disable-var-dec-num-check,omitempty" toml:"disable-var-dec-num-check,multiline,omitempty"`
DisableDecOrderCheck *bool `yaml:"disable-dec-order-check,omitempty" toml:"disable-dec-order-check,multiline,omitempty"`
DisableInitFuncFirstCheck *bool `yaml:"disable-init-func-first-check,omitempty" toml:"disable-init-func-first-check,multiline,omitempty"`
}
type DogsledSettings struct {
MaxBlankIdentifiers *int `yaml:"max-blank-identifiers,omitempty" toml:"max-blank-identifiers,multiline,omitempty"`
}
type DuplSettings struct {
Threshold *int `yaml:"threshold,omitempty" toml:"threshold,multiline,omitempty"`
}
type DupWordSettings struct {
Keywords []string `yaml:"keywords,omitempty" toml:"keywords,multiline,omitempty"`
Ignore []string `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"`
}
type EmbeddedStructFieldCheckSettings struct {
ForbidMutex *bool `yaml:"forbid-mutex,omitempty" toml:"forbid-mutex,multiline,omitempty"`
}
type ErrcheckSettings struct {
DisableDefaultExclusions *bool `yaml:"disable-default-exclusions,omitempty" toml:"disable-default-exclusions,multiline,omitempty"`
CheckTypeAssertions *bool `yaml:"check-type-assertions,omitempty" toml:"check-type-assertions,multiline,omitempty"`
CheckAssignToBlank *bool `yaml:"check-blank,omitempty" toml:"check-blank,multiline,omitempty"`
ExcludeFunctions []string `yaml:"exclude-functions,omitempty" toml:"exclude-functions,multiline,omitempty"`
Verbose *bool `yaml:"verbose,omitempty" toml:"verbose,multiline,omitempty"`
}
type ErrChkJSONSettings struct {
CheckErrorFreeEncoding *bool `yaml:"check-error-free-encoding,omitempty" toml:"check-error-free-encoding,multiline,omitempty"`
ReportNoExported *bool `yaml:"report-no-exported,omitempty" toml:"report-no-exported,multiline,omitempty"`
}
type ErrorLintSettings struct {
Errorf *bool `yaml:"errorf,omitempty" toml:"errorf,multiline,omitempty"`
ErrorfMulti *bool `yaml:"errorf-multi,omitempty" toml:"errorf-multi,multiline,omitempty"`
Asserts *bool `yaml:"asserts,omitempty" toml:"asserts,multiline,omitempty"`
Comparison *bool `yaml:"comparison,omitempty" toml:"comparison,multiline,omitempty"`
AllowedErrors []ErrorLintAllowPair `yaml:"allowed-errors,omitempty" toml:"allowed-errors,multiline,omitempty"`
AllowedErrorsWildcard []ErrorLintAllowPair `yaml:"allowed-errors-wildcard,omitempty" toml:"allowed-errors-wildcard,multiline,omitempty"`
}
type ErrorLintAllowPair struct {
Err *string `yaml:"err,omitempty" toml:"err,multiline,omitempty"`
Fun *string `yaml:"fun,omitempty" toml:"fun,multiline,omitempty"`
}
type ExhaustiveSettings struct {
Check []string `yaml:"check,omitempty" toml:"check,multiline,omitempty"`
DefaultSignifiesExhaustive *bool `yaml:"default-signifies-exhaustive,omitempty" toml:"default-signifies-exhaustive,multiline,omitempty"`
IgnoreEnumMembers *string `yaml:"ignore-enum-members,omitempty" toml:"ignore-enum-members,multiline,omitempty"`
IgnoreEnumTypes *string `yaml:"ignore-enum-types,omitempty" toml:"ignore-enum-types,multiline,omitempty"`
PackageScopeOnly *bool `yaml:"package-scope-only,omitempty" toml:"package-scope-only,multiline,omitempty"`
ExplicitExhaustiveMap *bool `yaml:"explicit-exhaustive-map,omitempty" toml:"explicit-exhaustive-map,multiline,omitempty"`
ExplicitExhaustiveSwitch *bool `yaml:"explicit-exhaustive-switch,omitempty" toml:"explicit-exhaustive-switch,multiline,omitempty"`
DefaultCaseRequired *bool `yaml:"default-case-required,omitempty" toml:"default-case-required,multiline,omitempty"`
}
type ExhaustructSettings struct {
Include []string `yaml:"include,omitempty" toml:"include,multiline,omitempty"`
Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"`
}
type FatcontextSettings struct {
CheckStructPointers *bool `yaml:"check-struct-pointers,omitempty" toml:"check-struct-pointers,multiline,omitempty"`
}
type ForbidigoSettings struct {
Forbid []ForbidigoPattern `yaml:"forbid,omitempty" toml:"forbid,multiline,omitempty"`
ExcludeGodocExamples *bool `yaml:"exclude-godoc-examples,omitempty" toml:"exclude-godoc-examples,multiline,omitempty"`
AnalyzeTypes *bool `yaml:"analyze-types,omitempty" toml:"analyze-types,multiline,omitempty"`
}
type ForbidigoPattern struct {
Pattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"`
Package *string `yaml:"pkg,omitempty,omitempty" toml:"pkg,omitempty,multiline,omitempty"`
Msg *string `yaml:"msg,omitempty,omitempty" toml:"msg,omitempty,multiline,omitempty"`
}
type FuncOrderSettings struct {
Constructor *bool `yaml:"constructor,omitempty,omitempty" toml:"constructor,omitempty,multiline,omitempty"`
StructMethod *bool `yaml:"struct-method,omitempty,omitempty" toml:"struct-method,omitempty,multiline,omitempty"`
Alphabetical *bool `yaml:"alphabetical,omitempty,omitempty" toml:"alphabetical,omitempty,multiline,omitempty"`
}
type FunlenSettings struct {
Lines *int `yaml:"lines,omitempty" toml:"lines,multiline,omitempty"`
Statements *int `yaml:"statements,omitempty" toml:"statements,multiline,omitempty"`
IgnoreComments *bool `yaml:"ignore-comments,omitempty" toml:"ignore-comments,multiline,omitempty"`
}
type GinkgoLinterSettings struct {
SuppressLenAssertion *bool `yaml:"suppress-len-assertion,omitempty" toml:"suppress-len-assertion,multiline,omitempty"`
SuppressNilAssertion *bool `yaml:"suppress-nil-assertion,omitempty" toml:"suppress-nil-assertion,multiline,omitempty"`
SuppressErrAssertion *bool `yaml:"suppress-err-assertion,omitempty" toml:"suppress-err-assertion,multiline,omitempty"`
SuppressCompareAssertion *bool `yaml:"suppress-compare-assertion,omitempty" toml:"suppress-compare-assertion,multiline,omitempty"`
SuppressAsyncAssertion *bool `yaml:"suppress-async-assertion,omitempty" toml:"suppress-async-assertion,multiline,omitempty"`
SuppressTypeCompareWarning *bool `yaml:"suppress-type-compare-assertion,omitempty" toml:"suppress-type-compare-assertion,multiline,omitempty"`
ForbidFocusContainer *bool `yaml:"forbid-focus-container,omitempty" toml:"forbid-focus-container,multiline,omitempty"`
AllowHaveLenZero *bool `yaml:"allow-havelen-zero,omitempty" toml:"allow-havelen-zero,multiline,omitempty"`
ForceExpectTo *bool `yaml:"force-expect-to,omitempty" toml:"force-expect-to,multiline,omitempty"`
ValidateAsyncIntervals *bool `yaml:"validate-async-intervals,omitempty" toml:"validate-async-intervals,multiline,omitempty"`
ForbidSpecPollution *bool `yaml:"forbid-spec-pollution,omitempty" toml:"forbid-spec-pollution,multiline,omitempty"`
ForceSucceedForFuncs *bool `yaml:"force-succeed,omitempty" toml:"force-succeed,multiline,omitempty"`
}
type GoChecksumTypeSettings struct {
DefaultSignifiesExhaustive *bool `yaml:"default-signifies-exhaustive,omitempty" toml:"default-signifies-exhaustive,multiline,omitempty"`
IncludeSharedInterfaces *bool `yaml:"include-shared-interfaces,omitempty" toml:"include-shared-interfaces,multiline,omitempty"`
}
type GocognitSettings struct {
MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"`
}
type GoConstSettings struct {
IgnoreStringValues []string `yaml:"ignore-string-values,omitempty" toml:"ignore-string-values,multiline,omitempty"`
MatchWithConstants *bool `yaml:"match-constant,omitempty" toml:"match-constant,multiline,omitempty"`
MinStringLen *int `yaml:"min-len,omitempty" toml:"min-len,multiline,omitempty"`
MinOccurrencesCount *int `yaml:"min-occurrences,omitempty" toml:"min-occurrences,multiline,omitempty"`
ParseNumbers *bool `yaml:"numbers,omitempty" toml:"numbers,multiline,omitempty"`
NumberMin *int `yaml:"min,omitempty" toml:"min,multiline,omitempty"`
NumberMax *int `yaml:"max,omitempty" toml:"max,multiline,omitempty"`
IgnoreCalls *bool `yaml:"ignore-calls,omitempty" toml:"ignore-calls,multiline,omitempty"`
FindDuplicates *bool `yaml:"find-duplicates,omitempty" toml:"find-duplicates,multiline,omitempty"`
EvalConstExpressions *bool `yaml:"eval-const-expressions,omitempty" toml:"eval-const-expressions,multiline,omitempty"`
IgnoreStrings *string `yaml:"ignore-strings,omitempty" toml:"ignore-strings,multiline,omitempty"`
}
type GoCriticSettings struct {
Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"`
EnabledChecks []string `yaml:"enabled-checks,omitempty" toml:"enabled-checks,multiline,omitempty"`
EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"`
DisabledChecks []string `yaml:"disabled-checks,omitempty" toml:"disabled-checks,multiline,omitempty"`
EnabledTags []string `yaml:"enabled-tags,omitempty" toml:"enabled-tags,multiline,omitempty"`
DisabledTags []string `yaml:"disabled-tags,omitempty" toml:"disabled-tags,multiline,omitempty"`
SettingsPerCheck map[string]GoCriticCheckSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
}
type GoCriticCheckSettings map[string]any
type GoCycloSettings struct {
MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"`
}
type GodotSettings struct {
Scope *string `yaml:"scope,omitempty" toml:"scope,multiline,omitempty"`
Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"`
Capital *bool `yaml:"capital,omitempty" toml:"capital,multiline,omitempty"`
Period *bool `yaml:"period,omitempty" toml:"period,multiline,omitempty"`
}
type GodoxSettings struct {
Keywords []string `yaml:"keywords,omitempty" toml:"keywords,multiline,omitempty"`
}
type GoHeaderSettings struct {
Values map[string]map[string]string `yaml:"values,omitempty" toml:"values,multiline,omitempty"`
Template *string `yaml:"template,omitempty" toml:"template,multiline,omitempty"`
TemplatePath *string `yaml:"template-path,omitempty" toml:"template-path,multiline,omitempty"`
}
type GoModDirectivesSettings struct {
ReplaceAllowList []string `yaml:"replace-allow-list,omitempty" toml:"replace-allow-list,multiline,omitempty"`
ReplaceLocal *bool `yaml:"replace-local,omitempty" toml:"replace-local,multiline,omitempty"`
ExcludeForbidden *bool `yaml:"exclude-forbidden,omitempty" toml:"exclude-forbidden,multiline,omitempty"`
RetractAllowNoExplanation *bool `yaml:"retract-allow-no-explanation,omitempty" toml:"retract-allow-no-explanation,multiline,omitempty"`
ToolchainForbidden *bool `yaml:"toolchain-forbidden,omitempty" toml:"toolchain-forbidden,multiline,omitempty"`
ToolchainPattern *string `yaml:"toolchain-pattern,omitempty" toml:"toolchain-pattern,multiline,omitempty"`
ToolForbidden *bool `yaml:"tool-forbidden,omitempty" toml:"tool-forbidden,multiline,omitempty"`
GoDebugForbidden *bool `yaml:"go-debug-forbidden,omitempty" toml:"go-debug-forbidden,multiline,omitempty"`
GoVersionPattern *string `yaml:"go-version-pattern,omitempty" toml:"go-version-pattern,multiline,omitempty"`
}
type GoModGuardSettings struct {
Allowed GoModGuardAllowed `yaml:"allowed,omitempty" toml:"allowed,multiline,omitempty"`
Blocked GoModGuardBlocked `yaml:"blocked,omitempty" toml:"blocked,multiline,omitempty"`
}
type GoModGuardAllowed struct {
Modules []string `yaml:"modules,omitempty" toml:"modules,multiline,omitempty"`
Domains []string `yaml:"domains,omitempty" toml:"domains,multiline,omitempty"`
}
type GoModGuardBlocked struct {
Modules []map[string]GoModGuardModule `yaml:"modules,omitempty" toml:"modules,multiline,omitempty"`
Versions []map[string]GoModGuardVersion `yaml:"versions,omitempty" toml:"versions,multiline,omitempty"`
LocalReplaceDirectives *bool `yaml:"local-replace-directives,omitempty" toml:"local-replace-directives,multiline,omitempty"`
}
type GoModGuardModule struct {
Recommendations []string `yaml:"recommendations,omitempty" toml:"recommendations,multiline,omitempty"`
Reason *string `yaml:"reason,omitempty" toml:"reason,multiline,omitempty"`
}
type GoModGuardVersion struct {
Version *string `yaml:"version,omitempty" toml:"version,multiline,omitempty"`
Reason *string `yaml:"reason,omitempty" toml:"reason,multiline,omitempty"`
}
type GoSecSettings struct {
Includes []string `yaml:"includes,omitempty" toml:"includes,multiline,omitempty"`
Excludes []string `yaml:"excludes,omitempty" toml:"excludes,multiline,omitempty"`
Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
Confidence *string `yaml:"confidence,omitempty" toml:"confidence,multiline,omitempty"`
Config map[string]any `yaml:"config,omitempty" toml:"config,multiline,omitempty"`
Concurrency *int `yaml:"concurrency,omitempty" toml:"concurrency,multiline,omitempty"`
}
type GosmopolitanSettings struct {
AllowTimeLocal *bool `yaml:"allow-time-local,omitempty" toml:"allow-time-local,multiline,omitempty"`
EscapeHatches []string `yaml:"escape-hatches,omitempty" toml:"escape-hatches,multiline,omitempty"`
WatchForScripts []string `yaml:"watch-for-scripts,omitempty" toml:"watch-for-scripts,multiline,omitempty"`
}
type GovetSettings struct {
Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"`
EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"`
DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"`
Settings map[string]map[string]any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
}
type GrouperSettings struct {
ConstRequireSingleConst *bool `yaml:"const-require-single-const,omitempty" toml:"const-require-single-const,multiline,omitempty"`
ConstRequireGrouping *bool `yaml:"const-require-grouping,omitempty" toml:"const-require-grouping,multiline,omitempty"`
ImportRequireSingleImport *bool `yaml:"import-require-single-import,omitempty" toml:"import-require-single-import,multiline,omitempty"`
ImportRequireGrouping *bool `yaml:"import-require-grouping,omitempty" toml:"import-require-grouping,multiline,omitempty"`
TypeRequireSingleType *bool `yaml:"type-require-single-type,omitempty" toml:"type-require-single-type,multiline,omitempty"`
TypeRequireGrouping *bool `yaml:"type-require-grouping,omitempty" toml:"type-require-grouping,multiline,omitempty"`
VarRequireSingleVar *bool `yaml:"var-require-single-var,omitempty" toml:"var-require-single-var,multiline,omitempty"`
VarRequireGrouping *bool `yaml:"var-require-grouping,omitempty" toml:"var-require-grouping,multiline,omitempty"`
}
type IfaceSettings struct {
Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
Settings map[string]map[string]any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
}
type ImportAsSettings struct {
Alias []ImportAsAlias `yaml:"alias,omitempty" toml:"alias,multiline,omitempty"`
NoUnaliased *bool `yaml:"no-unaliased,omitempty" toml:"no-unaliased,multiline,omitempty"`
NoExtraAliases *bool `yaml:"no-extra-aliases,omitempty" toml:"no-extra-aliases,multiline,omitempty"`
}
type ImportAsAlias struct {
Pkg *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"`
Alias *string `yaml:"alias,omitempty" toml:"alias,multiline,omitempty"`
}
type INamedParamSettings struct {
SkipSingleParam *bool `yaml:"skip-single-param,omitempty" toml:"skip-single-param,multiline,omitempty"`
}
type InterfaceBloatSettings struct {
Max *int `yaml:"max,omitempty" toml:"max,multiline,omitempty"`
}
type IreturnSettings struct {
Allow []string `yaml:"allow,omitempty" toml:"allow,multiline,omitempty"`
Reject []string `yaml:"reject,omitempty" toml:"reject,multiline,omitempty"`
}
type LllSettings struct {
LineLength *int `yaml:"line-length,omitempty" toml:"line-length,multiline,omitempty"`
TabWidth *int `yaml:"tab-width,omitempty" toml:"tab-width,multiline,omitempty"`
}
type LoggerCheckSettings struct {
Kitlog *bool `yaml:"kitlog,omitempty" toml:"kitlog,multiline,omitempty"`
Klog *bool `yaml:"klog,omitempty" toml:"klog,multiline,omitempty"`
Logr *bool `yaml:"logr,omitempty" toml:"logr,multiline,omitempty"`
Slog *bool `yaml:"slog,omitempty" toml:"slog,multiline,omitempty"`
Zap *bool `yaml:"zap,omitempty" toml:"zap,multiline,omitempty"`
RequireStringKey *bool `yaml:"require-string-key,omitempty" toml:"require-string-key,multiline,omitempty"`
NoPrintfLike *bool `yaml:"no-printf-like,omitempty" toml:"no-printf-like,multiline,omitempty"`
Rules []string `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
}
type MaintIdxSettings struct {
Under *int `yaml:"under,omitempty" toml:"under,multiline,omitempty"`
}
type MakezeroSettings struct {
Always *bool `yaml:"always,omitempty" toml:"always,multiline,omitempty"`
}
type MisspellSettings struct {
Mode *string `yaml:"mode,omitempty" toml:"mode,multiline,omitempty"`
Locale *string `yaml:"locale,omitempty" toml:"locale,multiline,omitempty"`
ExtraWords []MisspellExtraWords `yaml:"extra-words,omitempty" toml:"extra-words,multiline,omitempty"`
IgnoreRules []string `yaml:"ignore-rules,omitempty" toml:"ignore-rules,multiline,omitempty"`
}
type MisspellExtraWords struct {
Typo *string `yaml:"typo,omitempty" toml:"typo,multiline,omitempty"`
Correction *string `yaml:"correction,omitempty" toml:"correction,multiline,omitempty"`
}
type MustTagSettings struct {
Functions []MustTagFunction `yaml:"functions,omitempty" toml:"functions,multiline,omitempty"`
}
type MustTagFunction struct {
Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"`
Tag *string `yaml:"tag,omitempty" toml:"tag,multiline,omitempty"`
ArgPos *int `yaml:"arg-pos,omitempty" toml:"arg-pos,multiline,omitempty"`
}
type NakedretSettings struct {
MaxFuncLines *uint `yaml:"max-func-lines,omitempty" toml:"max-func-lines,multiline,omitempty"`
}
type NestifSettings struct {
MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"`
}
type NilNilSettings struct {
OnlyTwo *bool `yaml:"only-two,omitempty" toml:"only-two,multiline,omitempty"`
DetectOpposite *bool `yaml:"detect-opposite,omitempty" toml:"detect-opposite,multiline,omitempty"`
CheckedTypes []string `yaml:"checked-types,omitempty" toml:"checked-types,multiline,omitempty"`
}
type NlreturnSettings struct {
BlockSize *int `yaml:"block-size,omitempty" toml:"block-size,multiline,omitempty"`
}
type MndSettings struct {
Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"`
IgnoredNumbers []string `yaml:"ignored-numbers,omitempty" toml:"ignored-numbers,multiline,omitempty"`
IgnoredFiles []string `yaml:"ignored-files,omitempty" toml:"ignored-files,multiline,omitempty"`
IgnoredFunctions []string `yaml:"ignored-functions,omitempty" toml:"ignored-functions,multiline,omitempty"`
}
type NoLintLintSettings struct {
RequireExplanation *bool `yaml:"require-explanation,omitempty" toml:"require-explanation,multiline,omitempty"`
RequireSpecific *bool `yaml:"require-specific,omitempty" toml:"require-specific,multiline,omitempty"`
AllowNoExplanation []string `yaml:"allow-no-explanation,omitempty" toml:"allow-no-explanation,multiline,omitempty"`
AllowUnused *bool `yaml:"allow-unused,omitempty" toml:"allow-unused,multiline,omitempty"`
}
type NoNamedReturnsSettings struct {
ReportErrorInDefer *bool `yaml:"report-error-in-defer,omitempty" toml:"report-error-in-defer,multiline,omitempty"`
}
type ParallelTestSettings struct {
Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
IgnoreMissing *bool `yaml:"ignore-missing,omitempty" toml:"ignore-missing,multiline,omitempty"`
IgnoreMissingSubtests *bool `yaml:"ignore-missing-subtests,omitempty" toml:"ignore-missing-subtests,multiline,omitempty"`
}
type PerfSprintSettings struct {
IntegerFormat *bool `yaml:"integer-format,omitempty" toml:"integer-format,multiline,omitempty"`
IntConversion *bool `yaml:"int-conversion,omitempty" toml:"int-conversion,multiline,omitempty"`
ErrorFormat *bool `yaml:"error-format,omitempty" toml:"error-format,multiline,omitempty"`
ErrError *bool `yaml:"err-error,omitempty" toml:"err-error,multiline,omitempty"`
ErrorF *bool `yaml:"errorf,omitempty" toml:"errorf,multiline,omitempty"`
StringFormat *bool `yaml:"string-format,omitempty" toml:"string-format,multiline,omitempty"`
SprintF1 *bool `yaml:"sprintf1,omitempty" toml:"sprintf1,multiline,omitempty"`
StrConcat *bool `yaml:"strconcat,omitempty" toml:"strconcat,multiline,omitempty"`
BoolFormat *bool `yaml:"bool-format,omitempty" toml:"bool-format,multiline,omitempty"`
HexFormat *bool `yaml:"hex-format,omitempty" toml:"hex-format,multiline,omitempty"`
}
type PreallocSettings struct {
Simple *bool `yaml:"simple,omitempty" toml:"simple,multiline,omitempty"`
RangeLoops *bool `yaml:"range-loops,omitempty" toml:"range-loops,multiline,omitempty"`
ForLoops *bool `yaml:"for-loops,omitempty" toml:"for-loops,multiline,omitempty"`
}
type PredeclaredSettings struct {
Ignore []string `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"`
Qualified *bool `yaml:"qualified-name,omitempty" toml:"qualified-name,multiline,omitempty"`
}
type PromlinterSettings struct {
Strict *bool `yaml:"strict,omitempty" toml:"strict,multiline,omitempty"`
DisabledLinters []string `yaml:"disabled-linters,omitempty" toml:"disabled-linters,multiline,omitempty"`
}
type ProtoGetterSettings struct {
SkipGeneratedBy []string `yaml:"skip-generated-by,omitempty" toml:"skip-generated-by,multiline,omitempty"`
SkipFiles []string `yaml:"skip-files,omitempty" toml:"skip-files,multiline,omitempty"`
SkipAnyGenerated *bool `yaml:"skip-any-generated,omitempty" toml:"skip-any-generated,multiline,omitempty"`
ReplaceFirstArgInAppend *bool `yaml:"replace-first-arg-in-append,omitempty" toml:"replace-first-arg-in-append,multiline,omitempty"`
}
type ReassignSettings struct {
Patterns []string `yaml:"patterns,omitempty" toml:"patterns,multiline,omitempty"`
}
type RecvcheckSettings struct {
DisableBuiltin *bool `yaml:"disable-builtin,omitempty" toml:"disable-builtin,multiline,omitempty"`
Exclusions []string `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"`
}
type ReviveSettings struct {
Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
MaxOpenFiles *int `yaml:"max-open-files,omitempty" toml:"max-open-files,multiline,omitempty"`
Confidence *float64 `yaml:"confidence,omitempty" toml:"confidence,multiline,omitempty"`
Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
EnableAllRules *bool `yaml:"enable-all-rules,omitempty" toml:"enable-all-rules,multiline,omitempty"`
Rules []ReviveRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
ErrorCode *int `yaml:"error-code,omitempty" toml:"error-code,multiline,omitempty"`
WarningCode *int `yaml:"warning-code,omitempty" toml:"warning-code,multiline,omitempty"`
Directives []ReviveDirective `yaml:"directives,omitempty" toml:"directives,multiline,omitempty"`
}
type ReviveRule struct {
Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"`
Arguments []any `yaml:"arguments,omitempty" toml:"arguments,multiline,omitempty"`
Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
Disabled *bool `yaml:"disabled,omitempty" toml:"disabled,multiline,omitempty"`
Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"`
}
type ReviveDirective struct {
Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"`
Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
}
type RowsErrCheckSettings struct {
Packages []string `yaml:"packages,omitempty" toml:"packages,multiline,omitempty"`
}
type SlogLintSettings struct {
NoMixedArgs *bool `yaml:"no-mixed-args,omitempty" toml:"no-mixed-args,multiline,omitempty"`
KVOnly *bool `yaml:"kv-only,omitempty" toml:"kv-only,multiline,omitempty"`
AttrOnly *bool `yaml:"attr-only,omitempty" toml:"attr-only,multiline,omitempty"`
NoGlobal *string `yaml:"no-global,omitempty" toml:"no-global,multiline,omitempty"`
Context *string `yaml:"context,omitempty" toml:"context,multiline,omitempty"`
StaticMsg *bool `yaml:"static-msg,omitempty" toml:"static-msg,multiline,omitempty"`
MsgStyle *string `yaml:"msg-style,omitempty" toml:"msg-style,multiline,omitempty"`
NoRawKeys *bool `yaml:"no-raw-keys,omitempty" toml:"no-raw-keys,multiline,omitempty"`
KeyNamingCase *string `yaml:"key-naming-case,omitempty" toml:"key-naming-case,multiline,omitempty"`
ForbiddenKeys []string `yaml:"forbidden-keys,omitempty" toml:"forbidden-keys,multiline,omitempty"`
ArgsOnSepLines *bool `yaml:"args-on-sep-lines,omitempty" toml:"args-on-sep-lines,multiline,omitempty"`
}
type SpancheckSettings struct {
Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"`
IgnoreCheckSignatures []string `yaml:"ignore-check-signatures,omitempty" toml:"ignore-check-signatures,multiline,omitempty"`
ExtraStartSpanSignatures []string `yaml:"extra-start-span-signatures,omitempty" toml:"extra-start-span-signatures,multiline,omitempty"`
}
type StaticCheckSettings struct {
Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"`
Initialisms []string `yaml:"initialisms,omitempty" toml:"initialisms,multiline,omitempty"`
DotImportWhitelist []string `yaml:"dot-import-whitelist,omitempty" toml:"dot-import-whitelist,multiline,omitempty"`
HTTPStatusCodeWhitelist []string `yaml:"http-status-code-whitelist,omitempty" toml:"http-status-code-whitelist,multiline,omitempty"`
}
type TagAlignSettings struct {
Align *bool `yaml:"align,omitempty" toml:"align,multiline,omitempty"`
Sort *bool `yaml:"sort,omitempty" toml:"sort,multiline,omitempty"`
Order []string `yaml:"order,omitempty" toml:"order,multiline,omitempty"`
Strict *bool `yaml:"strict,omitempty" toml:"strict,multiline,omitempty"`
}
type TagliatelleSettings struct {
Case TagliatelleCase `yaml:"case,omitempty" toml:"case,multiline,omitempty"`
}
type TagliatelleCase struct {
TagliatelleBase `yaml:",inline"`
Overrides []TagliatelleOverrides `yaml:"overrides,omitempty" toml:"overrides,multiline,omitempty"`
}
type TagliatelleOverrides struct {
TagliatelleBase `yaml:",inline"`
Package *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"`
Ignore *bool `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"`
}
type TagliatelleBase struct {
Rules map[string]string `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
ExtendedRules map[string]TagliatelleExtendedRule `yaml:"extended-rules,omitempty" toml:"extended-rules,multiline,omitempty"`
UseFieldName *bool `yaml:"use-field-name,omitempty" toml:"use-field-name,multiline,omitempty"`
IgnoredFields []string `yaml:"ignored-fields,omitempty" toml:"ignored-fields,multiline,omitempty"`
}
type TagliatelleExtendedRule struct {
Case *string `yaml:"case,omitempty" toml:"case,multiline,omitempty"`
ExtraInitialisms *bool `yaml:"extra-initialisms,omitempty" toml:"extra-initialisms,multiline,omitempty"`
InitialismOverrides map[string]bool `yaml:"initialism-overrides,omitempty" toml:"initialism-overrides,multiline,omitempty"`
}
type TestifylintSettings struct {
EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"`
DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"`
EnabledCheckers []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
DisabledCheckers []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"`
BoolCompare TestifylintBoolCompare `yaml:"bool-compare,omitempty" toml:"bool-compare,multiline,omitempty"`
ExpectedActual TestifylintExpectedActual `yaml:"expected-actual,omitempty" toml:"expected-actual,multiline,omitempty"`
Formatter TestifylintFormatter `yaml:"formatter,omitempty" toml:"formatter,multiline,omitempty"`
GoRequire TestifylintGoRequire `yaml:"go-require,omitempty" toml:"go-require,multiline,omitempty"`
RequireError TestifylintRequireError `yaml:"require-error,omitempty" toml:"require-error,multiline,omitempty"`
SuiteExtraAssertCall TestifylintSuiteExtraAssertCall `yaml:"suite-extra-assert-call,omitempty" toml:"suite-extra-assert-call,multiline,omitempty"`
}
type TestifylintBoolCompare struct {
IgnoreCustomTypes *bool `yaml:"ignore-custom-types,omitempty" toml:"ignore-custom-types,multiline,omitempty"`
}
type TestifylintExpectedActual struct {
ExpVarPattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"`
}
type TestifylintFormatter struct {
CheckFormatString *bool `yaml:"check-format-string,omitempty" toml:"check-format-string,multiline,omitempty"`
RequireFFuncs *bool `yaml:"require-f-funcs,omitempty" toml:"require-f-funcs,multiline,omitempty"`
RequireStringMsg *bool `yaml:"require-string-msg,omitempty" toml:"require-string-msg,multiline,omitempty"`
}
type TestifylintGoRequire struct {
IgnoreHTTPHandlers *bool `yaml:"ignore-http-handlers,omitempty" toml:"ignore-http-handlers,multiline,omitempty"`
}
type TestifylintRequireError struct {
FnPattern *string `yaml:"fn-pattern,omitempty" toml:"fn-pattern,multiline,omitempty"`
}
type TestifylintSuiteExtraAssertCall struct {
Mode *string `yaml:"mode,omitempty" toml:"mode,multiline,omitempty"`
}
type TestpackageSettings struct {
SkipRegexp *string `yaml:"skip-regexp,omitempty" toml:"skip-regexp,multiline,omitempty"`
AllowPackages []string `yaml:"allow-packages,omitempty" toml:"allow-packages,multiline,omitempty"`
}
type ThelperSettings struct {
Test ThelperOptions `yaml:"test,omitempty" toml:"test,multiline,omitempty"`
Fuzz ThelperOptions `yaml:"fuzz,omitempty" toml:"fuzz,multiline,omitempty"`
Benchmark ThelperOptions `yaml:"benchmark,omitempty" toml:"benchmark,multiline,omitempty"`
TB ThelperOptions `yaml:"tb,omitempty" toml:"tb,multiline,omitempty"`
}
type ThelperOptions struct {
First *bool `yaml:"first,omitempty" toml:"first,multiline,omitempty"`
Name *bool `yaml:"name,omitempty" toml:"name,multiline,omitempty"`
Begin *bool `yaml:"begin,omitempty" toml:"begin,multiline,omitempty"`
}
type UseStdlibVarsSettings struct {
HTTPMethod *bool `yaml:"http-method,omitempty" toml:"http-method,multiline,omitempty"`
HTTPStatusCode *bool `yaml:"http-status-code,omitempty" toml:"http-status-code,multiline,omitempty"`
TimeWeekday *bool `yaml:"time-weekday,omitempty" toml:"time-weekday,multiline,omitempty"`
TimeMonth *bool `yaml:"time-month,omitempty" toml:"time-month,multiline,omitempty"`
TimeLayout *bool `yaml:"time-layout,omitempty" toml:"time-layout,multiline,omitempty"`
CryptoHash *bool `yaml:"crypto-hash,omitempty" toml:"crypto-hash,multiline,omitempty"`
DefaultRPCPath *bool `yaml:"default-rpc-path,omitempty" toml:"default-rpc-path,multiline,omitempty"`
SQLIsolationLevel *bool `yaml:"sql-isolation-level,omitempty" toml:"sql-isolation-level,multiline,omitempty"`
TLSSignatureScheme *bool `yaml:"tls-signature-scheme,omitempty" toml:"tls-signature-scheme,multiline,omitempty"`
ConstantKind *bool `yaml:"constant-kind,omitempty" toml:"constant-kind,multiline,omitempty"`
TimeDateMonth *bool `yaml:"time-date-month,omitempty" toml:"time-date-month,multiline,omitempty"`
}
type UseTestingSettings struct {
ContextBackground *bool `yaml:"context-background,omitempty" toml:"context-background,multiline,omitempty"`
ContextTodo *bool `yaml:"context-todo,omitempty" toml:"context-todo,multiline,omitempty"`
OSChdir *bool `yaml:"os-chdir,omitempty" toml:"os-chdir,multiline,omitempty"`
OSMkdirTemp *bool `yaml:"os-mkdir-temp,omitempty" toml:"os-mkdir-temp,multiline,omitempty"`
OSSetenv *bool `yaml:"os-setenv,omitempty" toml:"os-setenv,multiline,omitempty"`
OSTempDir *bool `yaml:"os-temp-dir,omitempty" toml:"os-temp-dir,multiline,omitempty"`
OSCreateTemp *bool `yaml:"os-create-temp,omitempty" toml:"os-create-temp,multiline,omitempty"`
}
type UnconvertSettings struct {
FastMath *bool `yaml:"fast-math,omitempty" toml:"fast-math,multiline,omitempty"`
Safe *bool `yaml:"safe,omitempty" toml:"safe,multiline,omitempty"`
}
type UnparamSettings struct {
CheckExported *bool `yaml:"check-exported,omitempty" toml:"check-exported,multiline,omitempty"`
}
type UnusedSettings struct {
FieldWritesAreUses *bool `yaml:"field-writes-are-uses,omitempty" toml:"field-writes-are-uses,multiline,omitempty"`
PostStatementsAreReads *bool `yaml:"post-statements-are-reads,omitempty" toml:"post-statements-are-reads,multiline,omitempty"`
ExportedFieldsAreUsed *bool `yaml:"exported-fields-are-used,omitempty" toml:"exported-fields-are-used,multiline,omitempty"`
ParametersAreUsed *bool `yaml:"parameters-are-used,omitempty" toml:"parameters-are-used,multiline,omitempty"`
LocalVariablesAreUsed *bool `yaml:"local-variables-are-used,omitempty" toml:"local-variables-are-used,multiline,omitempty"`
GeneratedIsUsed *bool `yaml:"generated-is-used,omitempty" toml:"generated-is-used,multiline,omitempty"`
}
type VarnamelenSettings struct {
MaxDistance *int `yaml:"max-distance,omitempty" toml:"max-distance,multiline,omitempty"`
MinNameLength *int `yaml:"min-name-length,omitempty" toml:"min-name-length,multiline,omitempty"`
CheckReceiver *bool `yaml:"check-receiver,omitempty" toml:"check-receiver,multiline,omitempty"`
CheckReturn *bool `yaml:"check-return,omitempty" toml:"check-return,multiline,omitempty"`
CheckTypeParam *bool `yaml:"check-type-param,omitempty" toml:"check-type-param,multiline,omitempty"`
IgnoreNames []string `yaml:"ignore-names,omitempty" toml:"ignore-names,multiline,omitempty"`
IgnoreTypeAssertOk *bool `yaml:"ignore-type-assert-ok,omitempty" toml:"ignore-type-assert-ok,multiline,omitempty"`
IgnoreMapIndexOk *bool `yaml:"ignore-map-index-ok,omitempty" toml:"ignore-map-index-ok,multiline,omitempty"`
IgnoreChanRecvOk *bool `yaml:"ignore-chan-recv-ok,omitempty" toml:"ignore-chan-recv-ok,multiline,omitempty"`
IgnoreDecls []string `yaml:"ignore-decls,omitempty" toml:"ignore-decls,multiline,omitempty"`
}
type WhitespaceSettings struct {
MultiIf *bool `yaml:"multi-if,omitempty" toml:"multi-if,multiline,omitempty"`
MultiFunc *bool `yaml:"multi-func,omitempty" toml:"multi-func,multiline,omitempty"`
}
type WrapcheckSettings struct {
ExtraIgnoreSigs []string `yaml:"extra-ignore-sigs,omitempty" toml:"extra-ignore-sigs,multiline,omitempty"`
IgnoreSigs []string `yaml:"ignore-sigs,omitempty" toml:"ignore-sigs,multiline,omitempty"`
IgnoreSigRegexps []string `yaml:"ignore-sig-regexps,omitempty" toml:"ignore-sig-regexps,multiline,omitempty"`
IgnorePackageGlobs []string `yaml:"ignore-package-globs,omitempty" toml:"ignore-package-globs,multiline,omitempty"`
IgnoreInterfaceRegexps []string `yaml:"ignore-interface-regexps,omitempty" toml:"ignore-interface-regexps,multiline,omitempty"`
ReportInternalErrors *bool `yaml:"report-internal-errors,omitempty" toml:"report-internal-errors,multiline,omitempty"`
}
type WSLv4Settings struct {
StrictAppend *bool `yaml:"strict-append,omitempty" toml:"strict-append,multiline,omitempty"`
AllowAssignAndCallCuddle *bool `yaml:"allow-assign-and-call,omitempty" toml:"allow-assign-and-call,multiline,omitempty"`
AllowAssignAndAnythingCuddle *bool `yaml:"allow-assign-and-anything,omitempty" toml:"allow-assign-and-anything,multiline,omitempty"`
AllowMultiLineAssignCuddle *bool `yaml:"allow-multiline-assign,omitempty" toml:"allow-multiline-assign,multiline,omitempty"`
ForceCaseTrailingWhitespaceLimit *int `yaml:"force-case-trailing-whitespace,omitempty" toml:"force-case-trailing-whitespace,multiline,omitempty"`
AllowTrailingComment *bool `yaml:"allow-trailing-comment,omitempty" toml:"allow-trailing-comment,multiline,omitempty"`
AllowSeparatedLeadingComment *bool `yaml:"allow-separated-leading-comment,omitempty" toml:"allow-separated-leading-comment,multiline,omitempty"`
AllowCuddleDeclaration *bool `yaml:"allow-cuddle-declarations,omitempty" toml:"allow-cuddle-declarations,multiline,omitempty"`
AllowCuddleWithCalls []string `yaml:"allow-cuddle-with-calls,omitempty" toml:"allow-cuddle-with-calls,multiline,omitempty"`
AllowCuddleWithRHS []string `yaml:"allow-cuddle-with-rhs,omitempty" toml:"allow-cuddle-with-rhs,multiline,omitempty"`
AllowCuddleUsedInBlock *bool `yaml:"allow-cuddle-used-in-block,omitempty" toml:"allow-cuddle-used-in-block,multiline,omitempty"`
ForceCuddleErrCheckAndAssign *bool `yaml:"force-err-cuddling,omitempty" toml:"force-err-cuddling,multiline,omitempty"`
ErrorVariableNames []string `yaml:"error-variable-names,omitempty" toml:"error-variable-names,multiline,omitempty"`
ForceExclusiveShortDeclarations *bool `yaml:"force-short-decl-cuddling,omitempty" toml:"force-short-decl-cuddling,multiline,omitempty"`
}
type WSLv5Settings struct {
AllowFirstInBlock *bool `yaml:"allow-first-in-block,omitempty" toml:"allow-first-in-block,multiline,omitempty"`
AllowWholeBlock *bool `yaml:"allow-whole-block,omitempty" toml:"allow-whole-block,multiline,omitempty"`
BranchMaxLines *int `yaml:"branch-max-lines,omitempty" toml:"branch-max-lines,multiline,omitempty"`
CaseMaxLines *int `yaml:"case-max-lines,omitempty" toml:"case-max-lines,multiline,omitempty"`
Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"`
Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"`
}
type CustomLinterSettings struct {
Type *string `yaml:"type,omitempty" toml:"type,multiline,omitempty"`
Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"`
Description *string `yaml:"description,omitempty" toml:"description,multiline,omitempty"`
OriginalURL *string `yaml:"original-url,omitempty" toml:"original-url,multiline,omitempty"`
Settings any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/output.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type Output struct {
Formats Formats `yaml:"formats,omitempty" toml:"formats,multiline,omitempty"`
SortOrder []string `yaml:"sort-order,omitempty" toml:"sort-order,multiline,omitempty"`
ShowStats *bool `yaml:"show-stats,omitempty" toml:"show-stats,multiline,omitempty"`
PathPrefix *string `yaml:"path-prefix,omitempty" toml:"path-prefix,multiline,omitempty"`
PathMode *string `yaml:"path-mode,omitempty" toml:"path-mode,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/output_formats.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type Formats struct {
Text Text `yaml:"text,omitempty" toml:"text,multiline,omitempty"`
JSON SimpleFormat `yaml:"json,omitempty" toml:"json,multiline,omitempty"`
Tab Tab `yaml:"tab,omitempty" toml:"tab,multiline,omitempty"`
HTML SimpleFormat `yaml:"html,omitempty" toml:"html,multiline,omitempty"`
Checkstyle SimpleFormat `yaml:"checkstyle,omitempty" toml:"checkstyle,multiline,omitempty"`
CodeClimate SimpleFormat `yaml:"code-climate,omitempty" toml:"code-climate,multiline,omitempty"`
JUnitXML JUnitXML `yaml:"junit-xml,omitempty" toml:"junit-xml,multiline,omitempty"`
TeamCity SimpleFormat `yaml:"teamcity,omitempty" toml:"teamcity,multiline,omitempty"`
Sarif SimpleFormat `yaml:"sarif,omitempty" toml:"sarif,multiline,omitempty"`
}
type SimpleFormat struct {
Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"`
}
type Text struct {
SimpleFormat `yaml:",inline"`
PrintLinterName *bool `yaml:"print-linter-name,omitempty" toml:"print-linter-name,multiline,omitempty"`
PrintIssuedLine *bool `yaml:"print-issued-lines,omitempty" toml:"print-issued-lines,multiline,omitempty"`
Colors *bool `yaml:"colors,omitempty" toml:"colors,multiline,omitempty"`
}
type Tab struct {
SimpleFormat `yaml:",inline"`
PrintLinterName *bool `yaml:"print-linter-name,omitempty" toml:"print-linter-name,multiline,omitempty"`
Colors *bool `yaml:"colors,omitempty" toml:"colors,multiline,omitempty"`
}
type JUnitXML struct {
SimpleFormat `yaml:",inline"`
Extended *bool `yaml:"extended,omitempty" toml:"extended,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/run.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
import (
"time"
)
type Run struct {
Timeout time.Duration `yaml:"timeout,omitempty" toml:"timeout,multiline,omitempty"`
Concurrency *int `yaml:"concurrency,omitempty" toml:"concurrency,multiline,omitempty"`
Go *string `yaml:"go,omitempty" toml:"go,multiline,omitempty"`
RelativePathMode *string `yaml:"relative-path-mode,omitempty" toml:"relative-path-mode,multiline,omitempty"`
BuildTags []string `yaml:"build-tags,omitempty" toml:"build-tags,multiline,omitempty"`
ModulesDownloadMode *string `yaml:"modules-download-mode,omitempty" toml:"modules-download-mode,multiline,omitempty"`
ExitCodeIfIssuesFound *int `yaml:"issues-exit-code,omitempty" toml:"issues-exit-code,multiline,omitempty"`
AnalyzeTests *bool `yaml:"tests,omitempty" toml:"tests,multiline,omitempty"`
AllowParallelRunners *bool `yaml:"allow-parallel-runners,omitempty" toml:"allow-parallel-runners,multiline,omitempty"`
AllowSerialRunners *bool `yaml:"allow-serial-runners,omitempty" toml:"allow-serial-runners,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/migrate/versiontwo/severity.go
================================================
// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
package versiontwo
type Severity struct {
Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"`
Rules []SeverityRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
}
type SeverityRule struct {
BaseRule `yaml:",inline"`
Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
}
================================================
FILE: pkg/commands/internal/testdata/imports.go
================================================
package main
import (
_ "example.com/foo/bar/test"
_ "example.org/foo/bar/test"
)
================================================
FILE: pkg/commands/internal/vibra.go
================================================
package internal
import (
"fmt"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
type FlagFunc[T any] func(name string, value T, usage string) *T
type FlagPFunc[T any] func(name, shorthand string, value T, usage string) *T
// AddFlagAndBind adds a Cobra/pflag flag and binds it with Viper.
func AddFlagAndBind[T any](v *viper.Viper, fs *pflag.FlagSet, pfn FlagFunc[T], name, bind string, value T, usage string) {
pfn(name, value, usage)
err := v.BindPFlag(bind, fs.Lookup(name))
if err != nil {
panic(fmt.Sprintf("failed to bind flag %s: %v", name, err))
}
}
// AddFlagAndBindP adds a Cobra/pflag flag and binds it with Viper.
func AddFlagAndBindP[T any](v *viper.Viper, fs *pflag.FlagSet, pfn FlagPFunc[T], name, shorthand, bind string, value T, usage string) {
pfn(name, shorthand, value, usage)
err := v.BindPFlag(bind, fs.Lookup(name))
if err != nil {
panic(fmt.Sprintf("failed to bind flag %s: %v", name, err))
}
}
// AddDeprecatedFlagAndBind similar to AddFlagAndBind but deprecate the flag.
func AddDeprecatedFlagAndBind[T any](v *viper.Viper, fs *pflag.FlagSet, pfn FlagFunc[T], name, bind string, value T, usage string) {
AddFlagAndBind(v, fs, pfn, name, bind, value, usage)
deprecateFlag(fs, name)
}
// AddHackedStringSliceP Hack for slice, see Loader.applyStringSliceHack.
func AddHackedStringSliceP(fs *pflag.FlagSet, name, shorthand, usage string) {
fs.StringSliceP(name, shorthand, nil, usage)
}
// AddHackedStringSlice Hack for slice, see Loader.applyStringSliceHack.
func AddHackedStringSlice(fs *pflag.FlagSet, name, usage string) {
AddHackedStringSliceP(fs, name, "", usage)
}
// AddDeprecatedHackedStringSlice similar to AddHackedStringSlice but deprecate the flag.
func AddDeprecatedHackedStringSlice(fs *pflag.FlagSet, name, usage string) {
AddHackedStringSlice(fs, name, usage)
deprecateFlag(fs, name)
}
func deprecateFlag(fs *pflag.FlagSet, name string) {
_ = fs.MarkHidden(name)
_ = fs.MarkDeprecated(name, "check the documentation for more information.")
}
================================================
FILE: pkg/commands/linters.go
================================================
package commands
import (
"encoding/json"
"fmt"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type lintersHelp struct {
Enabled []linterHelp
Disabled []linterHelp
}
type lintersOptions struct {
config.LoaderOptions
JSON bool
}
type lintersCommand struct {
viper *viper.Viper
cmd *cobra.Command
opts lintersOptions
cfg *config.Config
log logutils.Log
dbManager *lintersdb.Manager
}
func newLintersCommand(logger logutils.Log) *lintersCommand {
c := &lintersCommand{
viper: viper.New(),
cfg: config.NewDefault(),
log: logger,
}
lintersCmd := &cobra.Command{
Use: "linters",
Short: "List current linters configuration.",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
RunE: c.execute,
PreRunE: c.preRunE,
SilenceUsage: true,
}
fs := lintersCmd.Flags()
fs.SortFlags = false // sort them as they are defined here
setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
setupLintersFlagSet(c.viper, fs)
fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
c.cmd = lintersCmd
return c
}
func (c *lintersCommand) preRunE(cmd *cobra.Command, args []string) error {
loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
err := loader.Load(config.LoadOptions{Validation: true})
if err != nil {
return fmt.Errorf("can't load config: %w", err)
}
dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg,
lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log))
if err != nil {
return err
}
c.dbManager = dbManager
return nil
}
func (c *lintersCommand) execute(_ *cobra.Command, _ []string) error {
enabledLintersMap, err := c.dbManager.GetEnabledLintersMap()
if err != nil {
return fmt.Errorf("can't get enabled linters: %w", err)
}
var enabledLinters []*linter.Config
var disabledLinters []*linter.Config
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
if lc.Internal {
continue
}
if goformatters.IsFormatter(lc.Name()) {
continue
}
if enabledLintersMap[lc.Name()] == nil {
disabledLinters = append(disabledLinters, lc)
} else {
enabledLinters = append(enabledLinters, lc)
}
}
if c.opts.JSON {
linters := lintersHelp{}
for _, lc := range enabledLinters {
linters.Enabled = append(linters.Enabled, newLinterHelp(lc))
}
for _, lc := range disabledLinters {
linters.Disabled = append(linters.Disabled, newLinterHelp(lc))
}
return json.NewEncoder(c.cmd.OutOrStdout()).Encode(linters)
}
color.Green("Enabled by your configuration linters:\n")
printLinters(enabledLinters)
color.Red("\nDisabled by your configuration linters:\n")
printLinters(disabledLinters)
return nil
}
================================================
FILE: pkg/commands/migrate.go
================================================
package commands
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/charmbracelet/lipgloss"
"github.com/fatih/color"
"github.com/santhosh-tekuri/jsonschema/v6"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type migrateOptions struct {
config.LoaderOptions
format string // Flag only.
skipValidation bool // Flag only.
}
type migrateCommand struct {
viper *viper.Viper
cmd *cobra.Command
opts migrateOptions
cfg *versionone.Config
buildInfo BuildInfo
log logutils.Log
}
func newMigrateCommand(log logutils.Log, info BuildInfo) *migrateCommand {
c := &migrateCommand{
viper: viper.New(),
cfg: versionone.NewConfig(),
buildInfo: info,
log: log,
}
migrateCmd := &cobra.Command{
Use: "migrate",
Short: "Migrate configuration file from v1 to v2.",
SilenceUsage: true,
SilenceErrors: true,
Args: cobra.NoArgs,
RunE: c.execute,
PreRunE: c.preRunE,
PersistentPreRunE: c.persistentPreRunE,
}
migrateCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals
migrateCmd.SetErr(logutils.StdErr)
fs := migrateCmd.Flags()
fs.SortFlags = false // sort them as they are defined here
setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
fs.StringVar(&c.opts.format, "format", "",
color.GreenString("Output file format.\nBy default, the format of the input configuration file is used.\n"+
"It can be 'yml', 'yaml', 'toml', or 'json'."))
fs.BoolVar(&c.opts.skipValidation, "skip-validation", false,
color.GreenString("Skip validation of the configuration file against the JSON Schema for v1."))
c.cmd = migrateCmd
return c
}
func (c *migrateCommand) execute(_ *cobra.Command, _ []string) error {
srcPath := c.viper.ConfigFileUsed()
if srcPath == "" {
c.log.Warnf("No config file detected")
os.Exit(exitcodes.NoConfigFileDetected)
}
err := c.backupConfigurationFile(srcPath)
if err != nil {
return err
}
c.log.Warnf("The configuration comments are not migrated.")
c.log.Warnf("Details about the migration: https://golangci-lint.run/docs/product/migration-guide/")
c.log.Infof("Migrating v1 configuration file: %s", srcPath)
ext := filepath.Ext(srcPath)
if c.opts.format != "" {
ext = "." + c.opts.format
}
if !strings.EqualFold(filepath.Ext(srcPath), ext) {
defer func() {
_ = os.RemoveAll(srcPath)
}()
}
if c.cfg.Run.Timeout != 0 {
c.log.Warnf("The configuration `run.timeout` is ignored. By default, in v2, the timeout is disabled.")
}
newCfg := migrate.ToConfig(c.cfg)
dstPath := strings.TrimSuffix(srcPath, filepath.Ext(srcPath)) + ext
err = saveNewConfiguration(newCfg, dstPath)
if err != nil {
return fmt.Errorf("saving configuration file: %w", err)
}
c.log.Infof("Migration done: %s", dstPath)
callForAction(c.cmd)
return nil
}
func (c *migrateCommand) preRunE(cmd *cobra.Command, _ []string) error {
switch strings.ToLower(c.opts.format) {
case "", "yml", "yaml", "toml", "json":
// Valid format.
default:
return fmt.Errorf("unsupported format: %s", c.opts.format)
}
if c.cfg.Version != "" {
return fmt.Errorf("configuration version is already set: %s", c.cfg.Version)
}
if c.opts.skipValidation {
return nil
}
usedConfigFile := c.viper.ConfigFileUsed()
if usedConfigFile == "" {
c.log.Warnf("No config file detected")
os.Exit(exitcodes.NoConfigFileDetected)
}
c.log.Infof("Validating v1 configuration file: %s", usedConfigFile)
err := validateConfiguration("https://golangci-lint.run/jsonschema/golangci.v1.jsonschema.json", usedConfigFile)
if err != nil {
var v *jsonschema.ValidationError
if !errors.As(err, &v) {
return fmt.Errorf("[%s] validate: %w", usedConfigFile, err)
}
printValidationDetail(cmd, v.DetailedOutput())
return errors.New("the configuration contains invalid elements")
}
return nil
}
func (c *migrateCommand) persistentPreRunE(_ *cobra.Command, args []string) error {
c.log.Infof("%s", c.buildInfo.String())
loader := config.NewBaseLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, c.opts.LoaderOptions, fakeloader.NewConfig(), args)
// Loads the configuration just to get the effective path of the configuration.
err := loader.Load()
if err != nil {
return fmt.Errorf("can't load config: %w", err)
}
srcPath := c.viper.ConfigFileUsed()
if srcPath == "" {
c.log.Warnf("No config file detected")
os.Exit(exitcodes.NoConfigFileDetected)
}
return fakeloader.Load(srcPath, c.cfg)
}
func (c *migrateCommand) backupConfigurationFile(srcPath string) error {
filename := strings.TrimSuffix(filepath.Base(srcPath), filepath.Ext(srcPath)) + ".bck" + filepath.Ext(srcPath)
dstPath := filepath.Join(filepath.Dir(srcPath), filename)
c.log.Infof("Saving the v1 configuration to: %s", dstPath)
stat, err := os.Stat(srcPath)
if err != nil {
return err
}
data, err := os.ReadFile(srcPath)
if err != nil {
return err
}
err = os.WriteFile(dstPath, data, stat.Mode())
if err != nil {
return err
}
return nil
}
func saveNewConfiguration(cfg any, dstPath string) error {
dstFile, err := os.Create(dstPath)
if err != nil {
return err
}
defer func() { _ = dstFile.Close() }()
return parser.Encode(cfg, dstFile)
}
func callForAction(cmd *cobra.Command) {
pStyle := lipgloss.NewStyle().
Padding(1).
BorderStyle(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("161")).
Align(lipgloss.Center)
hStyle := lipgloss.NewStyle().Bold(true)
s := fmt.Sprintln(hStyle.Render("We need you!"))
s += `
Donations help fund the ongoing development and maintenance of this tool.
If golangci-lint has been useful to you, please consider contributing.
Donate now: https://donate.golangci.org`
cmd.Println(pStyle.Render(s))
}
================================================
FILE: pkg/commands/root.go
================================================
package commands
import (
"errors"
"fmt"
"os"
"slices"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
func Execute(info BuildInfo) error {
return newRootCommand(info).Execute()
}
type rootOptions struct {
PrintVersion bool // Flag only.
Verbose bool // Flag only.
Color string // Flag only.
}
type rootCommand struct {
cmd *cobra.Command
opts rootOptions
log logutils.Log
}
func newRootCommand(info BuildInfo) *rootCommand {
c := &rootCommand{}
rootCmd := &cobra.Command{
Use: "golangci-lint",
Short: "golangci-lint is a smart linters runner.",
Long: `Smart, fast linters runner.`,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
if c.opts.PrintVersion {
_ = printVersion(logutils.StdOut, info)
return nil
}
return cmd.Help()
},
}
fs := rootCmd.Flags()
fs.BoolVar(&c.opts.PrintVersion, "version", false, color.GreenString("Print version"))
setupRootPersistentFlags(rootCmd.PersistentFlags(), &c.opts)
log := logutils.NewStderrLog(logutils.DebugKeyEmpty)
// Each command uses a dedicated configuration structure to avoid side effects of bindings.
rootCmd.AddCommand(
newLintersCommand(log).cmd,
newFormattersCommand(log).cmd,
newRunCommand(log, info).cmd,
newFmtCommand(log, info).cmd,
newMigrateCommand(log, info).cmd,
newCacheCommand().cmd,
newConfigCommand(log, info).cmd,
newVersionCommand(info).cmd,
newCustomCommand(log).cmd,
)
rootCmd.SetHelpCommand(newHelpCommand(log).cmd)
c.log = log
c.cmd = rootCmd
return c
}
func (c *rootCommand) Execute() error {
err := setupLogger(c.log)
if err != nil {
return err
}
return c.cmd.Execute()
}
func setupRootPersistentFlags(fs *pflag.FlagSet, opts *rootOptions) {
fs.BoolP("help", "h", false, color.GreenString("Help for a command"))
fs.BoolVarP(&opts.Verbose, "verbose", "v", false, color.GreenString("Verbose output"))
fs.StringVar(&opts.Color, "color", "auto", color.GreenString("Use color when printing; can be 'always', 'auto', or 'never'"))
}
func setupLogger(logger logutils.Log) error {
opts, err := forceRootParsePersistentFlags()
if err != nil && !errors.Is(err, pflag.ErrHelp) {
return err
}
if opts == nil {
return nil
}
logutils.SetupVerboseLog(logger, opts.Verbose)
switch opts.Color {
case "always":
color.NoColor = false
case "never":
color.NoColor = true
case "auto":
// nothing
default:
logger.Fatalf("invalid value %q for --color; must be 'always', 'auto', or 'never'", opts.Color)
}
// For log level colors (mainly for verbose output)
logutils.DisableColors(color.NoColor)
return nil
}
func forceRootParsePersistentFlags() (*rootOptions, error) {
// We use another pflag.FlagSet here to not set `changed` flag on cmd.Flags() options.
// Otherwise, string slice options will be duplicated.
fs := pflag.NewFlagSet("config flag set", pflag.ContinueOnError)
// Ignore unknown flags because we will parse the command flags later.
fs.ParseErrorsAllowlist = pflag.ParseErrorsAllowlist{UnknownFlags: true}
opts := &rootOptions{}
// Don't do `fs.AddFlagSet(cmd.Flags())` because it shares flags representations:
// `changed` variable inside string slice vars will be shared.
// Use another config variable here,
// to not affect main parsing by this parsing of only config option.
setupRootPersistentFlags(fs, opts)
fs.Usage = func() {} // otherwise, help text will be printed twice
if err := fs.Parse(safeArgs(fs, os.Args)); err != nil {
if errors.Is(err, pflag.ErrHelp) {
return nil, err
}
return nil, fmt.Errorf("can't parse args: %w", err)
}
return opts, nil
}
// Shorthands are a problem because pflag, with UnknownFlags, will try to parse all the letters as options.
// A shorthand can aggregate several letters (ex `ps -aux`)
// The function replaces non-supported shorthands by a dumb flag.
func safeArgs(fs *pflag.FlagSet, args []string) []string {
var shorthands []string
fs.VisitAll(func(flag *pflag.Flag) {
shorthands = append(shorthands, flag.Shorthand)
})
var cleanArgs []string
for _, arg := range args {
if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' && !slices.Contains(shorthands, string(arg[1])) {
cleanArgs = append(cleanArgs, "--potato")
continue
}
cleanArgs = append(cleanArgs, arg)
}
return cleanArgs
}
================================================
FILE: pkg/commands/run.go
================================================
package commands
import (
"bytes"
"context"
"crypto/sha256"
"errors"
"fmt"
"io"
"log"
"maps"
"os"
"path/filepath"
"runtime"
"runtime/pprof"
"runtime/trace"
"slices"
"strconv"
"strings"
"time"
"github.com/fatih/color"
"github.com/gofrs/flock"
"github.com/ldez/grignotin/goenv"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"go.yaml.in/yaml/v3"
"golang.org/x/mod/sumdb/dirhash"
"github.com/golangci/golangci-lint/v2/internal/cache"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
"github.com/golangci/golangci-lint/v2/pkg/goutil"
"github.com/golangci/golangci-lint/v2/pkg/lint"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
"github.com/golangci/golangci-lint/v2/pkg/printers"
"github.com/golangci/golangci-lint/v2/pkg/report"
"github.com/golangci/golangci-lint/v2/pkg/result"
"github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
const defaultTimeout = 0 * time.Minute
const (
// envFailOnWarnings value: "1"
envFailOnWarnings = "FAIL_ON_WARNINGS"
// envMemLogEvery value: "1"
envMemLogEvery = "GL_MEM_LOG_EVERY"
)
const (
envMemProfileRate = "GL_MEM_PROFILE_RATE"
)
type runOptions struct {
config.LoaderOptions
CPUProfilePath string // Flag only.
MemProfilePath string // Flag only.
TracePath string // Flag only.
PrintResourcesUsage bool // Flag only.
}
type runCommand struct {
viper *viper.Viper
cmd *cobra.Command
opts runOptions
cfg *config.Config
buildInfo BuildInfo
dbManager *lintersdb.Manager
printer *printers.Printer
log logutils.Log
debugf logutils.DebugFunc
reportData *report.Data
contextBuilder *lint.ContextBuilder
goenv *goutil.Env
fileCache *fsutils.FileCache
lineCache *fsutils.LineCache
flock *flock.Flock
exitCode int
}
func newRunCommand(logger logutils.Log, info BuildInfo) *runCommand {
reportData := &report.Data{}
c := &runCommand{
viper: viper.New(),
log: report.NewLogWrapper(logger, reportData),
debugf: logutils.Debug(logutils.DebugKeyExec),
cfg: config.NewDefault(),
reportData: reportData,
buildInfo: info,
}
runCmd := &cobra.Command{
Use: "run",
Short: "Lint the code.",
Run: c.execute,
PreRunE: c.preRunE,
PostRun: c.postRun,
PersistentPreRunE: c.persistentPreRunE,
PersistentPostRunE: c.persistentPostRunE,
SilenceUsage: true,
}
runCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals
runCmd.SetErr(logutils.StdErr)
fs := runCmd.Flags()
fs.SortFlags = false // sort them as they are defined here
// Only for testing purpose.
// Don't add other flags here.
fs.BoolVar(&c.cfg.InternalCmdTest, "internal-cmd-test", false,
color.GreenString("Option is used only for testing golangci-lint command, don't use it"))
_ = fs.MarkHidden("internal-cmd-test")
setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
setupLintersFlagSet(c.viper, fs)
setupRunFlagSet(c.viper, fs)
setupOutputFlagSet(c.viper, fs)
setupIssuesFlagSet(c.viper, fs)
setupRunPersistentFlags(runCmd.PersistentFlags(), &c.opts)
c.cmd = runCmd
return c
}
func (c *runCommand) persistentPreRunE(cmd *cobra.Command, args []string) error {
if err := c.startTracing(); err != nil {
return err
}
c.log.Infof("%s", c.buildInfo.String())
loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
err := loader.Load(config.LoadOptions{CheckDeprecation: true, Validation: true})
if err != nil {
return fmt.Errorf("can't load config: %w", err)
}
// https://go.dev/doc/go1.25#container-aware-gomaxprocs
if c.cfg.Run.Concurrency != 0 {
runtime.GOMAXPROCS(c.cfg.Run.Concurrency)
}
return nil
}
func (c *runCommand) persistentPostRunE(_ *cobra.Command, _ []string) error {
if err := c.stopTracing(); err != nil {
return err
}
os.Exit(c.exitCode)
return nil
}
func (c *runCommand) preRunE(_ *cobra.Command, args []string) error {
dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg,
lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log))
if err != nil {
return err
}
c.dbManager = dbManager
c.printer, err = printers.NewPrinter(c.log, &c.cfg.Output.Formats, c.reportData, c.cfg.GetBasePath())
if err != nil {
return err
}
c.goenv = goutil.NewEnv(c.log.Child(logutils.DebugKeyGoEnv))
c.fileCache = fsutils.NewFileCache()
c.lineCache = fsutils.NewLineCache(c.fileCache)
sw := timeutils.NewStopwatch("pkgcache", c.log.Child(logutils.DebugKeyStopwatch))
pkgCache, err := cache.NewCache(sw, c.log.Child(logutils.DebugKeyPkgCache))
if err != nil {
return fmt.Errorf("failed to build packages cache: %w", err)
}
guard := load.NewGuard()
pkgLoader := lint.NewPackageLoader(c.log.Child(logutils.DebugKeyLoader), c.cfg, args, c.goenv, guard)
c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, pkgCache, guard)
if err = initHashSalt(c.log.Child(logutils.DebugKeyGoModSalt), c.buildInfo.Version, c.cfg); err != nil {
return fmt.Errorf("failed to init hash salt: %w", err)
}
if ok := c.acquireFileLock(); !ok {
return errors.New("parallel golangci-lint is running")
}
return nil
}
func (c *runCommand) postRun(_ *cobra.Command, _ []string) {
c.releaseFileLock()
}
func (c *runCommand) execute(_ *cobra.Command, _ []string) {
needTrackResources := logutils.IsVerbose() || c.opts.PrintResourcesUsage
trackResourcesEndCh := make(chan struct{})
// Note: this defer must be before ctx.cancel defer
defer func() {
// wait until resource tracking finished to print properly
if needTrackResources {
<-trackResourcesEndCh
}
}()
ctx, cancel := context.WithCancel(context.Background())
if c.cfg.Run.Timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, c.cfg.Run.Timeout)
}
defer cancel()
if needTrackResources {
go watchResources(ctx, trackResourcesEndCh, c.log, c.debugf)
}
if err := c.runAndPrint(ctx); err != nil {
c.log.Errorf("Running error: %s", err)
if c.exitCode == exitcodes.Success {
var exitErr *exitcodes.ExitError
if errors.As(err, &exitErr) {
c.exitCode = exitErr.Code
} else {
c.exitCode = exitcodes.Failure
}
}
}
c.setupExitCode(ctx)
}
func (c *runCommand) startTracing() error {
if c.opts.CPUProfilePath != "" {
f, err := os.Create(c.opts.CPUProfilePath)
if err != nil {
return fmt.Errorf("can't create file %s: %w", c.opts.CPUProfilePath, err)
}
if err := pprof.StartCPUProfile(f); err != nil {
return fmt.Errorf("can't start CPU profiling: %w", err)
}
}
if c.opts.MemProfilePath != "" {
if rate := os.Getenv(envMemProfileRate); rate != "" {
runtime.MemProfileRate, _ = strconv.Atoi(rate)
}
}
if c.opts.TracePath != "" {
f, err := os.Create(c.opts.TracePath)
if err != nil {
return fmt.Errorf("can't create file %s: %w", c.opts.TracePath, err)
}
if err = trace.Start(f); err != nil {
return fmt.Errorf("can't start tracing: %w", err)
}
}
return nil
}
func (c *runCommand) stopTracing() error {
if c.opts.CPUProfilePath != "" {
pprof.StopCPUProfile()
}
if c.opts.MemProfilePath != "" {
f, err := os.Create(c.opts.MemProfilePath)
if err != nil {
return fmt.Errorf("can't create file %s: %w", c.opts.MemProfilePath, err)
}
var ms runtime.MemStats
runtime.ReadMemStats(&ms)
printMemStats(&ms, c.log)
if err := pprof.WriteHeapProfile(f); err != nil {
return fmt.Errorf("can't write heap profile: %w", err)
}
_ = f.Close()
}
if c.opts.TracePath != "" {
trace.Stop()
}
return nil
}
func (c *runCommand) runAndPrint(ctx context.Context) error {
if err := c.goenv.Discover(ctx); err != nil {
c.log.Warnf("Failed to discover go env: %s", err)
}
if !logutils.HaveDebugTag(logutils.DebugKeyLintersOutput) {
// Don't allow linters and loader to print anything
log.SetOutput(io.Discard)
savedStdout, savedStderr := c.setOutputToDevNull()
defer func() {
os.Stdout, os.Stderr = savedStdout, savedStderr
}()
}
enabledLintersMap, err := c.dbManager.GetEnabledLintersMap()
if err != nil {
return err
}
c.printDeprecatedLinterMessages(enabledLintersMap)
issues, err := c.runAnalysis(ctx)
if err != nil {
return err // XXX: don't lose type
}
// Fills linters information for the JSON printer.
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
isEnabled := enabledLintersMap[lc.Name()] != nil
c.reportData.AddLinter(lc.Name(), isEnabled)
}
err = c.printer.Print(issues)
if err != nil {
return err
}
c.printStats(issues)
c.setExitCodeIfIssuesFound(issues)
c.fileCache.PrintStats(c.log)
return nil
}
// runAnalysis executes the linters that have been enabled in the configuration.
func (c *runCommand) runAnalysis(ctx context.Context) ([]*result.Issue, error) {
lintersToRun, err := c.dbManager.GetOptimizedLinters()
if err != nil {
return nil, err
}
lintCtx, err := c.contextBuilder.Build(ctx, c.log.Child(logutils.DebugKeyLintersContext), lintersToRun)
if err != nil {
return nil, fmt.Errorf("context loading failed: %w", err)
}
runner, err := lint.NewRunner(c.log.Child(logutils.DebugKeyRunner), c.cfg,
c.goenv, c.lineCache, c.fileCache, c.dbManager, lintCtx)
if err != nil {
return nil, err
}
return runner.Run(ctx, lintersToRun)
}
func (c *runCommand) setOutputToDevNull() (savedStdout, savedStderr *os.File) {
savedStdout, savedStderr = os.Stdout, os.Stderr
devNull, err := os.Open(os.DevNull)
if err != nil {
c.log.Warnf("Can't open null device %q: %s", os.DevNull, err)
return
}
os.Stdout, os.Stderr = devNull, devNull
return
}
func (c *runCommand) setExitCodeIfIssuesFound(issues []*result.Issue) {
if len(issues) != 0 {
c.exitCode = c.cfg.Run.ExitCodeIfIssuesFound
}
}
func (c *runCommand) printDeprecatedLinterMessages(enabledLinters map[string]*linter.Config) {
if c.cfg.InternalCmdTest || os.Getenv(logutils.EnvTestRun) == "1" {
return
}
for name, lc := range enabledLinters {
if !lc.IsDeprecated() {
continue
}
var extra string
if lc.Deprecation.Replacement != "" {
extra = fmt.Sprintf("Replaced by %s.", lc.Deprecation.Replacement)
}
c.log.Warnf("The linter '%s' is deprecated (since %s) due to: %s %s", name, lc.Deprecation.Since, lc.Deprecation.Message, extra)
if lc.Deprecation.ConfigSuggestion != nil {
suggestion, err := lc.Deprecation.ConfigSuggestion()
if err != nil {
c.log.Errorf("New configuration suggestion error: %v", err)
}
if suggestion != "" {
c.log.Warnf("Suggested new configuration:\n%s", suggestion)
}
}
}
}
func (c *runCommand) printStats(issues []*result.Issue) {
if !c.cfg.Output.ShowStats {
return
}
if len(issues) == 0 {
c.cmd.Println("0 issues.")
return
}
stats := map[string]int{}
for idx := range issues {
stats[issues[idx].FromLinter]++
}
c.cmd.Printf("%d issues:\n", len(issues))
keys := slices.Sorted(maps.Keys(stats))
for _, key := range keys {
c.cmd.Printf("* %s: %d\n", key, stats[key])
}
}
func (c *runCommand) setupExitCode(ctx context.Context) {
if ctx.Err() != nil {
c.exitCode = exitcodes.Timeout
c.log.Errorf("Timeout exceeded: try increasing it by passing --timeout option")
return
}
if c.exitCode != exitcodes.Success {
return
}
needFailOnWarnings := os.Getenv(logutils.EnvTestRun) == "1" || os.Getenv(envFailOnWarnings) == "1"
if needFailOnWarnings && len(c.reportData.Warnings) != 0 {
c.exitCode = exitcodes.WarningInTest
return
}
if c.reportData.Error != "" {
// it's a case e.g. when typecheck linter couldn't parse and error and just logged it
c.exitCode = exitcodes.ErrorWasLogged
return
}
}
func (c *runCommand) acquireFileLock() bool {
if c.cfg.Run.AllowParallelRunners {
c.debugf("Parallel runners are allowed, no locking")
return true
}
lockFile := filepath.Join(os.TempDir(), "golangci-lint.lock")
c.debugf("Locking on file %s...", lockFile)
f := flock.New(lockFile)
const retryDelay = time.Second
ctx := context.Background()
if !c.cfg.Run.AllowSerialRunners {
const totalTimeout = 5 * time.Second
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, totalTimeout)
defer cancel()
}
if ok, _ := f.TryLockContext(ctx, retryDelay); !ok {
return false
}
c.flock = f
return true
}
func (c *runCommand) releaseFileLock() {
if c.cfg.Run.AllowParallelRunners {
return
}
if err := c.flock.Unlock(); err != nil {
c.debugf("Failed to unlock on file: %s", err)
}
if err := os.Remove(c.flock.Path()); err != nil {
c.debugf("Failed to remove lock file: %s", err)
}
}
func watchResources(ctx context.Context, done chan struct{}, logger logutils.Log, debugf logutils.DebugFunc) {
startedAt := time.Now()
debugf("Started tracking time")
var maxRSSMB, totalRSSMB float64
var iterationsCount int
const intervalMS = 100
ticker := time.NewTicker(intervalMS * time.Millisecond)
defer ticker.Stop()
logEveryRecord := os.Getenv(envMemLogEvery) == "1"
const MB = 1024 * 1024
track := func() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
if logEveryRecord {
debugf("Stopping memory tracing iteration, printing ...")
printMemStats(&m, logger)
}
rssMB := float64(m.Sys) / MB
if rssMB > maxRSSMB {
maxRSSMB = rssMB
}
totalRSSMB += rssMB
iterationsCount++
}
for {
track()
stop := false
select {
case <-ctx.Done():
stop = true
debugf("Stopped resources tracking")
case <-ticker.C:
}
if stop {
break
}
}
track()
avgRSSMB := totalRSSMB / float64(iterationsCount)
logger.Infof("Memory: %d samples, avg is %.1fMB, max is %.1fMB",
iterationsCount, avgRSSMB, maxRSSMB)
logger.Infof("Execution took %s", time.Since(startedAt))
close(done)
}
func setupConfigFileFlagSet(fs *pflag.FlagSet, cfg *config.LoaderOptions) {
fs.StringVarP(&cfg.Config, "config", "c", "", color.GreenString("Read config from file path `PATH`"))
fs.BoolVar(&cfg.NoConfig, "no-config", false, color.GreenString("Don't read config file"))
}
func setupRunPersistentFlags(fs *pflag.FlagSet, opts *runOptions) {
fs.BoolVar(&opts.PrintResourcesUsage, "print-resources-usage", false,
color.GreenString("Print avg and max memory usage of golangci-lint and total time"))
_ = fs.MarkDeprecated("print-resources-usage", "use --verbose instead")
fs.StringVar(&opts.CPUProfilePath, "cpu-profile-path", "", color.GreenString("Path to CPU profile output file"))
fs.StringVar(&opts.MemProfilePath, "mem-profile-path", "", color.GreenString("Path to memory profile output file"))
fs.StringVar(&opts.TracePath, "trace-path", "", color.GreenString("Path to trace output file"))
}
func printMemStats(ms *runtime.MemStats, logger logutils.Log) {
logger.Infof("Mem stats: alloc=%s total_alloc=%s sys=%s "+
"heap_alloc=%s heap_sys=%s heap_idle=%s heap_released=%s heap_in_use=%s "+
"stack_in_use=%s stack_sys=%s "+
"mspan_sys=%s mcache_sys=%s buck_hash_sys=%s gc_sys=%s other_sys=%s "+
"mallocs_n=%d frees_n=%d heap_objects_n=%d gc_cpu_fraction=%.2f",
formatMemory(ms.Alloc), formatMemory(ms.TotalAlloc), formatMemory(ms.Sys),
formatMemory(ms.HeapAlloc), formatMemory(ms.HeapSys),
formatMemory(ms.HeapIdle), formatMemory(ms.HeapReleased), formatMemory(ms.HeapInuse),
formatMemory(ms.StackInuse), formatMemory(ms.StackSys),
formatMemory(ms.MSpanSys), formatMemory(ms.MCacheSys), formatMemory(ms.BuckHashSys),
formatMemory(ms.GCSys), formatMemory(ms.OtherSys),
ms.Mallocs, ms.Frees, ms.HeapObjects, ms.GCCPUFraction)
}
func formatMemory(memBytes uint64) string {
const Kb = 1024
const Mb = Kb * 1024
if memBytes < Kb {
return fmt.Sprintf("%db", memBytes)
}
if memBytes < Mb {
return fmt.Sprintf("%dkb", memBytes/Kb)
}
return fmt.Sprintf("%dmb", memBytes/Mb)
}
// Related to cache.
func initHashSalt(logger logutils.Log, version string, cfg *config.Config) error {
binSalt, err := computeBinarySalt(version)
if err != nil {
return fmt.Errorf("failed to calculate binary salt: %w", err)
}
configSalt, err := computeConfigSalt(cfg)
if err != nil {
return fmt.Errorf("failed to calculate config salt: %w", err)
}
goModSalt, err := computeGoModSalt()
if err != nil {
// NOTE: missing go.mod must be ignored.
logger.Warnf("Failed to calculate go.mod salt: %v", err)
}
b := bytes.NewBuffer(binSalt)
b.Write(configSalt)
b.WriteString(goModSalt)
cache.SetSalt(b)
return nil
}
func computeBinarySalt(version string) ([]byte, error) {
if version != "" && version != "(devel)" {
return []byte(version), nil
}
if logutils.HaveDebugTag(logutils.DebugKeyBinSalt) {
return []byte("debug"), nil
}
p, err := os.Executable()
if err != nil {
return nil, err
}
f, err := os.Open(p)
if err != nil {
return nil, err
}
defer f.Close()
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
return nil, err
}
return h.Sum(nil), nil
}
// computeConfigSalt computes configuration hash.
// We don't hash all config fields to reduce meaningless cache invalidations.
// At least, it has a huge impact on tests speed.
// Fields: `LintersSettings` and `Run.BuildTags`.
func computeConfigSalt(cfg *config.Config) ([]byte, error) {
lintersSettingsBytes, err := yaml.Marshal(cfg.Linters.Settings)
if err != nil {
return nil, fmt.Errorf("failed to JSON marshal config linter settings: %w", err)
}
configData := bytes.NewBufferString("linters.settings=")
configData.Write(lintersSettingsBytes)
configData.WriteString("\nbuild-tags=%s" + strings.Join(cfg.Run.BuildTags, ","))
h := sha256.New()
if _, err := h.Write(configData.Bytes()); err != nil {
return nil, err
}
return h.Sum(nil), nil
}
func computeGoModSalt() (string, error) {
values, err := goenv.Get(context.Background(), goenv.GOMOD)
if err != nil {
return "", fmt.Errorf("failed to get goenv: %w", err)
}
goModPath := filepath.Clean(values[goenv.GOMOD])
data, err := os.ReadFile(goModPath)
if err != nil {
return "", fmt.Errorf("failed to read go.mod: %w", err)
}
sum, err := dirhash.Hash1([]string{goModPath}, func(string) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(data)), nil
})
if err != nil {
return "", fmt.Errorf("failed to compute go.sum: %w", err)
}
return sum, nil
}
================================================
FILE: pkg/commands/version.go
================================================
package commands
import (
"encoding/json"
"fmt"
"io"
"os"
"runtime/debug"
"github.com/fatih/color"
"github.com/spf13/cobra"
)
type BuildInfo struct {
GoVersion string `json:"goVersion"`
Version string `json:"version"`
Commit string `json:"commit"`
Date string `json:"date"`
BuildInfo *debug.BuildInfo `json:"buildInfo,omitempty"`
}
func (b BuildInfo) String() string {
return fmt.Sprintf("golangci-lint has version %s built with %s from %s on %s",
b.Version, b.GoVersion, b.Commit, b.Date)
}
type versionOptions struct {
Debug bool
JSON bool
Short bool
}
type versionCommand struct {
cmd *cobra.Command
opts versionOptions
info BuildInfo
}
func newVersionCommand(info BuildInfo) *versionCommand {
c := &versionCommand{info: info}
versionCmd := &cobra.Command{
Use: "version",
Short: "Display the golangci-lint version.",
Args: cobra.NoArgs,
ValidArgsFunction: cobra.NoFileCompletions,
RunE: c.execute,
}
fs := versionCmd.Flags()
fs.SortFlags = false // sort them as they are defined here
fs.BoolVar(&c.opts.Debug, "debug", false, color.GreenString("Add build information"))
fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
fs.BoolVar(&c.opts.Short, "short", false, color.GreenString("Display only the version number"))
c.cmd = versionCmd
return c
}
func (c *versionCommand) execute(_ *cobra.Command, _ []string) error {
var info *debug.BuildInfo
if c.opts.Debug {
info, _ = debug.ReadBuildInfo()
}
switch {
case c.opts.JSON:
c.info.BuildInfo = info
return json.NewEncoder(os.Stdout).Encode(c.info)
case c.opts.Short:
fmt.Println(c.info.Version)
return nil
default:
if info != nil {
fmt.Println(info.String())
}
return printVersion(os.Stdout, c.info)
}
}
func printVersion(w io.Writer, info BuildInfo) error {
_, err := fmt.Fprintln(w, info.String())
return err
}
================================================
FILE: pkg/config/base_loader.go
================================================
package config
import (
"errors"
"fmt"
"os"
"path/filepath"
"slices"
"github.com/go-viper/mapstructure/v2"
"github.com/mitchellh/go-homedir"
"github.com/spf13/viper"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type BaseConfig interface {
IsInternalTest() bool
SetConfigDir(dir string)
}
type BaseLoader struct {
opts LoaderOptions
viper *viper.Viper
log logutils.Log
cfg BaseConfig
args []string
}
func NewBaseLoader(log logutils.Log, v *viper.Viper, opts LoaderOptions, cfg BaseConfig, args []string) *BaseLoader {
return &BaseLoader{
opts: opts,
viper: v,
log: log,
cfg: cfg,
args: args,
}
}
func (l *BaseLoader) Load() error {
err := l.setConfigFile()
if err != nil {
return err
}
err = l.parseConfig()
if err != nil {
return err
}
return nil
}
func (l *BaseLoader) setConfigFile() error {
configFile, err := l.evaluateOptions()
if err != nil {
if errors.Is(err, errConfigDisabled) {
return nil
}
return fmt.Errorf("can't parse --config option: %w", err)
}
if configFile != "" {
l.viper.SetConfigFile(configFile)
// Assume YAML if the file has no extension.
if filepath.Ext(configFile) == "" {
l.viper.SetConfigType("yaml")
}
} else {
l.setupConfigFileSearch()
}
return nil
}
func (l *BaseLoader) evaluateOptions() (string, error) {
if l.opts.NoConfig && l.opts.Config != "" {
return "", errors.New("can't combine option --config and --no-config")
}
if l.opts.NoConfig {
return "", errConfigDisabled
}
configFile, err := homedir.Expand(l.opts.Config)
if err != nil {
return "", errors.New("failed to expand configuration path")
}
return configFile, nil
}
func (l *BaseLoader) setupConfigFileSearch() {
l.viper.SetConfigName(".golangci")
configSearchPaths := l.getConfigSearchPaths()
l.log.Infof("Config search paths: %s", configSearchPaths)
for _, p := range configSearchPaths {
l.viper.AddConfigPath(p)
}
}
func (l *BaseLoader) getConfigSearchPaths() []string {
firstArg := "./..."
if len(l.args) > 0 {
firstArg = l.args[0]
}
absPath, err := filepath.Abs(firstArg)
if err != nil {
l.log.Warnf("Can't make abs path for %q: %s", firstArg, err)
absPath = filepath.Clean(firstArg)
}
// start from it
var currentDir string
if fsutils.IsDir(absPath) {
currentDir = absPath
} else {
currentDir = filepath.Dir(absPath)
}
// find all dirs from it up to the root
searchPaths := []string{"./"}
for {
searchPaths = append(searchPaths, currentDir)
parent := filepath.Dir(currentDir)
if currentDir == parent || parent == "" {
break
}
currentDir = parent
}
// find home directory for global config
if home, err := homedir.Dir(); err != nil {
l.log.Warnf("Can't get user's home directory: %v", err)
} else if !slices.Contains(searchPaths, home) {
searchPaths = append(searchPaths, home)
}
return searchPaths
}
func (l *BaseLoader) parseConfig() error {
if err := l.viper.ReadInConfig(); err != nil {
var configFileNotFoundError viper.ConfigFileNotFoundError
if errors.As(err, &configFileNotFoundError) {
// Load configuration from flags only.
err = l.viper.Unmarshal(l.cfg, customDecoderHook())
if err != nil {
return fmt.Errorf("can't unmarshal config by viper (flags): %w", err)
}
return nil
}
return fmt.Errorf("can't read viper config: %w", err)
}
err := l.setConfigDir()
if err != nil {
return err
}
// Load configuration from all sources (flags, file).
if err := l.viper.Unmarshal(l.cfg, customDecoderHook()); err != nil {
return fmt.Errorf("can't unmarshal config by viper (flags, file): %w", err)
}
if l.cfg.IsInternalTest() { // just for testing purposes: to detect config file usage
_, _ = fmt.Fprintln(logutils.StdOut, "test")
os.Exit(exitcodes.Success)
}
return nil
}
func (l *BaseLoader) setConfigDir() error {
usedConfigFile := l.viper.ConfigFileUsed()
if usedConfigFile == "" {
return nil
}
if usedConfigFile == os.Stdin.Name() {
usedConfigFile = ""
l.log.Infof("Reading config file stdin")
} else {
var err error
usedConfigFile, err = fsutils.ShortestRelPath(usedConfigFile, "")
if err != nil {
l.log.Warnf("Can't pretty print config file path: %v", err)
}
l.log.Infof("Used config file %s", usedConfigFile)
}
usedConfigDir, err := filepath.Abs(filepath.Dir(usedConfigFile))
if err != nil {
return errors.New("can't get config directory")
}
l.cfg.SetConfigDir(usedConfigDir)
return nil
}
func customDecoderHook() viper.DecoderConfigOption {
return viper.DecodeHook(DecodeHookFunc())
}
func DecodeHookFunc() mapstructure.DecodeHookFunc {
return mapstructure.ComposeDecodeHookFunc(
// Default hooks (https://github.com/spf13/viper/blob/518241257478c557633ab36e474dfcaeb9a3c623/viper.go#L135-L138).
mapstructure.StringToTimeDurationHookFunc(),
mapstructure.StringToSliceHookFunc(","),
// Needed for forbidigo, and output.formats.
mapstructure.TextUnmarshallerHookFunc(),
)
}
================================================
FILE: pkg/config/base_rule.go
================================================
package config
import (
"errors"
"fmt"
"regexp"
)
type BaseRule struct {
Linters []string `mapstructure:"linters"`
Path string `mapstructure:"path"`
PathExcept string `mapstructure:"path-except"`
Text string `mapstructure:"text"`
Source string `mapstructure:"source"`
// For compatibility with exclude-use-default/include.
InternalReference string `mapstructure:"-"`
}
func (b *BaseRule) Validate(minConditionsCount int) error {
if err := validateOptionalRegex(b.Path); err != nil {
return fmt.Errorf("invalid path regex: %w", err)
}
if err := validateOptionalRegex(b.PathExcept); err != nil {
return fmt.Errorf("invalid path-except regex: %w", err)
}
if err := validateOptionalRegex(b.Text); err != nil {
return fmt.Errorf("invalid text regex: %w", err)
}
if err := validateOptionalRegex(b.Source); err != nil {
return fmt.Errorf("invalid source regex: %w", err)
}
if b.Path != "" && b.PathExcept != "" {
return errors.New("path and path-except should not be set at the same time")
}
nonBlank := 0
if len(b.Linters) > 0 {
nonBlank++
}
// Filtering by path counts as one condition, regardless how it is done (one or both).
// Otherwise, a rule with Path and PathExcept set would pass validation
// whereas before the introduction of path-except that wouldn't have been precise enough.
if b.Path != "" || b.PathExcept != "" {
nonBlank++
}
if b.Text != "" {
nonBlank++
}
if b.Source != "" {
nonBlank++
}
if nonBlank < minConditionsCount {
return fmt.Errorf("at least %d of (text, source, path[-except], linters) should be set", minConditionsCount)
}
return nil
}
func validateOptionalRegex(value string) error {
if value == "" {
return nil
}
_, err := regexp.Compile(value)
return err
}
================================================
FILE: pkg/config/config.go
================================================
package config
import (
"cmp"
"context"
"fmt"
"os"
"path/filepath"
"slices"
"strings"
hcversion "github.com/hashicorp/go-version"
"github.com/ldez/grignotin/goenv"
"github.com/ldez/grignotin/gomod"
"golang.org/x/mod/modfile"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
// defaultGoVersion the value should be "oldstable" - 1.
// If the current stable version is 1.24 then 1.23 - 1 = 1.22.
const defaultGoVersion = "1.22"
// Config encapsulates the config data specified in the golangci-lint YAML config file.
type Config struct {
cfgDir string // Path to the directory containing golangci-lint config file.
basePath string // Path the root directory related to [Run.RelativePathMode].
Version string `mapstructure:"version"`
Run Run `mapstructure:"run"`
Output Output `mapstructure:"output"`
Linters Linters `mapstructure:"linters"`
Issues Issues `mapstructure:"issues"`
Severity Severity `mapstructure:"severity"`
Formatters Formatters `mapstructure:"formatters"`
InternalCmdTest bool // Option is used only for testing golangci-lint command, don't use it
InternalTest bool // Option is used only for testing golangci-lint code, don't use it
}
// GetConfigDir returns the directory that contains golangci-lint config file.
func (c *Config) GetConfigDir() string {
return c.cfgDir
}
// SetConfigDir sets the path to directory that contains golangci-lint config file.
func (c *Config) SetConfigDir(dir string) {
c.cfgDir = dir
}
func (c *Config) GetBasePath() string {
return c.basePath
}
func (c *Config) IsInternalTest() bool {
return c.InternalTest
}
func (c *Config) Validate() error {
validators := []func() error{
c.Run.Validate,
c.Output.Validate,
c.Linters.Validate,
c.Formatters.Validate,
c.Severity.Validate,
}
for _, v := range validators {
if err := v(); err != nil {
return err
}
}
return nil
}
func NewDefault() *Config {
return &Config{
Linters: Linters{
Settings: defaultLintersSettings,
},
Formatters: Formatters{
Settings: defaultFormatterSettings,
},
}
}
func IsGoGreaterThanOrEqual(current, limit string) bool {
v1, err := hcversion.NewVersion(strings.TrimPrefix(current, "go"))
if err != nil {
return false
}
l, err := hcversion.NewVersion(limit)
if err != nil {
return false
}
return v1.GreaterThanOrEqual(l)
}
func detectGoVersion(ctx context.Context, log logutils.Log) string {
return cmp.Or(detectGoVersionFromGoMod(ctx, log), defaultGoVersion)
}
// detectGoVersionFromGoMod tries to get Go version from go.mod.
// It returns `toolchain` version if present,
// else it returns `go` version if present,
// else it returns `GOVERSION` version if present,
// else it returns empty.
func detectGoVersionFromGoMod(ctx context.Context, log logutils.Log) string {
values, err := goenv.Get(ctx, goenv.GOMOD, goenv.GOVERSION)
if err != nil {
values = map[string]string{
goenv.GOMOD: detectGoModFallback(ctx),
}
}
if values[goenv.GOMOD] == "" {
return parseGoVersion(values[goenv.GOVERSION])
}
file, err := parseGoMod(values[goenv.GOMOD])
if err != nil {
return parseGoVersion(values[goenv.GOVERSION])
}
if file.Module != nil {
log.Infof("Module name %q", file.Module.Mod.Path)
}
// The toolchain exists only if 'toolchain' version > 'go' version.
// If 'toolchain' version <= 'go' version, `go mod tidy` will remove 'toolchain' version from go.mod.
if file.Toolchain != nil && file.Toolchain.Name != "" {
return parseGoVersion(file.Toolchain.Name)
}
if file.Go != nil && file.Go.Version != "" {
return file.Go.Version
}
return parseGoVersion(values[goenv.GOVERSION])
}
func parseGoVersion(v string) string {
raw := strings.TrimPrefix(v, "go")
// prerelease version (ex: go1.24rc1)
idx := strings.IndexFunc(raw, func(r rune) bool {
return (r < '0' || r > '9') && r != '.'
})
if idx != -1 {
raw = raw[:idx]
}
return raw
}
func parseGoMod(goMod string) (*modfile.File, error) {
raw, err := os.ReadFile(filepath.Clean(goMod))
if err != nil {
return nil, fmt.Errorf("reading go.mod file: %w", err)
}
return modfile.Parse("go.mod", raw, nil)
}
func detectGoModFallback(ctx context.Context) string {
info, err := gomod.GetModuleInfo(ctx)
if err != nil {
return ""
}
wd, err := os.Getwd()
if err != nil {
return ""
}
slices.SortFunc(info, func(a, b gomod.ModInfo) int {
return cmp.Compare(len(b.Path), len(a.Path))
})
goMod := info[0]
for _, m := range info {
if !strings.HasPrefix(wd, m.Dir) {
continue
}
goMod = m
break
}
return goMod.GoMod
}
================================================
FILE: pkg/config/config_test.go
================================================
package config
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestIsGoGreaterThanOrEqual(t *testing.T) {
testCases := []struct {
desc string
current string
limit string
assert assert.BoolAssertionFunc
}{
{
desc: "current (with minor.major) lower than limit",
current: "go1.21",
limit: "1.22",
assert: assert.False,
},
{
desc: "current (with 0 patch) lower than limit",
current: "go1.21.0",
limit: "1.22",
assert: assert.False,
},
{
desc: "current (current with multiple patches) lower than limit",
current: "go1.21.6",
limit: "1.22",
assert: assert.False,
},
{
desc: "current lower than limit (with minor.major)",
current: "go1.22",
limit: "1.22",
assert: assert.True,
},
{
desc: "current lower than limit (with 0 patch)",
current: "go1.22.0",
limit: "1.22",
assert: assert.True,
},
{
desc: "current lower than limit (current with multiple patches)",
current: "go1.22.6",
limit: "1.22",
assert: assert.True,
},
{
desc: "current greater than limit",
current: "go1.23.0",
limit: "1.22",
assert: assert.True,
},
{
desc: "current with no prefix",
current: "1.22",
limit: "1.22",
assert: assert.True,
},
{
desc: "invalid current value",
current: "go",
limit: "1.22",
assert: assert.False,
},
{
desc: "invalid limit value",
current: "go1.22",
limit: "go",
assert: assert.False,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
test.assert(t, IsGoGreaterThanOrEqual(test.current, test.limit))
})
}
}
func Test_parseGoVersion(t *testing.T) {
testCases := []struct {
desc string
version string
expected string
}{
{
desc: "empty version",
version: "",
expected: "",
},
{
desc: "no prefixed version",
version: "1.23.0",
expected: "1.23.0",
},
{
desc: "semver version",
version: "go1.23.0",
expected: "1.23.0",
},
{
desc: "family version",
version: "go1.23",
expected: "1.23",
},
{
desc: "prerelease version",
version: "go1.24rc1",
expected: "1.24",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
v := parseGoVersion(test.version)
assert.Equal(t, test.expected, v)
})
}
}
================================================
FILE: pkg/config/formatters.go
================================================
package config
import (
"fmt"
"slices"
)
type Formatters struct {
Enable []string `mapstructure:"enable"`
Settings FormatterSettings `mapstructure:"settings"`
Exclusions FormatterExclusions `mapstructure:"exclusions"`
}
func (f *Formatters) Validate() error {
for _, n := range f.Enable {
if !slices.Contains(getAllFormatterNames(), n) {
return fmt.Errorf("%s is not a formatter", n)
}
}
return nil
}
type FormatterExclusions struct {
Generated string `mapstructure:"generated"`
Paths []string `mapstructure:"paths"`
WarnUnused bool `mapstructure:"warn-unused"`
}
================================================
FILE: pkg/config/formatters_settings.go
================================================
package config
var defaultFormatterSettings = FormatterSettings{
GoFmt: GoFmtSettings{
Simplify: true,
},
Gci: GciSettings{
Sections: []string{"standard", "default"},
},
GoLines: GoLinesSettings{
MaxLen: 100,
TabLen: 4,
ReformatTags: true,
ChainSplitDots: true,
},
}
type FormatterSettings struct {
Gci GciSettings `mapstructure:"gci"`
GoFmt GoFmtSettings `mapstructure:"gofmt"`
GoFumpt GoFumptSettings `mapstructure:"gofumpt"`
GoImports GoImportsSettings `mapstructure:"goimports"`
GoLines GoLinesSettings `mapstructure:"golines"`
}
type GciSettings struct {
Sections []string `mapstructure:"sections"`
NoInlineComments bool `mapstructure:"no-inline-comments"`
NoPrefixComments bool `mapstructure:"no-prefix-comments"`
CustomOrder bool `mapstructure:"custom-order"`
NoLexOrder bool `mapstructure:"no-lex-order"`
}
type GoFmtSettings struct {
Simplify bool `mapstructure:"simplify"`
RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"`
}
type GoFmtRewriteRule struct {
Pattern string `mapstructure:"pattern"`
Replacement string `mapstructure:"replacement"`
}
type GoFumptSettings struct {
ModulePath string `mapstructure:"module-path"`
ExtraRules bool `mapstructure:"extra-rules"`
LangVersion string `mapstructure:"-"`
}
type GoImportsSettings struct {
LocalPrefixes []string `mapstructure:"local-prefixes"`
}
type GoLinesSettings struct {
MaxLen int `mapstructure:"max-len"`
TabLen int `mapstructure:"tab-len"`
ShortenComments bool `mapstructure:"shorten-comments"`
ReformatTags bool `mapstructure:"reformat-tags"`
ChainSplitDots bool `mapstructure:"chain-split-dots"`
}
================================================
FILE: pkg/config/issues.go
================================================
package config
type Issues struct {
MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"`
MaxSameIssues int `mapstructure:"max-same-issues"`
UniqByLine bool `mapstructure:"uniq-by-line"`
DiffFromRevision string `mapstructure:"new-from-rev"`
DiffFromMergeBase string `mapstructure:"new-from-merge-base"`
DiffPatchFilePath string `mapstructure:"new-from-patch"`
WholeFiles bool `mapstructure:"whole-files"`
Diff bool `mapstructure:"new"`
NeedFix bool `mapstructure:"fix"`
}
================================================
FILE: pkg/config/linters.go
================================================
package config
import (
"fmt"
"slices"
)
const (
GroupStandard = "standard"
GroupAll = "all"
GroupNone = "none"
GroupFast = "fast"
)
type Linters struct {
Default string `mapstructure:"default"`
Enable []string `mapstructure:"enable"`
Disable []string `mapstructure:"disable"`
FastOnly bool `mapstructure:"fast-only"` // Flag only option.
Settings LintersSettings `mapstructure:"settings"`
Exclusions LinterExclusions `mapstructure:"exclusions"`
}
func (l *Linters) Validate() error {
validators := []func() error{
l.Exclusions.Validate,
l.validateNoFormatters,
}
for _, v := range validators {
if err := v(); err != nil {
return err
}
}
return nil
}
func (l *Linters) validateNoFormatters() error {
for _, n := range slices.Concat(l.Enable, l.Disable) {
if slices.Contains(getAllFormatterNames(), n) {
return fmt.Errorf("%s is a formatter", n)
}
}
return nil
}
func getAllFormatterNames() []string {
return []string{"gci", "gofmt", "gofumpt", "goimports", "golines", "swaggo"}
}
================================================
FILE: pkg/config/linters_exclusions.go
================================================
package config
import (
"fmt"
"slices"
)
const (
GeneratedModeLax = "lax"
GeneratedModeStrict = "strict"
GeneratedModeDisable = "disable"
)
const (
ExclusionPresetComments = "comments"
ExclusionPresetStdErrorHandling = "std-error-handling"
ExclusionPresetCommonFalsePositives = "common-false-positives"
ExclusionPresetLegacy = "legacy"
)
const excludeRuleMinConditionsCount = 2
type LinterExclusions struct {
Generated string `mapstructure:"generated"`
WarnUnused bool `mapstructure:"warn-unused"`
Presets []string `mapstructure:"presets"`
Rules []ExcludeRule `mapstructure:"rules"`
Paths []string `mapstructure:"paths"`
PathsExcept []string `mapstructure:"paths-except"`
}
func (e *LinterExclusions) Validate() error {
for i, rule := range e.Rules {
if err := rule.Validate(); err != nil {
return fmt.Errorf("error in exclude rule #%d: %w", i, err)
}
}
allPresets := []string{
ExclusionPresetComments,
ExclusionPresetStdErrorHandling,
ExclusionPresetCommonFalsePositives,
ExclusionPresetLegacy,
}
for _, preset := range e.Presets {
if !slices.Contains(allPresets, preset) {
return fmt.Errorf("invalid preset: %s", preset)
}
}
return nil
}
type ExcludeRule struct {
BaseRule `mapstructure:",squash"`
}
func (e *ExcludeRule) Validate() error {
return e.BaseRule.Validate(excludeRuleMinConditionsCount)
}
================================================
FILE: pkg/config/linters_exclusions_test.go
================================================
package config
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestLinterExclusions_Validate(t *testing.T) {
testCases := []struct {
desc string
exclusions *LinterExclusions
}{
{
desc: "empty configuration",
exclusions: &LinterExclusions{},
},
{
desc: "valid preset",
exclusions: &LinterExclusions{
Presets: []string{ExclusionPresetComments},
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.exclusions.Validate()
require.NoError(t, err)
})
}
}
func TestLinterExclusions_Validate_error(t *testing.T) {
testCases := []struct {
desc string
exclusions *LinterExclusions
expected string
}{
{
desc: "invalid preset name",
exclusions: &LinterExclusions{
Presets: []string{"foo"},
},
expected: "invalid preset: foo",
},
{
desc: "invalid rule: empty rule",
exclusions: &LinterExclusions{
Rules: []ExcludeRule{{BaseRule: BaseRule{}}},
},
expected: "error in exclude rule #0: at least 2 of (text, source, path[-except], linters) should be set",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.exclusions.Validate()
require.EqualError(t, err, test.expected)
})
}
}
================================================
FILE: pkg/config/linters_settings.go
================================================
package config
import (
"errors"
"fmt"
"runtime"
)
var defaultLintersSettings = LintersSettings{
FormatterSettings: defaultFormatterSettings,
Asasalint: AsasalintSettings{
UseBuiltinExclusions: true,
},
Decorder: DecorderSettings{
DecOrder: []string{"type", "const", "var", "func"},
DisableDecNumCheck: true,
DisableDecOrderCheck: true,
DisableInitFuncFirstCheck: true,
},
Dogsled: DogsledSettings{
MaxBlankIdentifiers: 2,
},
Dupl: DuplSettings{
Threshold: 150,
},
EmbeddedStructFieldCheck: EmbeddedStructFieldCheckSettings{
EmptyLine: true,
},
ErrorLint: ErrorLintSettings{
Errorf: true,
ErrorfMulti: true,
Asserts: true,
Comparison: true,
},
Exhaustive: ExhaustiveSettings{
Check: []string{"switch"},
DefaultSignifiesExhaustive: false,
IgnoreEnumMembers: "",
PackageScopeOnly: false,
ExplicitExhaustiveMap: false,
ExplicitExhaustiveSwitch: false,
},
Forbidigo: ForbidigoSettings{
ExcludeGodocExamples: true,
},
FuncOrder: FuncOrderSettings{
Constructor: true,
StructMethod: true,
},
Funlen: FunlenSettings{
IgnoreComments: true,
},
GoChecksumType: GoChecksumTypeSettings{
DefaultSignifiesExhaustive: true,
},
Gocognit: GocognitSettings{
MinComplexity: 30,
},
Goconst: GoConstSettings{
MatchWithConstants: true,
MinStringLen: 3,
MinOccurrencesCount: 3,
NumberMin: 3,
NumberMax: 3,
IgnoreCalls: true,
},
Gocritic: GoCriticSettings{
SettingsPerCheck: map[string]GoCriticCheckSettings{},
},
Gocyclo: GoCycloSettings{
MinComplexity: 30,
},
Godox: GodoxSettings{
Keywords: []string{},
},
Godot: GodotSettings{
Scope: "declarations",
Period: true,
},
Gosec: GoSecSettings{
Concurrency: runtime.NumCPU(),
},
Gosmopolitan: GosmopolitanSettings{
AllowTimeLocal: false,
EscapeHatches: []string{},
WatchForScripts: []string{"Han"},
},
Inamedparam: INamedParamSettings{
SkipSingleParam: false,
},
InterfaceBloat: InterfaceBloatSettings{
Max: 10,
},
Lll: LllSettings{
LineLength: 120,
TabWidth: 1,
},
LoggerCheck: LoggerCheckSettings{
Kitlog: true,
Klog: true,
Logr: true,
Slog: true,
Zap: true,
RequireStringKey: false,
NoPrintfLike: false,
Rules: nil,
},
MaintIdx: MaintIdxSettings{
Under: 20,
},
Nakedret: NakedretSettings{
MaxFuncLines: 30,
},
Nestif: NestifSettings{
MinComplexity: 5,
},
NoLintLint: NoLintLintSettings{
RequireExplanation: false,
RequireSpecific: false,
AllowUnused: false,
},
PerfSprint: PerfSprintSettings{
IntegerFormat: true,
IntConversion: true,
ErrorFormat: true,
ErrError: false,
ErrorF: true,
StringFormat: true,
SprintF1: true,
StrConcat: true,
BoolFormat: true,
HexFormat: true,
ConcatLoop: true,
},
Prealloc: PreallocSettings{
Simple: true,
RangeLoops: true,
ForLoops: false,
},
Predeclared: PredeclaredSettings{
Qualified: false,
},
SlogLint: SlogLintSettings{
NoMixedArgs: true,
KVOnly: false,
AttrOnly: false,
NoGlobal: "",
Context: "",
StaticMsg: false,
NoRawKeys: false,
KeyNamingCase: "",
ForbiddenKeys: nil,
ArgsOnSepLines: false,
},
TagAlign: TagAlignSettings{
Align: true,
Sort: true,
Order: nil,
Strict: false,
},
Testpackage: TestpackageSettings{
SkipRegexp: `(export|internal)_test\.go`,
AllowPackages: []string{"main"},
},
Unqueryvet: UnqueryvetSettings{
CheckSQLBuilders: true,
CheckAliasedWildcard: true,
CheckStringConcat: true,
CheckFormatStrings: true,
CheckStringBuilder: true,
CheckSubqueries: true,
SQLBuilders: UnqueryvetSQLBuildersSettings{
Squirrel: true,
GORM: true,
SQLx: true,
Ent: true,
PGX: true,
Bun: true,
SQLBoiler: true,
Jet: true,
},
CheckN1: false,
CheckSQLInjection: false,
CheckTxLeak: false,
},
Unused: UnusedSettings{
FieldWritesAreUses: true,
PostStatementsAreReads: false,
ExportedFieldsAreUsed: true,
ParametersAreUsed: true,
LocalVariablesAreUsed: true,
GeneratedIsUsed: true,
},
UseStdlibVars: UseStdlibVarsSettings{
HTTPMethod: true,
HTTPStatusCode: true,
},
UseTesting: UseTestingSettings{
ContextBackground: false,
ContextTodo: false,
OSChdir: true,
OSMkdirTemp: true,
OSSetenv: true,
OSTempDir: false,
OSCreateTemp: true,
},
Varnamelen: VarnamelenSettings{
MaxDistance: 5,
MinNameLength: 3,
},
WSL: WSLv4Settings{
StrictAppend: true,
AllowAssignAndCallCuddle: true,
AllowAssignAndAnythingCuddle: false,
AllowMultiLineAssignCuddle: true,
ForceCaseTrailingWhitespaceLimit: 0,
AllowTrailingComment: false,
AllowSeparatedLeadingComment: false,
AllowCuddleDeclaration: false,
AllowCuddleWithCalls: []string{"Lock", "RLock"},
AllowCuddleWithRHS: []string{"Unlock", "RUnlock"},
AllowCuddleUsedInBlock: false,
ForceCuddleErrCheckAndAssign: false,
ErrorVariableNames: []string{"err"},
ForceExclusiveShortDeclarations: false,
},
WSLv5: WSLv5Settings{
AllowFirstInBlock: true,
AllowWholeBlock: false,
BranchMaxLines: 2,
CaseMaxLines: 0,
Default: "default",
Enable: nil,
Disable: nil,
},
}
type LintersSettings struct {
FormatterSettings `mapstructure:"-"`
Asasalint AsasalintSettings `mapstructure:"asasalint"`
BiDiChk BiDiChkSettings `mapstructure:"bidichk"`
CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"`
Cyclop CyclopSettings `mapstructure:"cyclop"`
Decorder DecorderSettings `mapstructure:"decorder"`
Depguard DepGuardSettings `mapstructure:"depguard"`
Dogsled DogsledSettings `mapstructure:"dogsled"`
Dupl DuplSettings `mapstructure:"dupl"`
DupWord DupWordSettings `mapstructure:"dupword"`
EmbeddedStructFieldCheck EmbeddedStructFieldCheckSettings `mapstructure:"embeddedstructfieldcheck"`
Errcheck ErrcheckSettings `mapstructure:"errcheck"`
ErrChkJSON ErrChkJSONSettings `mapstructure:"errchkjson"`
ErrorLint ErrorLintSettings `mapstructure:"errorlint"`
Exhaustive ExhaustiveSettings `mapstructure:"exhaustive"`
Exhaustruct ExhaustructSettings `mapstructure:"exhaustruct"`
Fatcontext FatcontextSettings `mapstructure:"fatcontext"`
Forbidigo ForbidigoSettings `mapstructure:"forbidigo"`
FuncOrder FuncOrderSettings `mapstructure:"funcorder"`
Funlen FunlenSettings `mapstructure:"funlen"`
GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"`
Gocognit GocognitSettings `mapstructure:"gocognit"`
GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"`
Goconst GoConstSettings `mapstructure:"goconst"`
Gocritic GoCriticSettings `mapstructure:"gocritic"`
Gocyclo GoCycloSettings `mapstructure:"gocyclo"`
Godoclint GodoclintSettings `mapstructure:"godoclint"`
Godot GodotSettings `mapstructure:"godot"`
Godox GodoxSettings `mapstructure:"godox"`
Goheader GoHeaderSettings `mapstructure:"goheader"`
GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"`
Gomodguard GoModGuardSettings `mapstructure:"gomodguard"`
Gosec GoSecSettings `mapstructure:"gosec"`
Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"`
Unqueryvet UnqueryvetSettings `mapstructure:"unqueryvet"`
Govet GovetSettings `mapstructure:"govet"`
Grouper GrouperSettings `mapstructure:"grouper"`
Iface IfaceSettings `mapstructure:"iface"`
ImportAs ImportAsSettings `mapstructure:"importas"`
Inamedparam INamedParamSettings `mapstructure:"inamedparam"`
Ineffassign IneffassignSettings `mapstructure:"ineffassign"`
InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"`
IotaMixing IotaMixingSettings `mapstructure:"iotamixing"`
Ireturn IreturnSettings `mapstructure:"ireturn"`
Lll LllSettings `mapstructure:"lll"`
LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"`
MaintIdx MaintIdxSettings `mapstructure:"maintidx"`
Makezero MakezeroSettings `mapstructure:"makezero"`
Misspell MisspellSettings `mapstructure:"misspell"`
Mnd MndSettings `mapstructure:"mnd"`
Modernize ModernizeSettings `mapstructure:"modernize"`
MustTag MustTagSettings `mapstructure:"musttag"`
Nakedret NakedretSettings `mapstructure:"nakedret"`
Nestif NestifSettings `mapstructure:"nestif"`
NilNil NilNilSettings `mapstructure:"nilnil"`
Nlreturn NlreturnSettings `mapstructure:"nlreturn"`
NoLintLint NoLintLintSettings `mapstructure:"nolintlint"`
NoNamedReturns NoNamedReturnsSettings `mapstructure:"nonamedreturns"`
ParallelTest ParallelTestSettings `mapstructure:"paralleltest"`
PerfSprint PerfSprintSettings `mapstructure:"perfsprint"`
Prealloc PreallocSettings `mapstructure:"prealloc"`
Predeclared PredeclaredSettings `mapstructure:"predeclared"`
Promlinter PromlinterSettings `mapstructure:"promlinter"`
ProtoGetter ProtoGetterSettings `mapstructure:"protogetter"`
Reassign ReassignSettings `mapstructure:"reassign"`
Recvcheck RecvcheckSettings `mapstructure:"recvcheck"`
Revive ReviveSettings `mapstructure:"revive"`
RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"`
SlogLint SlogLintSettings `mapstructure:"sloglint"`
Spancheck SpancheckSettings `mapstructure:"spancheck"`
Staticcheck StaticCheckSettings `mapstructure:"staticcheck"`
TagAlign TagAlignSettings `mapstructure:"tagalign"`
Tagliatelle TagliatelleSettings `mapstructure:"tagliatelle"`
Testifylint TestifylintSettings `mapstructure:"testifylint"`
Testpackage TestpackageSettings `mapstructure:"testpackage"`
Thelper ThelperSettings `mapstructure:"thelper"`
Unconvert UnconvertSettings `mapstructure:"unconvert"`
Unparam UnparamSettings `mapstructure:"unparam"`
Unused UnusedSettings `mapstructure:"unused"`
UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"`
UseTesting UseTestingSettings `mapstructure:"usetesting"`
Varnamelen VarnamelenSettings `mapstructure:"varnamelen"`
Whitespace WhitespaceSettings `mapstructure:"whitespace"`
Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"`
WSL WSLv4Settings `mapstructure:"wsl"` // Deprecated: use WSLv5 instead.
WSLv5 WSLv5Settings `mapstructure:"wsl_v5"`
Custom map[string]CustomLinterSettings `mapstructure:"custom"`
}
func (s *LintersSettings) Validate() error {
if err := s.Govet.Validate(); err != nil {
return err
}
for name, settings := range s.Custom {
if err := settings.Validate(); err != nil {
return fmt.Errorf("custom linter %q: %w", name, err)
}
}
return nil
}
type AsasalintSettings struct {
Exclude []string `mapstructure:"exclude"`
UseBuiltinExclusions bool `mapstructure:"use-builtin-exclusions"`
}
type BiDiChkSettings struct {
LeftToRightEmbedding bool `mapstructure:"left-to-right-embedding"`
RightToLeftEmbedding bool `mapstructure:"right-to-left-embedding"`
PopDirectionalFormatting bool `mapstructure:"pop-directional-formatting"`
LeftToRightOverride bool `mapstructure:"left-to-right-override"`
RightToLeftOverride bool `mapstructure:"right-to-left-override"`
LeftToRightIsolate bool `mapstructure:"left-to-right-isolate"`
RightToLeftIsolate bool `mapstructure:"right-to-left-isolate"`
FirstStrongIsolate bool `mapstructure:"first-strong-isolate"`
PopDirectionalIsolate bool `mapstructure:"pop-directional-isolate"`
}
type CopyLoopVarSettings struct {
CheckAlias bool `mapstructure:"check-alias"`
}
type CyclopSettings struct {
MaxComplexity int `mapstructure:"max-complexity"`
PackageAverage float64 `mapstructure:"package-average"`
}
type DepGuardSettings struct {
Rules map[string]*DepGuardList `mapstructure:"rules"`
}
type DepGuardList struct {
ListMode string `mapstructure:"list-mode"`
Files []string `mapstructure:"files"`
Allow []string `mapstructure:"allow"`
Deny []DepGuardDeny `mapstructure:"deny"`
}
type DepGuardDeny struct {
Pkg string `mapstructure:"pkg"`
Desc string `mapstructure:"desc"`
}
type DecorderSettings struct {
DecOrder []string `mapstructure:"dec-order"`
IgnoreUnderscoreVars bool `mapstructure:"ignore-underscore-vars"`
DisableDecNumCheck bool `mapstructure:"disable-dec-num-check"`
DisableTypeDecNumCheck bool `mapstructure:"disable-type-dec-num-check"`
DisableConstDecNumCheck bool `mapstructure:"disable-const-dec-num-check"`
DisableVarDecNumCheck bool `mapstructure:"disable-var-dec-num-check"`
DisableDecOrderCheck bool `mapstructure:"disable-dec-order-check"`
DisableInitFuncFirstCheck bool `mapstructure:"disable-init-func-first-check"`
}
type DogsledSettings struct {
MaxBlankIdentifiers int `mapstructure:"max-blank-identifiers"`
}
type DuplSettings struct {
Threshold int `mapstructure:"threshold"`
}
type DupWordSettings struct {
Keywords []string `mapstructure:"keywords"`
Ignore []string `mapstructure:"ignore"`
CommentsOnly bool `mapstructure:"comments-only"`
}
type EmbeddedStructFieldCheckSettings struct {
ForbidMutex bool `mapstructure:"forbid-mutex"`
EmptyLine bool `mapstructure:"empty-line"`
}
type ErrcheckSettings struct {
DisableDefaultExclusions bool `mapstructure:"disable-default-exclusions"`
CheckTypeAssertions bool `mapstructure:"check-type-assertions"`
CheckAssignToBlank bool `mapstructure:"check-blank"`
ExcludeFunctions []string `mapstructure:"exclude-functions"`
Verbose bool `mapstructure:"verbose"`
}
type ErrChkJSONSettings struct {
CheckErrorFreeEncoding bool `mapstructure:"check-error-free-encoding"`
ReportNoExported bool `mapstructure:"report-no-exported"`
}
type ErrorLintSettings struct {
Errorf bool `mapstructure:"errorf"`
ErrorfMulti bool `mapstructure:"errorf-multi"`
Asserts bool `mapstructure:"asserts"`
Comparison bool `mapstructure:"comparison"`
AllowedErrors []ErrorLintAllowPair `mapstructure:"allowed-errors"`
AllowedErrorsWildcard []ErrorLintAllowPair `mapstructure:"allowed-errors-wildcard"`
}
type ErrorLintAllowPair struct {
Err string `mapstructure:"err"`
Fun string `mapstructure:"fun"`
}
type ExhaustiveSettings struct {
Check []string `mapstructure:"check"`
DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"`
IgnoreEnumMembers string `mapstructure:"ignore-enum-members"`
IgnoreEnumTypes string `mapstructure:"ignore-enum-types"`
PackageScopeOnly bool `mapstructure:"package-scope-only"`
ExplicitExhaustiveMap bool `mapstructure:"explicit-exhaustive-map"`
ExplicitExhaustiveSwitch bool `mapstructure:"explicit-exhaustive-switch"`
DefaultCaseRequired bool `mapstructure:"default-case-required"`
}
type ExhaustructSettings struct {
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
AllowEmpty bool `mapstructure:"allow-empty"`
AllowEmptyRx []string `mapstructure:"allow-empty-rx"`
AllowEmptyReturns bool `mapstructure:"allow-empty-returns"`
AllowEmptyDeclarations bool `mapstructure:"allow-empty-declarations"`
}
type FatcontextSettings struct {
CheckStructPointers bool `mapstructure:"check-struct-pointers"`
}
type ForbidigoSettings struct {
Forbid []ForbidigoPattern `mapstructure:"forbid"`
ExcludeGodocExamples bool `mapstructure:"exclude-godoc-examples"`
AnalyzeTypes bool `mapstructure:"analyze-types"`
}
type ForbidigoPattern struct {
Pattern string `yaml:"p" mapstructure:"pattern"`
Package string `yaml:"pkg,omitempty" mapstructure:"pkg,omitempty"`
Msg string `yaml:"msg,omitempty" mapstructure:"msg,omitempty"`
}
type FuncOrderSettings struct {
Constructor bool `mapstructure:"constructor,omitempty"`
StructMethod bool `mapstructure:"struct-method,omitempty"`
Alphabetical bool `mapstructure:"alphabetical,omitempty"`
}
type FunlenSettings struct {
Lines int `mapstructure:"lines"`
Statements int `mapstructure:"statements"`
IgnoreComments bool `mapstructure:"ignore-comments"`
}
type GinkgoLinterSettings struct {
SuppressLenAssertion bool `mapstructure:"suppress-len-assertion"`
SuppressNilAssertion bool `mapstructure:"suppress-nil-assertion"`
SuppressErrAssertion bool `mapstructure:"suppress-err-assertion"`
SuppressCompareAssertion bool `mapstructure:"suppress-compare-assertion"`
SuppressAsyncAssertion bool `mapstructure:"suppress-async-assertion"`
SuppressTypeCompareWarning bool `mapstructure:"suppress-type-compare-assertion"`
ForbidFocusContainer bool `mapstructure:"forbid-focus-container"`
AllowHaveLenZero bool `mapstructure:"allow-havelen-zero"`
ForceExpectTo bool `mapstructure:"force-expect-to"`
ValidateAsyncIntervals bool `mapstructure:"validate-async-intervals"`
ForbidSpecPollution bool `mapstructure:"forbid-spec-pollution"`
ForceSucceedForFuncs bool `mapstructure:"force-succeed"`
ForceAssertionDescription bool `mapstructure:"force-assertion-description"`
ForeToNot bool `mapstructure:"force-tonot"`
}
type GoChecksumTypeSettings struct {
DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"`
IncludeSharedInterfaces bool `mapstructure:"include-shared-interfaces"`
}
type GocognitSettings struct {
MinComplexity int `mapstructure:"min-complexity"`
}
type GoConstSettings struct {
IgnoreStringValues []string `mapstructure:"ignore-string-values"`
MatchWithConstants bool `mapstructure:"match-constant"`
MinStringLen int `mapstructure:"min-len"`
MinOccurrencesCount int `mapstructure:"min-occurrences"`
ParseNumbers bool `mapstructure:"numbers"`
NumberMin int `mapstructure:"min"`
NumberMax int `mapstructure:"max"`
IgnoreCalls bool `mapstructure:"ignore-calls"`
FindDuplicates bool `mapstructure:"find-duplicates"`
EvalConstExpressions bool `mapstructure:"eval-const-expressions"`
// Deprecated: use IgnoreStringValues instead.
IgnoreStrings string `mapstructure:"ignore-strings"`
}
type GoCriticSettings struct {
Go string `mapstructure:"-"`
DisableAll bool `mapstructure:"disable-all"`
EnabledChecks []string `mapstructure:"enabled-checks"`
EnableAll bool `mapstructure:"enable-all"`
DisabledChecks []string `mapstructure:"disabled-checks"`
EnabledTags []string `mapstructure:"enabled-tags"`
DisabledTags []string `mapstructure:"disabled-tags"`
SettingsPerCheck map[string]GoCriticCheckSettings `mapstructure:"settings"`
}
type GoCriticCheckSettings map[string]any
type GoCycloSettings struct {
MinComplexity int `mapstructure:"min-complexity"`
}
type GodoclintSettings struct {
Default *string `mapstructure:"default"`
Enable []string `mapstructure:"enable"`
Disable []string `mapstructure:"disable"`
Options struct {
MaxLen struct {
Length *uint `mapstructure:"length"`
} `mapstructure:"max-len"`
RequireDoc struct {
IgnoreExported *bool `mapstructure:"ignore-exported"`
IgnoreUnexported *bool `mapstructure:"ignore-unexported"`
} `mapstructure:"require-doc"`
StartWithName struct {
IncludeUnexported *bool `mapstructure:"include-unexported"`
} `mapstructure:"start-with-name"`
} `mapstructure:"options"`
}
type GodotSettings struct {
Scope string `mapstructure:"scope"`
Exclude []string `mapstructure:"exclude"`
Capital bool `mapstructure:"capital"`
Period bool `mapstructure:"period"`
}
type GodoxSettings struct {
Keywords []string `mapstructure:"keywords"`
}
type GoHeaderSettings struct {
Values map[string]map[string]string `mapstructure:"values"`
Template string `mapstructure:"template"`
TemplatePath string `mapstructure:"template-path"`
}
type GoModDirectivesSettings struct {
ReplaceAllowList []string `mapstructure:"replace-allow-list"`
ReplaceLocal bool `mapstructure:"replace-local"`
ExcludeForbidden bool `mapstructure:"exclude-forbidden"`
RetractAllowNoExplanation bool `mapstructure:"retract-allow-no-explanation"`
ToolchainForbidden bool `mapstructure:"toolchain-forbidden"`
ToolchainPattern string `mapstructure:"toolchain-pattern"`
ToolForbidden bool `mapstructure:"tool-forbidden"`
GoDebugForbidden bool `mapstructure:"go-debug-forbidden"`
GoVersionPattern string `mapstructure:"go-version-pattern"`
CheckModulePath bool `mapstructure:"check-module-path"`
}
type GoModGuardSettings struct {
Allowed GoModGuardAllowed `mapstructure:"allowed"`
Blocked GoModGuardBlocked `mapstructure:"blocked"`
}
type GoModGuardAllowed struct {
Modules []string `mapstructure:"modules"`
Domains []string `mapstructure:"domains"`
}
type GoModGuardBlocked struct {
Modules []map[string]GoModGuardModule `mapstructure:"modules"`
Versions []map[string]GoModGuardVersion `mapstructure:"versions"`
LocalReplaceDirectives bool `mapstructure:"local-replace-directives"`
}
type GoModGuardModule struct {
Recommendations []string `mapstructure:"recommendations"`
Reason string `mapstructure:"reason"`
}
type GoModGuardVersion struct {
Version string `mapstructure:"version"`
Reason string `mapstructure:"reason"`
}
type GoSecSettings struct {
Includes []string `mapstructure:"includes"`
Excludes []string `mapstructure:"excludes"`
Severity string `mapstructure:"severity"`
Confidence string `mapstructure:"confidence"`
Config map[string]any `mapstructure:"config"`
Concurrency int `mapstructure:"concurrency"`
}
type GosmopolitanSettings struct {
AllowTimeLocal bool `mapstructure:"allow-time-local"`
EscapeHatches []string `mapstructure:"escape-hatches"`
WatchForScripts []string `mapstructure:"watch-for-scripts"`
}
type GovetSettings struct {
Go string `mapstructure:"-"`
Enable []string `mapstructure:"enable"`
Disable []string `mapstructure:"disable"`
EnableAll bool `mapstructure:"enable-all"`
DisableAll bool `mapstructure:"disable-all"`
Settings map[string]map[string]any `mapstructure:"settings"`
}
func (cfg *GovetSettings) Validate() error {
if cfg.EnableAll && cfg.DisableAll {
return errors.New("govet: enable-all and disable-all can't be combined")
}
if cfg.EnableAll && len(cfg.Enable) != 0 {
return errors.New("govet: enable-all and enable can't be combined")
}
if cfg.DisableAll && len(cfg.Disable) != 0 {
return errors.New("govet: disable-all and disable can't be combined")
}
return nil
}
type GrouperSettings struct {
ConstRequireSingleConst bool `mapstructure:"const-require-single-const"`
ConstRequireGrouping bool `mapstructure:"const-require-grouping"`
ImportRequireSingleImport bool `mapstructure:"import-require-single-import"`
ImportRequireGrouping bool `mapstructure:"import-require-grouping"`
TypeRequireSingleType bool `mapstructure:"type-require-single-type"`
TypeRequireGrouping bool `mapstructure:"type-require-grouping"`
VarRequireSingleVar bool `mapstructure:"var-require-single-var"`
VarRequireGrouping bool `mapstructure:"var-require-grouping"`
}
type IfaceSettings struct {
Enable []string `mapstructure:"enable"`
Settings map[string]map[string]any `mapstructure:"settings"`
}
type ImportAsSettings struct {
Alias []ImportAsAlias `mapstructure:"alias"`
NoUnaliased bool `mapstructure:"no-unaliased"`
NoExtraAliases bool `mapstructure:"no-extra-aliases"`
}
type ImportAsAlias struct {
Pkg string `mapstructure:"pkg"`
Alias string `mapstructure:"alias"`
}
type INamedParamSettings struct {
SkipSingleParam bool `mapstructure:"skip-single-param"`
}
type IneffassignSettings struct {
CheckEscapingErrors bool `mapstructure:"check-escaping-errors"`
}
type InterfaceBloatSettings struct {
Max int `mapstructure:"max"`
}
type IotaMixingSettings struct {
ReportIndividual bool `mapstructure:"report-individual"`
}
type IreturnSettings struct {
Allow []string `mapstructure:"allow"`
Reject []string `mapstructure:"reject"`
}
type LllSettings struct {
LineLength int `mapstructure:"line-length"`
TabWidth int `mapstructure:"tab-width"`
}
type LoggerCheckSettings struct {
Kitlog bool `mapstructure:"kitlog"`
Klog bool `mapstructure:"klog"`
Logr bool `mapstructure:"logr"`
Slog bool `mapstructure:"slog"`
Zap bool `mapstructure:"zap"`
RequireStringKey bool `mapstructure:"require-string-key"`
NoPrintfLike bool `mapstructure:"no-printf-like"`
Rules []string `mapstructure:"rules"`
}
type MaintIdxSettings struct {
Under int `mapstructure:"under"`
}
type MakezeroSettings struct {
Always bool `mapstructure:"always"`
}
type MisspellSettings struct {
Mode string `mapstructure:"mode"`
Locale string `mapstructure:"locale"`
ExtraWords []MisspellExtraWords `mapstructure:"extra-words"`
IgnoreRules []string `mapstructure:"ignore-rules"`
}
type MisspellExtraWords struct {
Typo string `mapstructure:"typo"`
Correction string `mapstructure:"correction"`
}
type MustTagSettings struct {
Functions []MustTagFunction `mapstructure:"functions"`
}
type MustTagFunction struct {
Name string `mapstructure:"name"`
Tag string `mapstructure:"tag"`
ArgPos int `mapstructure:"arg-pos"`
}
type NakedretSettings struct {
MaxFuncLines uint `mapstructure:"max-func-lines"`
}
type NestifSettings struct {
MinComplexity int `mapstructure:"min-complexity"`
}
type NilNilSettings struct {
OnlyTwo *bool `mapstructure:"only-two"`
DetectOpposite bool `mapstructure:"detect-opposite"`
CheckedTypes []string `mapstructure:"checked-types"`
}
type NlreturnSettings struct {
BlockSize int `mapstructure:"block-size"`
}
type MndSettings struct {
Checks []string `mapstructure:"checks"`
IgnoredNumbers []string `mapstructure:"ignored-numbers"`
IgnoredFiles []string `mapstructure:"ignored-files"`
IgnoredFunctions []string `mapstructure:"ignored-functions"`
}
type ModernizeSettings struct {
Disable []string `mapstructure:"disable"`
}
type NoLintLintSettings struct {
RequireExplanation bool `mapstructure:"require-explanation"`
RequireSpecific bool `mapstructure:"require-specific"`
AllowNoExplanation []string `mapstructure:"allow-no-explanation"`
AllowUnused bool `mapstructure:"allow-unused"`
}
type NoNamedReturnsSettings struct {
ReportErrorInDefer bool `mapstructure:"report-error-in-defer"`
}
type ParallelTestSettings struct {
Go string `mapstructure:"-"`
IgnoreMissing bool `mapstructure:"ignore-missing"`
IgnoreMissingSubtests bool `mapstructure:"ignore-missing-subtests"`
}
type PerfSprintSettings struct {
IntegerFormat bool `mapstructure:"integer-format"`
IntConversion bool `mapstructure:"int-conversion"`
ErrorFormat bool `mapstructure:"error-format"`
ErrError bool `mapstructure:"err-error"`
ErrorF bool `mapstructure:"errorf"`
StringFormat bool `mapstructure:"string-format"`
SprintF1 bool `mapstructure:"sprintf1"`
StrConcat bool `mapstructure:"strconcat"`
BoolFormat bool `mapstructure:"bool-format"`
HexFormat bool `mapstructure:"hex-format"`
ConcatLoop bool `mapstructure:"concat-loop"`
LoopOtherOps bool `mapstructure:"loop-other-ops"`
}
type PreallocSettings struct {
Simple bool `mapstructure:"simple"`
RangeLoops bool `mapstructure:"range-loops"`
ForLoops bool `mapstructure:"for-loops"`
}
type PredeclaredSettings struct {
Ignore []string `mapstructure:"ignore"`
Qualified bool `mapstructure:"qualified-name"`
}
type PromlinterSettings struct {
Strict bool `mapstructure:"strict"`
DisabledLinters []string `mapstructure:"disabled-linters"`
}
type ProtoGetterSettings struct {
SkipGeneratedBy []string `mapstructure:"skip-generated-by"`
SkipFiles []string `mapstructure:"skip-files"`
SkipAnyGenerated bool `mapstructure:"skip-any-generated"`
ReplaceFirstArgInAppend bool `mapstructure:"replace-first-arg-in-append"`
}
type ReassignSettings struct {
Patterns []string `mapstructure:"patterns"`
}
type RecvcheckSettings struct {
DisableBuiltin bool `mapstructure:"disable-builtin"`
Exclusions []string `mapstructure:"exclusions"`
}
type ReviveSettings struct {
Go string `mapstructure:"-"`
MaxOpenFiles int `mapstructure:"max-open-files"`
Confidence float64 `mapstructure:"confidence"`
Severity string `mapstructure:"severity"`
EnableAllRules bool `mapstructure:"enable-all-rules"`
EnableDefaultRules bool `mapstructure:"enable-default-rules"`
Rules []ReviveRule `mapstructure:"rules"`
ErrorCode int `mapstructure:"error-code"`
WarningCode int `mapstructure:"warning-code"`
Directives []ReviveDirective `mapstructure:"directives"`
}
type ReviveRule struct {
Name string `mapstructure:"name"`
Arguments []any `mapstructure:"arguments"`
Severity string `mapstructure:"severity"`
Disabled bool `mapstructure:"disabled"`
Exclude []string `mapstructure:"exclude"`
}
type ReviveDirective struct {
Name string `mapstructure:"name"`
Severity string `mapstructure:"severity"`
}
type RowsErrCheckSettings struct {
Packages []string `mapstructure:"packages"`
}
type SlogLintSettings struct {
NoMixedArgs bool `mapstructure:"no-mixed-args"`
KVOnly bool `mapstructure:"kv-only"`
AttrOnly bool `mapstructure:"attr-only"`
NoGlobal string `mapstructure:"no-global"`
Context string `mapstructure:"context"`
StaticMsg bool `mapstructure:"static-msg"`
MsgStyle string `mapstructure:"msg-style"`
NoRawKeys bool `mapstructure:"no-raw-keys"`
KeyNamingCase string `mapstructure:"key-naming-case"`
ForbiddenKeys []string `mapstructure:"forbidden-keys"`
ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"`
}
type SpancheckSettings struct {
Checks []string `mapstructure:"checks"`
IgnoreCheckSignatures []string `mapstructure:"ignore-check-signatures"`
ExtraStartSpanSignatures []string `mapstructure:"extra-start-span-signatures"`
}
type StaticCheckSettings struct {
Checks []string `mapstructure:"checks"`
Initialisms []string `mapstructure:"initialisms"` // only for stylecheck
DotImportWhitelist []string `mapstructure:"dot-import-whitelist"` // only for stylecheck
HTTPStatusCodeWhitelist []string `mapstructure:"http-status-code-whitelist"` // only for stylecheck
}
func (s *StaticCheckSettings) HasConfiguration() bool {
return s.Initialisms == nil || s.HTTPStatusCodeWhitelist == nil || s.DotImportWhitelist == nil || s.Checks == nil
}
type TagAlignSettings struct {
Align bool `mapstructure:"align"`
Sort bool `mapstructure:"sort"`
Order []string `mapstructure:"order"`
Strict bool `mapstructure:"strict"`
}
type TagliatelleSettings struct {
Case TagliatelleCase `mapstructure:"case"`
}
type TagliatelleCase struct {
TagliatelleBase `mapstructure:",squash"`
Overrides []TagliatelleOverrides `mapstructure:"overrides"`
}
type TagliatelleOverrides struct {
TagliatelleBase `mapstructure:",squash"`
Package string `mapstructure:"pkg"`
Ignore bool `mapstructure:"ignore"`
}
type TagliatelleBase struct {
Rules map[string]string `mapstructure:"rules"`
ExtendedRules map[string]TagliatelleExtendedRule `mapstructure:"extended-rules"`
UseFieldName bool `mapstructure:"use-field-name"`
IgnoredFields []string `mapstructure:"ignored-fields"`
}
type TagliatelleExtendedRule struct {
Case string `mapstructure:"case"`
ExtraInitialisms bool `mapstructure:"extra-initialisms"`
InitialismOverrides map[string]bool `mapstructure:"initialism-overrides"`
}
type TestifylintSettings struct {
EnableAll bool `mapstructure:"enable-all"`
DisableAll bool `mapstructure:"disable-all"`
EnabledCheckers []string `mapstructure:"enable"`
DisabledCheckers []string `mapstructure:"disable"`
BoolCompare TestifylintBoolCompare `mapstructure:"bool-compare"`
ExpectedActual TestifylintExpectedActual `mapstructure:"expected-actual"`
Formatter TestifylintFormatter `mapstructure:"formatter"`
GoRequire TestifylintGoRequire `mapstructure:"go-require"`
RequireError TestifylintRequireError `mapstructure:"require-error"`
SuiteExtraAssertCall TestifylintSuiteExtraAssertCall `mapstructure:"suite-extra-assert-call"`
}
type TestifylintBoolCompare struct {
IgnoreCustomTypes bool `mapstructure:"ignore-custom-types"`
}
type TestifylintExpectedActual struct {
ExpVarPattern string `mapstructure:"pattern"`
}
type TestifylintFormatter struct {
CheckFormatString *bool `mapstructure:"check-format-string"`
RequireFFuncs bool `mapstructure:"require-f-funcs"`
RequireStringMsg bool `mapstructure:"require-string-msg"`
}
type TestifylintGoRequire struct {
IgnoreHTTPHandlers bool `mapstructure:"ignore-http-handlers"`
}
type TestifylintRequireError struct {
FnPattern string `mapstructure:"fn-pattern"`
}
type TestifylintSuiteExtraAssertCall struct {
Mode string `mapstructure:"mode"`
}
type TestpackageSettings struct {
SkipRegexp string `mapstructure:"skip-regexp"`
AllowPackages []string `mapstructure:"allow-packages"`
}
type ThelperSettings struct {
Test ThelperOptions `mapstructure:"test"`
Fuzz ThelperOptions `mapstructure:"fuzz"`
Benchmark ThelperOptions `mapstructure:"benchmark"`
TB ThelperOptions `mapstructure:"tb"`
}
type ThelperOptions struct {
First *bool `mapstructure:"first"`
Name *bool `mapstructure:"name"`
Begin *bool `mapstructure:"begin"`
}
type UseStdlibVarsSettings struct {
HTTPMethod bool `mapstructure:"http-method"`
HTTPStatusCode bool `mapstructure:"http-status-code"`
TimeWeekday bool `mapstructure:"time-weekday"`
TimeMonth bool `mapstructure:"time-month"`
TimeLayout bool `mapstructure:"time-layout"`
CryptoHash bool `mapstructure:"crypto-hash"`
DefaultRPCPath bool `mapstructure:"default-rpc-path"`
SQLIsolationLevel bool `mapstructure:"sql-isolation-level"`
TLSSignatureScheme bool `mapstructure:"tls-signature-scheme"`
ConstantKind bool `mapstructure:"constant-kind"`
TimeDateMonth bool `mapstructure:"time-date-month"`
}
type UseTestingSettings struct {
ContextBackground bool `mapstructure:"context-background"`
ContextTodo bool `mapstructure:"context-todo"`
OSChdir bool `mapstructure:"os-chdir"`
OSMkdirTemp bool `mapstructure:"os-mkdir-temp"`
OSSetenv bool `mapstructure:"os-setenv"`
OSTempDir bool `mapstructure:"os-temp-dir"`
OSCreateTemp bool `mapstructure:"os-create-temp"`
}
type UnconvertSettings struct {
FastMath bool `mapstructure:"fast-math"`
Safe bool `mapstructure:"safe"`
}
type UnparamSettings struct {
CheckExported bool `mapstructure:"check-exported"`
}
type UnqueryvetSettings struct {
CheckSQLBuilders bool `mapstructure:"check-sql-builders"`
AllowedPatterns []string `mapstructure:"allowed-patterns"`
IgnoredFunctions []string `mapstructure:"ignored-functions"`
CheckAliasedWildcard bool `mapstructure:"check-aliased-wildcard"`
CheckStringConcat bool `mapstructure:"check-string-concat"`
CheckFormatStrings bool `mapstructure:"check-format-strings"`
CheckStringBuilder bool `mapstructure:"check-string-builder"`
CheckSubqueries bool `mapstructure:"check-subqueries"`
CheckN1 bool `mapstructure:"check-n1"`
CheckSQLInjection bool `mapstructure:"check-sql-injection"`
CheckTxLeak bool `mapstructure:"check-tx-leaks"`
SQLBuilders UnqueryvetSQLBuildersSettings `mapstructure:"sql-builders"`
Allow []string `mapstructure:"allow"`
CustomRules []UnqueryvetCustomRule `mapstructure:"custom-rules"`
}
type UnqueryvetSQLBuildersSettings struct {
Squirrel bool `mapstructure:"squirrel"`
GORM bool `mapstructure:"gorm"`
SQLx bool `mapstructure:"sqlx"`
Ent bool `mapstructure:"ent"`
PGX bool `mapstructure:"pgx"`
Bun bool `mapstructure:"bun"`
SQLBoiler bool `mapstructure:"sqlboiler"`
Jet bool `mapstructure:"jet"`
}
type UnqueryvetCustomRule struct {
ID string `mapstructure:"id"`
Pattern string `mapstructure:"pattern"`
Patterns []string `mapstructure:"patterns"`
When string `mapstructure:"when"`
Message string `mapstructure:"message"`
Action string `mapstructure:"action"`
}
type UnusedSettings struct {
FieldWritesAreUses bool `mapstructure:"field-writes-are-uses"`
PostStatementsAreReads bool `mapstructure:"post-statements-are-reads"`
ExportedFieldsAreUsed bool `mapstructure:"exported-fields-are-used"`
ParametersAreUsed bool `mapstructure:"parameters-are-used"`
LocalVariablesAreUsed bool `mapstructure:"local-variables-are-used"`
GeneratedIsUsed bool `mapstructure:"generated-is-used"`
}
type VarnamelenSettings struct {
MaxDistance int `mapstructure:"max-distance"`
MinNameLength int `mapstructure:"min-name-length"`
CheckReceiver bool `mapstructure:"check-receiver"`
CheckReturn bool `mapstructure:"check-return"`
CheckTypeParam bool `mapstructure:"check-type-param"`
IgnoreNames []string `mapstructure:"ignore-names"`
IgnoreTypeAssertOk bool `mapstructure:"ignore-type-assert-ok"`
IgnoreMapIndexOk bool `mapstructure:"ignore-map-index-ok"`
IgnoreChanRecvOk bool `mapstructure:"ignore-chan-recv-ok"`
IgnoreDecls []string `mapstructure:"ignore-decls"`
}
type WhitespaceSettings struct {
MultiIf bool `mapstructure:"multi-if"`
MultiFunc bool `mapstructure:"multi-func"`
}
type WrapcheckSettings struct {
ExtraIgnoreSigs []string `mapstructure:"extra-ignore-sigs"`
IgnoreSigs []string `mapstructure:"ignore-sigs"`
IgnoreSigRegexps []string `mapstructure:"ignore-sig-regexps"`
IgnorePackageGlobs []string `mapstructure:"ignore-package-globs"`
IgnoreInterfaceRegexps []string `mapstructure:"ignore-interface-regexps"`
ReportInternalErrors bool `mapstructure:"report-internal-errors"`
}
// Deprecated: use WSLv5Settings instead.
type WSLv4Settings struct {
StrictAppend bool `mapstructure:"strict-append"`
AllowAssignAndCallCuddle bool `mapstructure:"allow-assign-and-call"`
AllowAssignAndAnythingCuddle bool `mapstructure:"allow-assign-and-anything"`
AllowMultiLineAssignCuddle bool `mapstructure:"allow-multiline-assign"`
ForceCaseTrailingWhitespaceLimit int `mapstructure:"force-case-trailing-whitespace"`
AllowTrailingComment bool `mapstructure:"allow-trailing-comment"`
AllowSeparatedLeadingComment bool `mapstructure:"allow-separated-leading-comment"`
AllowCuddleDeclaration bool `mapstructure:"allow-cuddle-declarations"`
AllowCuddleWithCalls []string `mapstructure:"allow-cuddle-with-calls"`
AllowCuddleWithRHS []string `mapstructure:"allow-cuddle-with-rhs"`
AllowCuddleUsedInBlock bool `mapstructure:"allow-cuddle-used-in-block"`
ForceCuddleErrCheckAndAssign bool `mapstructure:"force-err-cuddling"`
ErrorVariableNames []string `mapstructure:"error-variable-names"`
ForceExclusiveShortDeclarations bool `mapstructure:"force-short-decl-cuddling"`
}
type WSLv5Settings struct {
AllowFirstInBlock bool `mapstructure:"allow-first-in-block"`
AllowWholeBlock bool `mapstructure:"allow-whole-block"`
BranchMaxLines int `mapstructure:"branch-max-lines"`
CaseMaxLines int `mapstructure:"case-max-lines"`
Default string `mapstructure:"default"`
Enable []string `mapstructure:"enable"`
Disable []string `mapstructure:"disable"`
}
// CustomLinterSettings encapsulates the meta-data of a private linter.
type CustomLinterSettings struct {
// Type plugin type.
// It can be `goplugin` or `module`.
Type string `mapstructure:"type"`
// Path to a plugin *.so file that implements the private linter.
// Only for Go plugin system.
Path string `mapstructure:"path"`
// Description describes the purpose of the private linter.
Description string `mapstructure:"description"`
// OriginalURL The URL containing the source code for the private linter.
OriginalURL string `mapstructure:"original-url"`
// Settings plugin settings only work with linterdb.PluginConstructor symbol.
Settings any `mapstructure:"settings"`
}
func (s *CustomLinterSettings) Validate() error {
if s.Type == "module" {
if s.Path != "" {
return errors.New("path not supported with module type")
}
return nil
}
if s.Path == "" {
return errors.New("path is required")
}
return nil
}
================================================
FILE: pkg/config/linters_settings_test.go
================================================
package config
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestLintersSettings_Validate(t *testing.T) {
testCases := []struct {
desc string
settings *LintersSettings
}{
{
desc: "custom linter",
settings: &LintersSettings{
Custom: map[string]CustomLinterSettings{
"example": {
Type: "module",
},
},
},
},
{
desc: "govet",
settings: &LintersSettings{
Govet: GovetSettings{
Enable: []string{"a"},
DisableAll: true,
},
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
assert.NoError(t, err)
})
}
}
func TestLintersSettings_Validate_error(t *testing.T) {
testCases := []struct {
desc string
settings *LintersSettings
expected string
}{
{
desc: "custom linter error",
settings: &LintersSettings{
Custom: map[string]CustomLinterSettings{
"example": {
Type: "module",
Path: "example",
},
},
},
expected: `custom linter "example": path not supported with module type`,
},
{
desc: "govet error",
settings: &LintersSettings{
Govet: GovetSettings{
EnableAll: true,
DisableAll: true,
},
},
expected: "govet: enable-all and disable-all can't be combined",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
assert.EqualError(t, err, test.expected)
})
}
}
func TestCustomLinterSettings_Validate(t *testing.T) {
testCases := []struct {
desc string
settings *CustomLinterSettings
}{
{
desc: "only path",
settings: &CustomLinterSettings{
Path: "example",
},
},
{
desc: "path and type goplugin",
settings: &CustomLinterSettings{
Type: "goplugin",
Path: "example",
},
},
{
desc: "type module",
settings: &CustomLinterSettings{
Type: "module",
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
assert.NoError(t, err)
})
}
}
func TestCustomLinterSettings_Validate_error(t *testing.T) {
testCases := []struct {
desc string
settings *CustomLinterSettings
expected string
}{
{
desc: "missing path",
settings: &CustomLinterSettings{},
expected: "path is required",
},
{
desc: "module and path",
settings: &CustomLinterSettings{
Type: "module",
Path: "example",
},
expected: "path not supported with module type",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
assert.EqualError(t, err, test.expected)
})
}
}
func TestGovetSettings_Validate(t *testing.T) {
testCases := []struct {
desc string
settings *GovetSettings
}{
{
desc: "empty",
settings: &GovetSettings{},
},
{
desc: "disable-all and enable",
settings: &GovetSettings{
Enable: []string{"a"},
DisableAll: true,
},
},
{
desc: "enable-all and disable",
settings: &GovetSettings{
Disable: []string{"a"},
EnableAll: true,
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
assert.NoError(t, err)
})
}
}
func TestGovetSettings_Validate_error(t *testing.T) {
testCases := []struct {
desc string
settings *GovetSettings
expected string
}{
{
desc: "enable-all and disable-all",
settings: &GovetSettings{
EnableAll: true,
DisableAll: true,
},
expected: "govet: enable-all and disable-all can't be combined",
},
{
desc: "enable-all and enable",
settings: &GovetSettings{
EnableAll: true,
Enable: []string{"a"},
},
expected: "govet: enable-all and enable can't be combined",
},
{
desc: "disable-all and disable",
settings: &GovetSettings{
DisableAll: true,
Disable: []string{"a"},
},
expected: "govet: disable-all and disable can't be combined",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
assert.EqualError(t, err, test.expected)
})
}
}
================================================
FILE: pkg/config/loader.go
================================================
package config
import (
"context"
"errors"
"fmt"
"os"
"slices"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
"github.com/golangci/golangci-lint/v2/pkg/goutil"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
var errConfigDisabled = errors.New("config is disabled by --no-config")
const (
modeLinters = "linters"
modeFormatters = "formatters"
)
type LoaderOptions struct {
Config string // Flag only. The path to the golangci config file, as specified with the --config argument.
NoConfig bool // Flag only.
}
type LoadOptions struct {
CheckDeprecation bool
Validation bool
}
type Loader struct {
*BaseLoader
fs *pflag.FlagSet
cfg *Config
mode string
}
func NewLintersLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader {
loader := newLoader(log, v, fs, opts, cfg, args)
loader.mode = modeLinters
return loader
}
func NewFormattersLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader {
loader := newLoader(log, v, fs, opts, cfg, args)
loader.mode = modeFormatters
return loader
}
func newLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader {
return &Loader{
BaseLoader: NewBaseLoader(log, v, opts, cfg, args),
fs: fs,
cfg: cfg,
}
}
func (l *Loader) Load(opts LoadOptions) error {
err := l.BaseLoader.Load()
if err != nil {
return err
}
if l.mode == modeLinters {
l.applyStringSliceHack()
}
if l.cfg.Linters.Exclusions.Generated == "" {
l.cfg.Linters.Exclusions.Generated = GeneratedModeStrict
}
err = l.checkConfigurationVersion()
if err != nil {
return err
}
if !l.cfg.InternalCmdTest {
for _, n := range slices.Concat(l.cfg.Linters.Enable, l.cfg.Linters.Disable) {
if n == "typecheck" {
return fmt.Errorf("%s is not a linter, it cannot be enabled or disabled", n)
}
}
}
l.handleFormatters()
if opts.CheckDeprecation {
err = l.handleDeprecation()
if err != nil {
return err
}
l.handleFormatterDeprecations()
}
l.handleGoVersion()
err = goutil.CheckGoVersion(l.cfg.Run.Go)
if err != nil {
return err
}
l.cfg.basePath, err = fsutils.GetBasePath(context.Background(), l.cfg.Run.RelativePathMode, l.cfg.cfgDir)
if err != nil {
return fmt.Errorf("get base path: %w", err)
}
err = l.handleEnableOnlyOption()
if err != nil {
return err
}
if opts.Validation {
err = l.cfg.Validate()
if err != nil {
return err
}
}
return nil
}
// Hack to append values from StringSlice flags.
// Viper always overrides StringSlice values.
// https://github.com/spf13/viper/issues/1448
// So StringSlice flags are not bind to Viper like that their values are obtain via Cobra Flags.
func (l *Loader) applyStringSliceHack() {
if l.fs == nil {
return
}
l.appendStringSlice("enable", &l.cfg.Linters.Enable)
l.appendStringSlice("disable", &l.cfg.Linters.Disable)
l.appendStringSlice("build-tags", &l.cfg.Run.BuildTags)
}
func (l *Loader) appendStringSlice(name string, current *[]string) {
if l.fs.Changed(name) {
val, _ := l.fs.GetStringSlice(name)
*current = append(*current, val...)
}
}
func (l *Loader) checkConfigurationVersion() error {
if l.cfg.GetConfigDir() != "" && l.cfg.Version != "2" {
return fmt.Errorf("unsupported version of the configuration: %q "+
"See https://golangci-lint.run/docs/product/migration-guide for migration instructions", l.cfg.Version)
}
return nil
}
func (l *Loader) handleGoVersion() {
if l.cfg.Run.Go == "" {
l.cfg.Run.Go = detectGoVersion(context.Background(), l.log)
}
l.cfg.Linters.Settings.Govet.Go = l.cfg.Run.Go
l.cfg.Linters.Settings.ParallelTest.Go = l.cfg.Run.Go
l.cfg.Linters.Settings.GoFumpt.LangVersion = l.cfg.Run.Go
l.cfg.Formatters.Settings.GoFumpt.LangVersion = l.cfg.Run.Go
trimmedGoVersion := goutil.TrimGoVersion(l.cfg.Run.Go)
l.cfg.Linters.Settings.Revive.Go = trimmedGoVersion
l.cfg.Linters.Settings.Gocritic.Go = trimmedGoVersion
os.Setenv("GOSECGOVERSION", l.cfg.Run.Go)
}
func (l *Loader) handleDeprecation() error {
if l.cfg.InternalTest || l.cfg.InternalCmdTest || os.Getenv(logutils.EnvTestRun) == "1" {
return nil
}
l.handleLinterOptionDeprecations()
return nil
}
func (l *Loader) handleLinterOptionDeprecations() {
// Deprecated since v2.1.0.
if l.cfg.Linters.Settings.Goconst.IgnoreStrings != "" {
l.log.Warnf("The configuration option `linters.settings.goconst.ignore-strings` is deprecated, " +
"please use `linters.settings.goconst.ignore-string-values`.")
l.cfg.Linters.Settings.Goconst.IgnoreStringValues = append(l.cfg.Linters.Settings.Goconst.IgnoreStringValues,
l.cfg.Linters.Settings.Goconst.IgnoreStrings)
}
}
func (l *Loader) handleEnableOnlyOption() error {
lookup := l.fs.Lookup("enable-only")
if lookup == nil {
return nil
}
only, err := l.fs.GetStringSlice("enable-only")
if err != nil {
return err
}
if len(only) > 0 {
l.cfg.Linters = Linters{
Default: GroupNone,
Enable: only,
Settings: l.cfg.Linters.Settings,
Exclusions: l.cfg.Linters.Exclusions,
}
l.cfg.Formatters = Formatters{}
}
return nil
}
func (l *Loader) handleFormatters() {
l.handleFormatterOverrides()
l.handleFormatterExclusions()
}
// Overrides linter settings with formatter settings if the formatter is enabled.
func (l *Loader) handleFormatterOverrides() {
if slices.Contains(l.cfg.Formatters.Enable, "gofmt") {
l.cfg.Linters.Settings.GoFmt = l.cfg.Formatters.Settings.GoFmt
}
if slices.Contains(l.cfg.Formatters.Enable, "gofumpt") {
l.cfg.Linters.Settings.GoFumpt = l.cfg.Formatters.Settings.GoFumpt
}
if slices.Contains(l.cfg.Formatters.Enable, "goimports") {
l.cfg.Linters.Settings.GoImports = l.cfg.Formatters.Settings.GoImports
}
if slices.Contains(l.cfg.Formatters.Enable, "gci") {
l.cfg.Linters.Settings.Gci = l.cfg.Formatters.Settings.Gci
}
if slices.Contains(l.cfg.Formatters.Enable, "golines") {
l.cfg.Linters.Settings.GoLines = l.cfg.Formatters.Settings.GoLines
}
}
// Add formatter exclusions to linters exclusions.
func (l *Loader) handleFormatterExclusions() {
if len(l.cfg.Formatters.Enable) == 0 {
return
}
for _, path := range l.cfg.Formatters.Exclusions.Paths {
l.cfg.Linters.Exclusions.Rules = append(l.cfg.Linters.Exclusions.Rules, ExcludeRule{
BaseRule: BaseRule{
Linters: l.cfg.Formatters.Enable,
Path: path,
},
})
}
}
func (*Loader) handleFormatterDeprecations() {
// The function is empty but deprecations will happen in the future.
}
================================================
FILE: pkg/config/output.go
================================================
package config
import (
"fmt"
"slices"
"strings"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
)
type Output struct {
Formats Formats `mapstructure:"formats"`
SortOrder []string `mapstructure:"sort-order"`
ShowStats bool `mapstructure:"show-stats"`
PathPrefix string `mapstructure:"path-prefix"`
PathMode string `mapstructure:"path-mode"`
}
func (o *Output) Validate() error {
validators := []func() error{
o.validateSortOrder,
o.validatePathMode,
}
for _, v := range validators {
if err := v(); err != nil {
return err
}
}
return nil
}
func (o *Output) validateSortOrder() error {
validOrders := []string{"linter", "file", "severity"}
all := strings.Join(o.SortOrder, " ")
for _, order := range o.SortOrder {
if strings.Count(all, order) > 1 {
return fmt.Errorf("the sort-order name %q is repeated several times", order)
}
if !slices.Contains(validOrders, order) {
return fmt.Errorf("unsupported sort-order name %q", order)
}
}
return nil
}
func (o *Output) validatePathMode() error {
switch o.PathMode {
case "", fsutils.OutputPathModeAbsolute:
// Valid
default:
return fmt.Errorf("unsupported output path mode %q", o.PathMode)
}
return nil
}
================================================
FILE: pkg/config/output_formats.go
================================================
package config
type Formats struct {
Text Text `mapstructure:"text"`
JSON SimpleFormat `mapstructure:"json"`
Tab Tab `mapstructure:"tab"`
HTML SimpleFormat `mapstructure:"html"`
Checkstyle SimpleFormat `mapstructure:"checkstyle"`
CodeClimate SimpleFormat `mapstructure:"code-climate"`
JUnitXML JUnitXML `mapstructure:"junit-xml"`
TeamCity SimpleFormat `mapstructure:"teamcity"`
Sarif SimpleFormat `mapstructure:"sarif"`
}
func (f *Formats) IsEmpty() bool {
formats := []SimpleFormat{
f.Text.SimpleFormat,
f.JSON,
f.Tab.SimpleFormat,
f.HTML,
f.Checkstyle,
f.CodeClimate,
f.JUnitXML.SimpleFormat,
f.TeamCity,
f.Sarif,
}
for _, format := range formats {
if format.Path != "" {
return false
}
}
return true
}
type SimpleFormat struct {
Path string `mapstructure:"path"`
}
type Text struct {
SimpleFormat `mapstructure:",squash"`
PrintLinterName bool `mapstructure:"print-linter-name"`
PrintIssuedLine bool `mapstructure:"print-issued-lines"`
Colors bool `mapstructure:"colors"`
}
type Tab struct {
SimpleFormat `mapstructure:",squash"`
PrintLinterName bool `mapstructure:"print-linter-name"`
Colors bool `mapstructure:"colors"`
}
type JUnitXML struct {
SimpleFormat `mapstructure:",squash"`
Extended bool `mapstructure:"extended"`
}
================================================
FILE: pkg/config/output_test.go
================================================
package config
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
)
func TestOutput_Validate(t *testing.T) {
testCases := []struct {
desc string
settings *Output
}{
{
desc: "SortOrder: file",
settings: &Output{
SortOrder: []string{"file"},
},
},
{
desc: "SortOrder: linter",
settings: &Output{
SortOrder: []string{"linter"},
},
},
{
desc: "SortOrder: severity",
settings: &Output{
SortOrder: []string{"severity"},
},
},
{
desc: "SortOrder: multiple",
settings: &Output{
SortOrder: []string{"file", "linter", "severity"},
},
},
{
desc: "PathMode: empty",
settings: &Output{
PathMode: "",
},
},
{
desc: "PathMode: absolute",
settings: &Output{
PathMode: fsutils.OutputPathModeAbsolute,
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
require.NoError(t, err)
})
}
}
func TestOutput_Validate_error(t *testing.T) {
testCases := []struct {
desc string
settings *Output
expected string
}{
{
desc: "SortOrder: invalid",
settings: &Output{
SortOrder: []string{"a"},
},
expected: `unsupported sort-order name "a"`,
},
{
desc: "SortOrder: duplicate",
settings: &Output{
SortOrder: []string{"file", "linter", "severity", "linter"},
},
expected: `the sort-order name "linter" is repeated several times`,
},
{
desc: "PathMode: invalid",
settings: &Output{
PathMode: "example",
},
expected: `unsupported output path mode "example"`,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
require.EqualError(t, err, test.expected)
})
}
}
================================================
FILE: pkg/config/placeholders.go
================================================
package config
import "strings"
const (
// placeholderBasePath used inside linters to evaluate relative paths.
placeholderBasePath = "${base-path}"
// placeholderConfigPath used inside linters to paths relative to configuration.
placeholderConfigPath = "${config-path}"
)
func NewPlaceholderReplacer(cfg *Config) *strings.Replacer {
return strings.NewReplacer(
placeholderBasePath, cfg.GetBasePath(),
placeholderConfigPath, cfg.GetConfigDir(),
)
}
================================================
FILE: pkg/config/run.go
================================================
package config
import (
"fmt"
"slices"
"strings"
"time"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
)
// Run encapsulates the config options for running the linter analysis.
type Run struct {
Timeout time.Duration `mapstructure:"timeout"`
Concurrency int `mapstructure:"concurrency"`
Go string `mapstructure:"go"`
RelativePathMode string `mapstructure:"relative-path-mode"`
BuildTags []string `mapstructure:"build-tags"`
ModulesDownloadMode string `mapstructure:"modules-download-mode"`
EnableBuildVCS bool `mapstructure:"enable-build-vcs"`
ExitCodeIfIssuesFound int `mapstructure:"issues-exit-code"`
AnalyzeTests bool `mapstructure:"tests"`
AllowParallelRunners bool `mapstructure:"allow-parallel-runners"`
AllowSerialRunners bool `mapstructure:"allow-serial-runners"`
}
func (r *Run) Validate() error {
// go help modules
allowedModes := []string{"mod", "readonly", "vendor"}
if r.ModulesDownloadMode != "" && !slices.Contains(allowedModes, r.ModulesDownloadMode) {
return fmt.Errorf("invalid modules download path %s, only (%s) allowed", r.ModulesDownloadMode, strings.Join(allowedModes, "|"))
}
pathRelativeToModes := fsutils.AllRelativePathModes()
if r.RelativePathMode != "" && !slices.Contains(pathRelativeToModes, r.RelativePathMode) {
return fmt.Errorf("invalid relative path mode %s, only (%s) allowed", r.RelativePathMode, strings.Join(pathRelativeToModes, "|"))
}
return nil
}
================================================
FILE: pkg/config/run_test.go
================================================
package config
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestRun_Validate(t *testing.T) {
testCases := []struct {
desc string
settings *Run
}{
{
desc: "modules-download-mode: mod",
settings: &Run{
ModulesDownloadMode: "mod",
},
},
{
desc: "modules-download-mode: readonly",
settings: &Run{
ModulesDownloadMode: "readonly",
},
},
{
desc: "modules-download-mode: vendor",
settings: &Run{
ModulesDownloadMode: "vendor",
},
},
{
desc: "modules-download-mode: empty",
settings: &Run{
ModulesDownloadMode: "",
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
require.NoError(t, err)
})
}
}
func TestRun_Validate_error(t *testing.T) {
testCases := []struct {
desc string
settings *Run
expected string
}{
{
desc: "modules-download-mode: invalid",
settings: &Run{
ModulesDownloadMode: "invalid",
},
expected: "invalid modules download path invalid, only (mod|readonly|vendor) allowed",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.settings.Validate()
require.EqualError(t, err, test.expected)
})
}
}
================================================
FILE: pkg/config/severity.go
================================================
package config
import (
"errors"
"fmt"
)
const severityRuleMinConditionsCount = 1
type Severity struct {
Default string `mapstructure:"default"`
Rules []SeverityRule `mapstructure:"rules"`
}
func (s *Severity) Validate() error {
if len(s.Rules) > 0 && s.Default == "" {
return errors.New("can't set severity rule option: no default severity defined")
}
for i, rule := range s.Rules {
if err := rule.Validate(); err != nil {
return fmt.Errorf("error in severity rule #%d: %w", i, err)
}
}
return nil
}
type SeverityRule struct {
BaseRule `mapstructure:",squash"`
Severity string `mapstructure:"severity"`
}
func (s *SeverityRule) Validate() error {
if s.Severity == "" {
return errors.New("severity should be set")
}
return s.BaseRule.Validate(severityRuleMinConditionsCount)
}
================================================
FILE: pkg/config/severity_test.go
================================================
package config
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestSeverity_Validate(t *testing.T) {
testCases := []struct {
desc string
severity *Severity
}{
{
desc: "default with rules",
severity: &Severity{
Default: "high",
Rules: []SeverityRule{
{
Severity: "low",
BaseRule: BaseRule{
Path: "test",
},
},
},
},
},
{
desc: "default without rules",
severity: &Severity{
Default: "high",
},
},
{
desc: "same severity between default and rule",
severity: &Severity{
Default: "high",
Rules: []SeverityRule{
{
Severity: "high",
BaseRule: BaseRule{
Path: "test",
},
},
},
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.severity.Validate()
require.NoError(t, err)
})
}
}
func TestSeverity_Validate_error(t *testing.T) {
testCases := []struct {
desc string
severity *Severity
expected string
}{
{
desc: "missing default severity",
severity: &Severity{
Default: "",
Rules: []SeverityRule{
{
Severity: "low",
BaseRule: BaseRule{
Path: "test",
},
},
},
},
expected: "can't set severity rule option: no default severity defined",
},
{
desc: "missing rule severity",
severity: &Severity{
Default: "high",
Rules: []SeverityRule{
{
BaseRule: BaseRule{
Path: "test",
},
},
},
},
expected: "error in severity rule #0: severity should be set",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.severity.Validate()
require.EqualError(t, err, test.expected)
})
}
}
func TestSeverityRule_Validate(t *testing.T) {
rule := &SeverityRule{
Severity: "low",
BaseRule: BaseRule{
Path: "test",
},
}
err := rule.Validate()
require.NoError(t, err)
}
func TestSeverityRule_Validate_error(t *testing.T) {
testCases := []struct {
desc string
rule *SeverityRule
expected string
}{
{
desc: "missing severity",
rule: &SeverityRule{
BaseRule: BaseRule{
Path: "test",
},
},
expected: "severity should be set",
},
{
desc: "empty rule",
rule: &SeverityRule{
Severity: "low",
},
expected: "at least 1 of (text, source, path[-except], linters) should be set",
},
{
desc: "invalid path rule",
rule: &SeverityRule{
Severity: "low",
BaseRule: BaseRule{
Path: "**test",
},
},
expected: "invalid path regex: error parsing regexp: missing argument to repetition operator: `*`",
},
{
desc: "invalid path-except rule",
rule: &SeverityRule{
Severity: "low",
BaseRule: BaseRule{
PathExcept: "**test",
},
},
expected: "invalid path-except regex: error parsing regexp: missing argument to repetition operator: `*`",
},
{
desc: "invalid text rule",
rule: &SeverityRule{
Severity: "low",
BaseRule: BaseRule{
Text: "**test",
},
},
expected: "invalid text regex: error parsing regexp: missing argument to repetition operator: `*`",
},
{
desc: "invalid source rule",
rule: &SeverityRule{
Severity: "low",
BaseRule: BaseRule{
Source: "**test",
},
},
expected: "invalid source regex: error parsing regexp: missing argument to repetition operator: `*`",
},
{
desc: "path and path-expect",
rule: &SeverityRule{
Severity: "low",
BaseRule: BaseRule{
Path: "test",
PathExcept: "test",
},
},
expected: "path and path-except should not be set at the same time",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
err := test.rule.Validate()
require.EqualError(t, err, test.expected)
})
}
}
================================================
FILE: pkg/exitcodes/exitcodes.go
================================================
package exitcodes
const (
Success = iota
IssuesFound
WarningInTest
Failure
Timeout
NoGoFiles
NoConfigFileDetected
ErrorWasLogged
)
type ExitError struct {
Message string
Code int
}
func (e ExitError) Error() string {
return e.Message
}
var (
ErrNoGoFiles = &ExitError{
Message: "no go files to analyze",
Code: NoGoFiles,
}
ErrFailure = &ExitError{
Message: "failed to analyze",
Code: Failure,
}
)
================================================
FILE: pkg/fsutils/basepath.go
================================================
package fsutils
import (
"bytes"
"cmp"
"context"
"fmt"
"os/exec"
"path/filepath"
"github.com/ldez/grignotin/goenv"
)
// Relative path modes.
const (
RelativePathModeGoMod = "gomod"
RelativePathModeGitRoot = "gitroot"
RelativePathModeCfg = "cfg"
RelativePathModeWd = "wd"
)
// OutputPathModeAbsolute path mode used to show absolute paths in output reports (user-facing).
const OutputPathModeAbsolute = "abs"
func AllRelativePathModes() []string {
return []string{RelativePathModeGoMod, RelativePathModeGitRoot, RelativePathModeCfg, RelativePathModeWd}
}
func GetBasePath(ctx context.Context, mode, cfgDir string) (string, error) {
mode = cmp.Or(mode, RelativePathModeCfg)
switch mode {
case RelativePathModeCfg:
if cfgDir == "" {
return GetBasePath(ctx, RelativePathModeWd, cfgDir)
}
return cfgDir, nil
case RelativePathModeGoMod:
goMod, err := goenv.GetOne(ctx, goenv.GOMOD)
if err != nil {
return "", fmt.Errorf("get go.mod path: %w", err)
}
return filepath.Dir(goMod), nil
case RelativePathModeGitRoot:
root, err := gitRoot(ctx)
if err != nil {
return "", fmt.Errorf("get git root: %w", err)
}
return root, nil
case RelativePathModeWd:
wd, err := Getwd()
if err != nil {
return "", fmt.Errorf("get wd: %w", err)
}
return wd, nil
default:
return "", fmt.Errorf("unknown relative path mode: %s", mode)
}
}
func gitRoot(ctx context.Context) (string, error) {
cmd := exec.CommandContext(ctx, "git", "rev-parse", "--show-toplevel")
out, err := cmd.Output()
if err != nil {
return "", err
}
return string(bytes.TrimSpace(out)), nil
}
================================================
FILE: pkg/fsutils/filecache.go
================================================
package fsutils
import (
"fmt"
"os"
"sync"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type FileCache struct {
files sync.Map
}
func NewFileCache() *FileCache {
return &FileCache{}
}
func (fc *FileCache) GetFileBytes(filePath string) ([]byte, error) {
cachedBytes, ok := fc.files.Load(filePath)
if ok {
return cachedBytes.([]byte), nil
}
fileBytes, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("can't read file %s: %w", filePath, err)
}
fc.files.Store(filePath, fileBytes)
return fileBytes, nil
}
func PrettifyBytesCount(n int64) string {
const (
Multiplexer = 1024
KiB = 1 * Multiplexer
MiB = KiB * Multiplexer
GiB = MiB * Multiplexer
)
if n >= GiB {
return fmt.Sprintf("%.1fGiB", float64(n)/GiB)
}
if n >= MiB {
return fmt.Sprintf("%.1fMiB", float64(n)/MiB)
}
if n >= KiB {
return fmt.Sprintf("%.1fKiB", float64(n)/KiB)
}
return fmt.Sprintf("%dB", n)
}
func (fc *FileCache) PrintStats(log logutils.Log) {
var size int64
var mapLen int
fc.files.Range(func(_, fileBytes any) bool {
mapLen++
size += int64(len(fileBytes.([]byte)))
return true
})
log.Infof("File cache stats: %d entries of total size %s", mapLen, PrettifyBytesCount(size))
}
================================================
FILE: pkg/fsutils/fsutils.go
================================================
package fsutils
import (
"fmt"
"os"
"path/filepath"
"sync"
)
func IsDir(filename string) bool {
fi, err := os.Stat(filename)
return err == nil && fi.IsDir()
}
var (
cachedWd string
cachedWdError error
getWdOnce sync.Once
useCache = true
)
func UseWdCache(use bool) {
useCache = use
}
func Getwd() (string, error) {
if !useCache { // for tests
return os.Getwd()
}
getWdOnce.Do(func() {
cachedWd, cachedWdError = os.Getwd()
if cachedWdError != nil {
return
}
evaluatedWd, err := EvalSymlinks(cachedWd)
if err != nil {
cachedWd, cachedWdError = "", fmt.Errorf("can't eval symlinks on wd %s: %w", cachedWd, err)
return
}
cachedWd = evaluatedWd
})
return cachedWd, cachedWdError
}
var evalSymlinkCache sync.Map
type evalSymlinkRes struct {
path string
err error
}
func EvalSymlinks(path string) (string, error) {
r, ok := evalSymlinkCache.Load(path)
if ok {
er := r.(evalSymlinkRes)
return er.path, er.err
}
var er evalSymlinkRes
er.path, er.err = evalSymlinks(path)
evalSymlinkCache.Store(path, er)
return er.path, er.err
}
func ShortestRelPath(path, wd string) (string, error) {
if wd == "" { // get it if user don't have cached working dir
var err error
wd, err = Getwd()
if err != nil {
return "", fmt.Errorf("can't get working directory: %w", err)
}
}
evaluatedPath, err := EvalSymlinks(path)
if err != nil {
return "", fmt.Errorf("can't eval symlinks for path %s: %w", path, err)
}
path = evaluatedPath
// make path absolute and then relative to be able to fix this case:
// we are in `/test` dir, we want to normalize `../test`, and have file `file.go` in this dir;
// it must have normalized path `file.go`, not `../test/file.go`,
var absPath string
if filepath.IsAbs(path) {
absPath = path
} else {
absPath = filepath.Join(wd, path)
}
relPath, err := filepath.Rel(wd, absPath)
if err != nil {
return "", fmt.Errorf("can't get relative path for path %s and root %s: %w",
absPath, wd, err)
}
return relPath, nil
}
================================================
FILE: pkg/fsutils/fsutils_test.go
================================================
package fsutils
import (
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestShortestRelPath(t *testing.T) {
testCases := []struct {
desc string
path string
wd string
expected string
}{
{
desc: "based on parent path",
path: "fsutils_test.go",
wd: filepath.Join("..", "fsutils"),
expected: "fsutils_test.go",
},
{
desc: "based on current working directory",
path: "fsutils_test.go",
wd: "",
expected: "fsutils_test.go",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
rel, err := ShortestRelPath("fsutils_test.go", filepath.Join("..", "fsutils"))
require.NoError(t, err)
assert.Equal(t, test.expected, rel)
})
}
}
================================================
FILE: pkg/fsutils/fsutils_unix.go
================================================
//go:build !windows
package fsutils
import "path/filepath"
func evalSymlinks(path string) (string, error) {
return filepath.EvalSymlinks(path)
}
================================================
FILE: pkg/fsutils/fsutils_windows.go
================================================
//go:build windows
package fsutils
import (
"errors"
"os"
"path/filepath"
"syscall"
)
// This is a workaround for the behavior of [filepath.EvalSymlinks],
// which fails with [syscall.ENOTDIR] if the specified path contains a junction on Windows.
// Junctions can occur, for example, when a volume is mounted as a subdirectory inside another drive.
// This can usually happen when using the Dev Drives feature and replacing existing directories.
// See: https://github.com/golang/go/issues/40180
//
// Since [syscall.ENOTDIR] is only returned when calling [filepath.EvalSymlinks] on Windows
// if part of the presented path is a junction and nothing before was a symlink,
// we simply treat this as NOT symlink,
// because a symlink over the junction makes no sense at all.
func evalSymlinks(path string) (string, error) {
resolved, err := filepath.EvalSymlinks(path)
if err == nil {
return resolved, nil
}
if !errors.Is(err, syscall.ENOTDIR) {
return "", err
}
_, err = os.Stat(path)
if err != nil {
return "", err
}
// If exists, we make the path absolute, to be sure...
return filepath.Abs(path)
}
================================================
FILE: pkg/fsutils/linecache.go
================================================
package fsutils
import (
"bytes"
"fmt"
"sync"
)
type fileLinesCache [][]byte
type LineCache struct {
files sync.Map
fileCache *FileCache
}
func NewLineCache(fc *FileCache) *LineCache {
return &LineCache{
fileCache: fc,
}
}
// GetLine returns the index1-th (1-based index) line from the file on filePath
func (lc *LineCache) GetLine(filePath string, index1 int) (string, error) {
if index1 == 0 { // some linters, e.g. gosec can do it: it really means first line
index1 = 1
}
const index1To0Offset = -1
rawLine, err := lc.getRawLine(filePath, index1+index1To0Offset)
if err != nil {
return "", err
}
return string(bytes.Trim(rawLine, "\r")), nil
}
func (lc *LineCache) getRawLine(filePath string, index0 int) ([]byte, error) {
fc, err := lc.getFileCache(filePath)
if err != nil {
return nil, fmt.Errorf("failed to get file %s lines cache: %w", filePath, err)
}
if index0 < 0 {
return nil, fmt.Errorf("invalid file line index0 < 0: %d", index0)
}
if index0 >= len(fc) {
return nil, fmt.Errorf("invalid file line index0 (%d) >= len(fc) (%d)", index0, len(fc))
}
return fc[index0], nil
}
func (lc *LineCache) getFileCache(filePath string) (fileLinesCache, error) {
loadedFc, ok := lc.files.Load(filePath)
if ok {
return loadedFc.(fileLinesCache), nil
}
fileBytes, err := lc.fileCache.GetFileBytes(filePath)
if err != nil {
return nil, fmt.Errorf("can't get file %s bytes from cache: %w", filePath, err)
}
fc := bytes.Split(fileBytes, []byte("\n"))
lc.files.Store(filePath, fileLinesCache(fc))
return fc, nil
}
================================================
FILE: pkg/fsutils/path_unix.go
================================================
//go:build !windows
package fsutils
// NormalizePathInRegex it's a noop function on Unix.
func NormalizePathInRegex(path string) string {
return path
}
================================================
FILE: pkg/fsutils/path_windows.go
================================================
//go:build windows
package fsutils
import (
"path/filepath"
"regexp"
"strings"
)
var separatorToReplace = regexp.QuoteMeta(string(filepath.Separator))
// NormalizePathInRegex normalizes path in regular expressions.
// noop on Unix.
// This replacing should be safe because "/" are disallowed in Windows
// https://docs.microsoft.com/windows/win32/fileio/naming-a-file
func NormalizePathInRegex(path string) string {
// remove redundant character escape "\/" https://github.com/golangci/golangci-lint/issues/3277
clean := regexp.MustCompile(`\\+/`).
ReplaceAllStringFunc(path, func(s string) string {
if strings.Count(s, "\\")%2 == 0 {
return s
}
return s[1:]
})
return strings.ReplaceAll(clean, "/", separatorToReplace)
}
================================================
FILE: pkg/goanalysis/issue.go
================================================
package goanalysis
import (
"go/token"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
type Issue struct {
*result.Issue
Pass *analysis.Pass
}
func NewIssue(issue *result.Issue, pass *analysis.Pass) *Issue {
return &Issue{
Issue: issue,
Pass: pass,
}
}
type EncodingIssue struct {
FromLinter string
Text string
Severity string
Pos token.Position
LineRange *result.Range
SuggestedFixes []analysis.SuggestedFix
ExpectNoLint bool
ExpectedNoLintLinter string
}
================================================
FILE: pkg/goanalysis/linter.go
================================================
package goanalysis
import (
"context"
"errors"
"flag"
"fmt"
"strings"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
type LoadMode int
func (loadMode LoadMode) String() string {
switch loadMode {
case LoadModeNone:
return "none"
case LoadModeSyntax:
return "syntax"
case LoadModeTypesInfo:
return "types info"
case LoadModeWholeProgram:
return "whole program"
}
panic(fmt.Sprintf("unknown load mode %d", loadMode))
}
const (
LoadModeNone LoadMode = iota
LoadModeSyntax
LoadModeTypesInfo
LoadModeWholeProgram
)
type Linter struct {
name, desc string
analyzers []*analysis.Analyzer
cfg map[string]map[string]any
issuesReporter func(*linter.Context) []*Issue
contextSetter func(*linter.Context)
loadMode LoadMode
needUseOriginalPackages bool
}
func NewLinter(name, desc string, analyzers []*analysis.Analyzer, cfg map[string]map[string]any) *Linter {
return &Linter{name: name, desc: desc, analyzers: analyzers, cfg: cfg}
}
func NewLinterFromAnalyzer(analyzer *analysis.Analyzer) *Linter {
return NewLinter(analyzer.Name, analyzer.Doc, []*analysis.Analyzer{analyzer}, nil)
}
func (lnt *Linter) Run(_ context.Context, lintCtx *linter.Context) ([]*result.Issue, error) {
if err := lnt.preRun(lintCtx); err != nil {
return nil, err
}
return runAnalyzers(lnt, lintCtx)
}
func (lnt *Linter) UseOriginalPackages() {
lnt.needUseOriginalPackages = true
}
func (lnt *Linter) LoadMode() LoadMode {
return lnt.loadMode
}
func (lnt *Linter) WithDesc(desc string) *Linter {
lnt.desc = desc
return lnt
}
func (lnt *Linter) WithVersion(v int) *Linter {
if v == 0 {
return lnt
}
for _, analyzer := range lnt.analyzers {
if lnt.name != analyzer.Name {
continue
}
// The analyzer name should be the same as the linter name to avoid displaying the name inside the reports.
analyzer.Name = fmt.Sprintf("%s_v%d", analyzer.Name, v)
}
lnt.name = fmt.Sprintf("%s_v%d", lnt.name, v)
return lnt
}
func (lnt *Linter) WithConfig(cfg map[string]any) *Linter {
if len(cfg) == 0 {
return lnt
}
lnt.cfg = map[string]map[string]any{
lnt.name: cfg,
}
return lnt
}
func (lnt *Linter) WithLoadMode(loadMode LoadMode) *Linter {
lnt.loadMode = loadMode
return lnt
}
func (lnt *Linter) WithIssuesReporter(r func(*linter.Context) []*Issue) *Linter {
lnt.issuesReporter = r
return lnt
}
func (lnt *Linter) WithContextSetter(cs func(*linter.Context)) *Linter {
lnt.contextSetter = cs
return lnt
}
func (lnt *Linter) Name() string {
return lnt.name
}
func (lnt *Linter) Desc() string {
return lnt.desc
}
func (lnt *Linter) allAnalyzerNames() []string {
var ret []string
for _, a := range lnt.analyzers {
ret = append(ret, a.Name)
}
return ret
}
func (*Linter) configureAnalyzer(a *analysis.Analyzer, cfg map[string]any) error {
for k, v := range cfg {
f := a.Flags.Lookup(k)
if f == nil {
validFlagNames := allFlagNames(&a.Flags)
if len(validFlagNames) == 0 {
return errors.New("analyzer doesn't have settings")
}
return fmt.Errorf("analyzer doesn't have setting %q, valid settings: %v",
k, validFlagNames)
}
if err := f.Value.Set(valueToString(v)); err != nil {
return fmt.Errorf("failed to set analyzer setting %q with value %q: %w", k, v, err)
}
}
return nil
}
func (lnt *Linter) configure() error {
analyzersMap := map[string]*analysis.Analyzer{}
for _, a := range lnt.analyzers {
analyzersMap[a.Name] = a
}
for analyzerName, analyzerSettings := range lnt.cfg {
a := analyzersMap[analyzerName]
if a == nil {
return fmt.Errorf("settings key %q must be valid analyzer name, valid analyzers: %v",
analyzerName, lnt.allAnalyzerNames())
}
if err := lnt.configureAnalyzer(a, analyzerSettings); err != nil {
return fmt.Errorf("failed to configure analyzer %s: %w", analyzerName, err)
}
}
return nil
}
func (lnt *Linter) preRun(lintCtx *linter.Context) error {
if err := analysis.Validate(lnt.analyzers); err != nil {
return fmt.Errorf("failed to validate analyzers: %w", err)
}
if err := lnt.configure(); err != nil {
return fmt.Errorf("failed to configure analyzers: %w", err)
}
if lnt.contextSetter != nil {
lnt.contextSetter(lintCtx)
}
return nil
}
func (lnt *Linter) getName() string {
return lnt.name
}
func (lnt *Linter) getLinterNameForDiagnostic(*Diagnostic) string {
return lnt.name
}
func (lnt *Linter) getAnalyzers() []*analysis.Analyzer {
return lnt.analyzers
}
func (lnt *Linter) useOriginalPackages() bool {
return lnt.needUseOriginalPackages
}
func (lnt *Linter) reportIssues(lintCtx *linter.Context) []*Issue {
if lnt.issuesReporter != nil {
return lnt.issuesReporter(lintCtx)
}
return nil
}
func (lnt *Linter) getLoadMode() LoadMode {
return lnt.loadMode
}
func allFlagNames(fs *flag.FlagSet) []string {
var ret []string
fs.VisitAll(func(f *flag.Flag) {
ret = append(ret, f.Name)
})
return ret
}
func valueToString(v any) string {
if ss, ok := v.([]string); ok {
return strings.Join(ss, ",")
}
if is, ok := v.([]any); ok {
var ss []string
for _, i := range is {
ss = append(ss, fmt.Sprint(i))
}
return valueToString(ss)
}
return fmt.Sprint(v)
}
func DummyRun(_ *analysis.Pass) (any, error) {
return nil, nil
}
================================================
FILE: pkg/goanalysis/load/guard.go
================================================
package load
import (
"sync"
"golang.org/x/tools/go/packages"
)
type Guard struct {
loadMutexes map[*packages.Package]*sync.Mutex
mutex sync.Mutex
}
func NewGuard() *Guard {
return &Guard{
loadMutexes: map[*packages.Package]*sync.Mutex{},
}
}
func (g *Guard) AddMutexForPkg(pkg *packages.Package) {
g.loadMutexes[pkg] = &sync.Mutex{}
}
func (g *Guard) MutexForPkg(pkg *packages.Package) *sync.Mutex {
return g.loadMutexes[pkg]
}
func (g *Guard) Mutex() *sync.Mutex {
return &g.mutex
}
================================================
FILE: pkg/goanalysis/metalinter.go
================================================
package goanalysis
import (
"context"
"fmt"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
type MetaLinter struct {
linters []*Linter
analyzerToLinterName map[*analysis.Analyzer]string
}
func NewMetaLinter(linters []*Linter) *MetaLinter {
ml := &MetaLinter{linters: linters}
ml.analyzerToLinterName = ml.getAnalyzerToLinterNameMapping()
return ml
}
func (ml MetaLinter) Run(_ context.Context, lintCtx *linter.Context) ([]*result.Issue, error) {
for _, l := range ml.linters {
if err := l.preRun(lintCtx); err != nil {
return nil, fmt.Errorf("failed to pre-run %s: %w", l.Name(), err)
}
}
return runAnalyzers(ml, lintCtx)
}
func (MetaLinter) Name() string {
return "goanalysis_metalinter"
}
func (MetaLinter) Desc() string {
return ""
}
func (ml MetaLinter) getLoadMode() LoadMode {
loadMode := LoadModeNone
for _, l := range ml.linters {
if l.loadMode > loadMode {
loadMode = l.loadMode
}
}
return loadMode
}
func (ml MetaLinter) getAnalyzers() []*analysis.Analyzer {
var allAnalyzers []*analysis.Analyzer
for _, l := range ml.linters {
allAnalyzers = append(allAnalyzers, l.analyzers...)
}
return allAnalyzers
}
func (MetaLinter) getName() string {
return "metalinter"
}
func (MetaLinter) useOriginalPackages() bool {
return false // `unused` can't be run by this metalinter
}
func (ml MetaLinter) reportIssues(lintCtx *linter.Context) []*Issue {
var ret []*Issue
for _, lnt := range ml.linters {
if lnt.issuesReporter != nil {
ret = append(ret, lnt.issuesReporter(lintCtx)...)
}
}
return ret
}
func (ml MetaLinter) getLinterNameForDiagnostic(diag *Diagnostic) string {
return ml.analyzerToLinterName[diag.Analyzer]
}
func (ml MetaLinter) getAnalyzerToLinterNameMapping() map[*analysis.Analyzer]string {
analyzerToLinterName := map[*analysis.Analyzer]string{}
for _, l := range ml.linters {
for _, a := range l.analyzers {
analyzerToLinterName[a] = l.Name()
}
}
return analyzerToLinterName
}
================================================
FILE: pkg/goanalysis/pkgerrors/errors.go
================================================
package pkgerrors
import (
"errors"
"fmt"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
type IllTypedError struct {
Pkg *packages.Package
}
func (e *IllTypedError) Error() string {
return fmt.Sprintf("IllTypedError: errors in package: %v", e.Pkg.Errors)
}
func BuildIssuesFromIllTypedError(errs []error, lintCtx *linter.Context) ([]*result.Issue, error) {
var issues []*result.Issue
uniqReportedIssues := map[string]bool{}
var other error
for _, err := range errs {
var ill *IllTypedError
if !errors.As(err, &ill) {
if other == nil {
other = err
}
continue
}
for _, err := range extractErrors(ill.Pkg) {
issue, perr := parseError(err)
if perr != nil { // failed to parse
if uniqReportedIssues[err.Msg] {
continue
}
uniqReportedIssues[err.Msg] = true
lintCtx.Log.Errorf("typechecking error: %s", err.Msg)
} else {
key := fmt.Sprintf("%s.%d.%d.%s", issue.FilePath(), issue.Line(), issue.Column(), issue.Text)
if uniqReportedIssues[key] {
continue
}
uniqReportedIssues[key] = true
issue.Pkg = ill.Pkg // to save to cache later
issues = append(issues, issue)
}
}
}
if len(issues) == 0 && other != nil {
return nil, other
}
return issues, nil
}
================================================
FILE: pkg/goanalysis/pkgerrors/extract.go
================================================
package pkgerrors
import (
"fmt"
"maps"
"regexp"
"strings"
"golang.org/x/tools/go/packages"
)
// reFile matches a line who starts with path and position.
// ex: `/example/main.go:11:17: foobar`
var reFile = regexp.MustCompile(`^.+\.go:\d+:\d+: .+`)
func extractErrors(pkg *packages.Package) []packages.Error {
errors := extractErrorsImpl(pkg, map[*packages.Package]bool{})
if len(errors) == 0 {
return errors
}
skippedErrors := map[string]packages.Error{}
seenErrors := map[string]bool{}
var uniqErrors []packages.Error
for _, err := range errors {
msg := stackCrusher(err.Error())
if seenErrors[msg] {
continue
}
// This `if` is important to avoid duplicate errors.
// The goal is to keep the most relevant error.
if msg != err.Error() {
prev, alreadySkip := skippedErrors[msg]
if !alreadySkip {
skippedErrors[msg] = err
continue
}
if len(err.Error()) < len(prev.Error()) {
skippedErrors[msg] = err
}
continue
}
delete(skippedErrors, msg)
seenErrors[msg] = true
uniqErrors = append(uniqErrors, err)
}
// In some cases, the error stack doesn't contain the tip error.
// We must keep at least one of the original errors that contain the specific message.
for skippedError := range maps.Values(skippedErrors) {
uniqErrors = append(uniqErrors, skippedError)
}
if len(pkg.GoFiles) != 0 {
// errors were extracted from deps and have at least one file in package
for i := range uniqErrors {
if _, parseErr := parseErrorPosition(uniqErrors[i].Pos); parseErr == nil {
continue
}
// change pos to local file to properly process it by processors (properly read line etc.)
uniqErrors[i].Msg = fmt.Sprintf("%s: %s", uniqErrors[i].Pos, uniqErrors[i].Msg)
uniqErrors[i].Pos = fmt.Sprintf("%s:1", pkg.GoFiles[0])
}
// some errors like "code in directory expects import" don't have Pos, set it here
for i := range uniqErrors {
err := &uniqErrors[i]
if err.Pos == "" {
err.Pos = fmt.Sprintf("%s:1", pkg.GoFiles[0])
}
}
}
return uniqErrors
}
func extractErrorsImpl(pkg *packages.Package, seenPackages map[*packages.Package]bool) []packages.Error {
if seenPackages[pkg] {
return nil
}
seenPackages[pkg] = true
if !pkg.IllTyped { // otherwise, it may take hours to traverse all deps many times
return nil
}
if len(pkg.Errors) > 0 {
return pkg.Errors
}
var errors []packages.Error
for _, iPkg := range pkg.Imports {
iPkgErrors := extractErrorsImpl(iPkg, seenPackages)
if iPkgErrors != nil {
errors = append(errors, iPkgErrors...)
}
}
return errors
}
func stackCrusher(msg string) string {
index := strings.Index(msg, "(")
lastIndex := strings.LastIndex(msg, ")")
if index == -1 || index == len(msg)-1 || lastIndex == -1 || lastIndex != len(msg)-1 {
return msg
}
frag := msg[index+1 : lastIndex]
if !reFile.MatchString(frag) {
return msg
}
return stackCrusher(frag)
}
================================================
FILE: pkg/goanalysis/pkgerrors/extract_test.go
================================================
package pkgerrors
import (
"testing"
"github.com/stretchr/testify/assert"
"golang.org/x/tools/go/packages"
)
func Test_extractErrors(t *testing.T) {
testCases := []struct {
desc string
pkg *packages.Package
expected []packages.Error
}{
{
desc: "package with errors",
pkg: &packages.Package{
IllTyped: true,
Errors: []packages.Error{
{Pos: "/home/ldez/sources/golangci/sandbox/main.go:6:11", Msg: "test"},
},
},
expected: []packages.Error{
{Pos: "/home/ldez/sources/golangci/sandbox/main.go:6:11", Msg: "test"},
},
},
{
desc: "full error stack deduplication",
pkg: &packages.Package{
IllTyped: true,
Imports: map[string]*packages.Package{
"test": {
IllTyped: true,
Errors: []packages.Error{
{
Pos: "/home/ldez/sources/golangci/sandbox/main.go:6:11",
Msg: `/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/result/processors/nolint.go:13:2: /home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/result/processors/nolint.go:13:2: could not import github.com/golangci/golangci-lint/pkg/lint/lintersdb (/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go:13:2: could not import github.com/golangci/golangci-lint/pkg/golinters (/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:21:9: undeclared name: linterName))`,
Kind: 3,
},
{
Pos: "/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/result/processors/nolint.go:13:2",
Msg: `could not import github.com/golangci/golangci-lint/pkg/lint/lintersdb (/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go:13:2: could not import github.com/golangci/golangci-lint/pkg/golinters (/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:21:9: undeclared name: linterName))`,
Kind: 3,
},
{
Pos: "/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go:13:2",
Msg: `could not import github.com/golangci/golangci-lint/pkg/golinters (/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:21:9: undeclared name: linterName)`,
Kind: 3,
},
{
Pos: "/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:21:9",
Msg: `undeclared name: linterName`,
Kind: 3,
},
},
},
},
},
expected: []packages.Error{{
Pos: "/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:21:9",
Msg: "undeclared name: linterName",
Kind: 3,
}},
},
{
desc: "package with import errors but with only one error and without tip error",
pkg: &packages.Package{
IllTyped: true,
Imports: map[string]*packages.Package{
"test": {
IllTyped: true,
Errors: []packages.Error{
{
Pos: "/home/ldez/sources/golangci/sandbox/main.go:6:11",
Msg: "could not import github.com/example/foo (main.go:6:2: missing go.sum entry for module providing package github.com/example/foo (imported by github.com/golangci/sandbox); to add:\n\tgo get github.com/golangci/sandbox)",
Kind: 3,
},
},
},
},
},
expected: []packages.Error{{
Pos: "/home/ldez/sources/golangci/sandbox/main.go:6:11",
Msg: "could not import github.com/example/foo (main.go:6:2: missing go.sum entry for module providing package github.com/example/foo (imported by github.com/golangci/sandbox); to add:\n\tgo get github.com/golangci/sandbox)",
Kind: 3,
}},
},
{
desc: "package with import errors but without tip error",
pkg: &packages.Package{
IllTyped: true,
Imports: map[string]*packages.Package{
"test": {
IllTyped: true,
Errors: []packages.Error{
{
Pos: "/home/ldez/sources/golangci/sandbox/main.go:6:1",
Msg: "foo (/home/ldez/sources/golangci/sandbox/main.go:6:11: could not import github.com/example/foo (main.go:6:2: missing go.sum entry for module providing package github.com/example/foo (imported by github.com/golangci/sandbox); to add:\n\tgo get github.com/golangci/sandbox))",
Kind: 3,
},
{
Pos: "/home/ldez/sources/golangci/sandbox/main.go:6:11",
Msg: "could not import github.com/example/foo (main.go:6:2: missing go.sum entry for module providing package github.com/example/foo (imported by github.com/golangci/sandbox); to add:\n\tgo get github.com/golangci/sandbox)",
Kind: 3,
},
},
},
},
},
expected: []packages.Error{{
Pos: "/home/ldez/sources/golangci/sandbox/main.go:6:11",
Msg: "could not import github.com/example/foo (main.go:6:2: missing go.sum entry for module providing package github.com/example/foo (imported by github.com/golangci/sandbox); to add:\n\tgo get github.com/golangci/sandbox)",
Kind: 3,
}},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
errors := extractErrors(test.pkg)
assert.Equal(t, test.expected, errors)
})
}
}
func Test_stackCrusher(t *testing.T) {
testCases := []struct {
desc string
stack string
expected string
}{
{
desc: "large stack",
stack: `/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/result/processors/nolint.go:13:2: /home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/result/processors/nolint.go:13:2: could not import github.com/golangci/golangci-lint/pkg/lint/lintersdb (/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go:13:2: could not import github.com/golangci/golangci-lint/pkg/golinters (/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:21:9: undeclared name: linterName))`,
expected: "/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:21:9: undeclared name: linterName",
},
{
desc: "no stack",
stack: `/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:45:3: undeclared name: linterName`,
expected: "/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:45:3: undeclared name: linterName",
},
{
desc: "no stack but message with parenthesis",
stack: `/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:20:32: cannot use mu (variable of type sync.Mutex) as goanalysis.Issue value in argument to append`,
expected: "/home/ldez/sources/go/src/github.com/golangci/golangci-lint/pkg/golinters/deadcode.go:20:32: cannot use mu (variable of type sync.Mutex) as goanalysis.Issue value in argument to append",
},
{
desc: "stack with message with parenthesis at the end",
stack: `/home/username/childapp/interfaces/IPanel.go:4:2: could not import github.com/gotk3/gotk3/gtk (/home/username/childapp/vendor/github.com/gotk3/gotk3/gtk/aboutdialog.go:5:8: could not import C (cgo preprocessing failed))`,
expected: "/home/username/childapp/vendor/github.com/gotk3/gotk3/gtk/aboutdialog.go:5:8: could not import C (cgo preprocessing failed)",
},
{
desc: "no stack but message with parenthesis at the end",
stack: `/home/ldez/sources/go/src/github.com/golangci/sandbox/main.go:11:17: ui.test undefined (type App has no field or method test)`,
expected: "/home/ldez/sources/go/src/github.com/golangci/sandbox/main.go:11:17: ui.test undefined (type App has no field or method test)",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
actual := stackCrusher(test.stack)
assert.Equal(t, test.expected, actual)
})
}
}
================================================
FILE: pkg/goanalysis/pkgerrors/parse.go
================================================
package pkgerrors
import (
"errors"
"fmt"
"go/token"
"strconv"
"strings"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
func parseError(srcErr packages.Error) (*result.Issue, error) {
pos, err := parseErrorPosition(srcErr.Pos)
if err != nil {
return nil, err
}
return &result.Issue{
Pos: *pos,
Text: srcErr.Msg,
FromLinter: "typecheck",
}, nil
}
func parseErrorPosition(pos string) (*token.Position, error) {
// file:line(:column)
parts := strings.Split(pos, ":")
if len(parts) == 1 {
return nil, errors.New("no colons")
}
file := parts[0]
line, err := strconv.Atoi(parts[1])
if err != nil {
return nil, fmt.Errorf("can't parse line number %q: %w", parts[1], err)
}
var column int
if len(parts) == 3 { // got column
column, err = strconv.Atoi(parts[2])
if err != nil {
return nil, fmt.Errorf("failed to parse column from %q: %w", parts[2], err)
}
}
return &token.Position{
Filename: file,
Line: line,
Column: column,
}, nil
}
================================================
FILE: pkg/goanalysis/pkgerrors/parse_test.go
================================================
package pkgerrors
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"golang.org/x/tools/go/packages"
)
func Test_parseError(t *testing.T) {
cases := []struct {
in, out string
good bool
}{
{"f.go:1:2", "", true},
{"f.go:1", "", true},
{"f.go", "", false},
{"f.go: 1", "", false},
}
for _, c := range cases {
i, _ := parseError(packages.Error{
Pos: c.in,
Msg: "msg",
})
if !c.good {
assert.Nil(t, i)
continue
}
assert.NotNil(t, i)
pos := fmt.Sprintf("%s:%d", i.FilePath(), i.Line())
if i.Pos.Column != 0 {
pos += fmt.Sprintf(":%d", i.Pos.Column)
}
out := pos
expOut := c.out
if expOut == "" {
expOut = c.in
}
assert.Equal(t, expOut, out)
assert.Equal(t, "typecheck", i.FromLinter)
assert.Equal(t, "msg", i.Text)
}
}
================================================
FILE: pkg/goanalysis/position.go
================================================
package goanalysis
import (
"go/ast"
"go/token"
"path/filepath"
"golang.org/x/tools/go/analysis"
)
func GetGoFilePosition(pass *analysis.Pass, f *ast.File) (token.Position, bool) {
position := GetFilePositionFor(pass.Fset, f.Pos())
if filepath.Ext(position.Filename) == ".go" {
return position, true
}
return position, false
}
func GetFilePositionFor(fset *token.FileSet, p token.Pos) token.Position {
pos := fset.PositionFor(p, true)
ext := filepath.Ext(pos.Filename)
if ext != ".go" {
// position has been adjusted to a non-go file, revert to original file
return fset.PositionFor(p, false)
}
return pos
}
func EndOfLinePos(f *token.File, line int) token.Pos {
var end token.Pos
if line >= f.LineCount() {
// missing newline at the end of the file
end = f.Pos(f.Size())
} else {
end = f.LineStart(line+1) - token.Pos(1)
}
return end
}
// AdjustPos is a hack to get the right line to display.
// It should not be used outside some specific cases.
func AdjustPos(line, nonAdjLine, adjLine int) int {
return line + nonAdjLine - adjLine
}
================================================
FILE: pkg/goanalysis/runner.go
================================================
// Package goanalysis defines the implementation of the checker commands.
// The same code drives the multi-analysis driver, the single-analysis
// driver that is conventionally provided for convenience along with
// each analysis package, and the test driver.
package goanalysis
import (
"context"
"encoding/gob"
"fmt"
"go/token"
"maps"
"runtime"
"slices"
"sync"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/internal/cache"
"github.com/golangci/golangci-lint/v2/internal/errorutil"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
"github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
var (
debugf = logutils.Debug(logutils.DebugKeyGoAnalysis)
analyzeDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisAnalyze)
isMemoryDebug = logutils.HaveDebugTag(logutils.DebugKeyGoAnalysisMemory)
issuesCacheDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisIssuesCache)
factsDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisFacts)
factsCacheDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisFactsCache)
factsInheritDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisFactsInherit)
factsExportDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisFacts)
isFactsExportDebug = logutils.HaveDebugTag(logutils.DebugKeyGoAnalysisFactsExport)
)
type Diagnostic struct {
analysis.Diagnostic
Analyzer *analysis.Analyzer
Position token.Position
Pkg *packages.Package
File *token.File
}
type runner struct {
log logutils.Log
prefix string // ensure unique analyzer names
pkgCache *cache.Cache
loadGuard *load.Guard
loadMode LoadMode
passToPkg map[*analysis.Pass]*packages.Package
passToPkgGuard sync.Mutex
sw *timeutils.Stopwatch
}
func newRunner(prefix string, logger logutils.Log, pkgCache *cache.Cache, loadGuard *load.Guard,
loadMode LoadMode, sw *timeutils.Stopwatch,
) *runner {
return &runner{
prefix: prefix,
log: logger,
pkgCache: pkgCache,
loadGuard: loadGuard,
loadMode: loadMode,
passToPkg: map[*analysis.Pass]*packages.Package{},
sw: sw,
}
}
// Run loads the packages specified by args using go/packages,
// then applies the specified analyzers to them.
// Analysis flags must already have been set.
// It provides most of the logic for the main functions of both the
// singlechecker and the multi-analysis commands.
// It returns the appropriate exit code.
func (r *runner) run(analyzers []*analysis.Analyzer, initialPackages []*packages.Package) ([]*Diagnostic,
[]error, map[*analysis.Pass]*packages.Package,
) {
debugf("Analyzing %d packages on load mode %s", len(initialPackages), r.loadMode)
roots := r.analyze(initialPackages, analyzers)
diags, errs := extractDiagnostics(roots)
return diags, errs, r.passToPkg
}
type actKey struct {
*analysis.Analyzer
*packages.Package
}
func (r *runner) markAllActions(a *analysis.Analyzer, pkg *packages.Package, markedActions map[actKey]struct{}) {
k := actKey{a, pkg}
if _, ok := markedActions[k]; ok {
return
}
for _, req := range a.Requires {
r.markAllActions(req, pkg, markedActions)
}
if len(a.FactTypes) != 0 {
for path := range pkg.Imports {
r.markAllActions(a, pkg.Imports[path], markedActions)
}
}
markedActions[k] = struct{}{}
}
func (r *runner) makeAction(a *analysis.Analyzer, pkg *packages.Package,
initialPkgs map[*packages.Package]bool, actions map[actKey]*action, actAlloc *actionAllocator,
) *action {
k := actKey{a, pkg}
act, ok := actions[k]
if ok {
return act
}
act = actAlloc.alloc()
act.Analyzer = a
act.Package = pkg
act.runner = r
act.isInitialPkg = initialPkgs[pkg]
act.needAnalyzeSource = initialPkgs[pkg]
act.analysisDoneCh = make(chan struct{})
depsCount := len(a.Requires)
if len(a.FactTypes) > 0 {
depsCount += len(pkg.Imports)
}
act.Deps = make([]*action, 0, depsCount)
// Add a dependency on each required analyzers.
for _, req := range a.Requires {
act.Deps = append(act.Deps, r.makeAction(req, pkg, initialPkgs, actions, actAlloc))
}
r.buildActionFactDeps(act, a, pkg, initialPkgs, actions, actAlloc)
actions[k] = act
return act
}
func (r *runner) buildActionFactDeps(act *action, a *analysis.Analyzer, pkg *packages.Package,
initialPkgs map[*packages.Package]bool, actions map[actKey]*action, actAlloc *actionAllocator,
) {
// An analysis that consumes/produces facts
// must run on the package's dependencies too.
if len(a.FactTypes) == 0 {
return
}
act.objectFacts = make(map[objectFactKey]analysis.Fact)
act.packageFacts = make(map[packageFactKey]analysis.Fact)
paths := slices.Sorted(maps.Keys(pkg.Imports)) // for determinism
for _, path := range paths {
dep := r.makeAction(a, pkg.Imports[path], initialPkgs, actions, actAlloc)
act.Deps = append(act.Deps, dep)
}
// Need to register fact types for pkgcache proper gob encoding.
for _, f := range a.FactTypes {
gob.Register(f)
}
}
func (r *runner) prepareAnalysis(pkgs []*packages.Package,
analyzers []*analysis.Analyzer,
) (initialPkgs map[*packages.Package]bool, allActions, roots []*action) {
// Construct the action graph.
// Each graph node (action) is one unit of analysis.
// Edges express package-to-package (vertical) dependencies,
// and analysis-to-analysis (horizontal) dependencies.
// This place is memory-intensive: e.g. Istio project has 120k total actions.
// Therefore, optimize it carefully.
markedActions := make(map[actKey]struct{}, len(analyzers)*len(pkgs))
for _, a := range analyzers {
for _, pkg := range pkgs {
r.markAllActions(a, pkg, markedActions)
}
}
totalActionsCount := len(markedActions)
actions := make(map[actKey]*action, totalActionsCount)
actAlloc := newActionAllocator(totalActionsCount)
initialPkgs = make(map[*packages.Package]bool, len(pkgs))
for _, pkg := range pkgs {
initialPkgs[pkg] = true
}
// Build nodes for initial packages.
roots = make([]*action, 0, len(pkgs)*len(analyzers))
for _, a := range analyzers {
for _, pkg := range pkgs {
root := r.makeAction(a, pkg, initialPkgs, actions, actAlloc)
root.IsRoot = true
roots = append(roots, root)
}
}
allActions = slices.Collect(maps.Values(actions))
debugf("Built %d actions", len(actions))
return initialPkgs, allActions, roots
}
func (r *runner) analyze(pkgs []*packages.Package, analyzers []*analysis.Analyzer) []*action {
initialPkgs, actions, rootActions := r.prepareAnalysis(pkgs, analyzers)
actionPerPkg := map[*packages.Package][]*action{}
for _, act := range actions {
actionPerPkg[act.Package] = append(actionPerPkg[act.Package], act)
}
// Fill Imports field.
loadingPackages := map[*packages.Package]*loadingPackage{}
var dfs func(pkg *packages.Package)
dfs = func(pkg *packages.Package) {
if loadingPackages[pkg] != nil {
return
}
imports := map[string]*loadingPackage{}
for impPath, imp := range pkg.Imports {
dfs(imp)
impLp := loadingPackages[imp]
impLp.dependents++
imports[impPath] = impLp
}
loadingPackages[pkg] = &loadingPackage{
pkg: pkg,
imports: imports,
isInitial: initialPkgs[pkg],
log: r.log,
actions: actionPerPkg[pkg],
loadGuard: r.loadGuard,
dependents: 1, // self dependent
}
}
for _, act := range actions {
dfs(act.Package)
}
// Limit memory and IO usage.
gomaxprocs := runtime.GOMAXPROCS(-1)
debugf("Analyzing at most %d packages in parallel", gomaxprocs)
loadSem := make(chan struct{}, gomaxprocs)
debugf("There are %d initial and %d total packages", len(initialPkgs), len(loadingPackages))
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var wg sync.WaitGroup
for _, lp := range loadingPackages {
if lp.isInitial {
wg.Go(func() {
lp.analyzeRecursive(ctx, cancel, r.loadMode, loadSem)
})
}
}
wg.Wait()
return rootActions
}
func extractDiagnostics(roots []*action) (retDiags []*Diagnostic, retErrors []error) {
extracted := make(map[*action]bool)
var extract func(*action)
var visitAll func(actions []*action)
visitAll = func(actions []*action) {
for _, act := range actions {
if !extracted[act] {
extracted[act] = true
visitAll(act.Deps)
extract(act)
}
}
}
// De-duplicate diagnostics by position (not token.Pos) to
// avoid double-reporting in source files that belong to
// multiple packages, such as foo and foo.test.
type key struct {
token.Position
*analysis.Analyzer
message string
}
seen := make(map[key]bool)
extract = func(act *action) {
if act.Err != nil {
if pe, ok := act.Err.(*errorutil.PanicError); ok {
panic(pe)
}
retErrors = append(retErrors, fmt.Errorf("%s: %w", act.Analyzer.Name, act.Err))
return
}
if act.IsRoot {
for _, diag := range act.Diagnostics {
// We don't display a.Name/f.Category
// as most users don't care.
position := GetFilePositionFor(act.Package.Fset, diag.Pos)
file := act.Package.Fset.File(diag.Pos)
k := key{Position: position, Analyzer: act.Analyzer, message: diag.Message}
if seen[k] {
continue // duplicate
}
seen[k] = true
retDiag := &Diagnostic{
File: file,
Diagnostic: diag,
Analyzer: act.Analyzer,
Position: position,
Pkg: act.Package,
}
retDiags = append(retDiags, retDiag)
}
}
}
visitAll(roots)
return retDiags, retErrors
}
================================================
FILE: pkg/goanalysis/runner_action.go
================================================
package goanalysis
import (
"context"
"fmt"
"runtime/debug"
"github.com/golangci/golangci-lint/v2/internal/errorutil"
)
type actionAllocator struct {
allocatedActions []action
nextFreeIndex int
}
func newActionAllocator(maxCount int) *actionAllocator {
return &actionAllocator{
allocatedActions: make([]action, maxCount),
nextFreeIndex: 0,
}
}
func (actAlloc *actionAllocator) alloc() *action {
if actAlloc.nextFreeIndex == len(actAlloc.allocatedActions) {
panic(fmt.Sprintf("Made too many allocations of actions: %d allowed", len(actAlloc.allocatedActions)))
}
act := &actAlloc.allocatedActions[actAlloc.nextFreeIndex]
actAlloc.nextFreeIndex++
return act
}
func (act *action) waitUntilDependingAnalyzersWorked(ctx context.Context) {
for _, dep := range act.Deps {
if dep.Package == act.Package {
select {
case <-ctx.Done():
return
case <-dep.analysisDoneCh:
}
}
}
}
func (act *action) analyzeSafe() {
defer func() {
if p := recover(); p != nil {
if !act.IsRoot {
// This line allows to display "hidden" panic with analyzers like buildssa.
// Some linters are dependent of sub-analyzers but when a sub-analyzer fails the linter is not aware of that,
// this results to another panic (ex: "interface conversion: interface {} is nil, not *buildssa.SSA").
act.runner.log.Errorf("%s: panic during analysis: %v, %s", act.Analyzer.Name, p, string(debug.Stack()))
}
act.Err = errorutil.NewPanicError(fmt.Sprintf("%s: package %q (isInitialPkg: %t, needAnalyzeSource: %t): %s",
act.Analyzer.Name, act.Package.Name, act.isInitialPkg, act.needAnalyzeSource, p), debug.Stack())
}
}()
act.runner.sw.TrackStage(act.Analyzer.Name, act.analyze)
}
func (act *action) markDepsForAnalyzingSource() {
// Horizontal deps (analyzer.Requires) must be loaded from source and analyzed before analyzing
// this action.
for _, dep := range act.Deps {
if dep.Package == act.Package && !dep.needAnalyzeSource {
// Analyze source only for horizontal dependencies, e.g. from "buildssa".
dep.needAnalyzeSource = true // can't be set in parallel
dep.markDepsForAnalyzingSource()
}
}
}
================================================
FILE: pkg/goanalysis/runner_action_cache.go
================================================
package goanalysis
import (
"errors"
"fmt"
"io"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/types/objectpath"
"github.com/golangci/golangci-lint/v2/internal/cache"
)
type Fact struct {
Path string // non-empty only for object facts
Fact analysis.Fact
}
func (act *action) loadCachedFacts() bool {
if act.loadCachedFactsDone { // can't be set in parallel
return act.loadCachedFactsOk
}
res := func() bool {
if act.isInitialPkg {
return true // load cached facts only for non-initial packages
}
if len(act.Analyzer.FactTypes) == 0 {
return true // no need to load facts
}
return act.loadPersistedFacts()
}()
act.loadCachedFactsDone = true
act.loadCachedFactsOk = res
return res
}
func (act *action) persistFactsToCache() error {
analyzer := act.Analyzer
if len(analyzer.FactTypes) == 0 {
return nil
}
// Merge new facts into the package and persist them.
var facts []Fact
for key, fact := range act.packageFacts {
if key.pkg != act.Package.Types {
// The fact is from inherited facts from another package
continue
}
facts = append(facts, Fact{
Path: "",
Fact: fact,
})
}
for key, fact := range act.objectFacts {
obj := key.obj
if obj.Pkg() != act.Package.Types {
// The fact is from inherited facts from another package
continue
}
path, err := objectpath.For(obj)
if err != nil {
// The object is not globally addressable
continue
}
facts = append(facts, Fact{
Path: string(path),
Fact: fact,
})
}
factsCacheDebugf("Caching %d facts for package %q and analyzer %s", len(facts), act.Package.Name, act.Analyzer.Name)
return act.runner.pkgCache.Put(act.Package, cache.HashModeNeedAllDeps, factCacheKey(analyzer), facts)
}
func (act *action) loadPersistedFacts() bool {
var facts []Fact
err := act.runner.pkgCache.Get(act.Package, cache.HashModeNeedAllDeps, factCacheKey(act.Analyzer), &facts)
if err != nil {
if !errors.Is(err, cache.ErrMissing) && !errors.Is(err, io.EOF) {
act.runner.log.Warnf("Failed to get persisted facts: %s", err)
}
factsCacheDebugf("No cached facts for package %q and analyzer %s", act.Package.Name, act.Analyzer.Name)
return false
}
factsCacheDebugf("Loaded %d cached facts for package %q and analyzer %s", len(facts), act.Package.Name, act.Analyzer.Name)
for _, f := range facts {
if f.Path == "" { // this is a package fact
key := packageFactKey{pkg: act.Package.Types, typ: act.factType(f.Fact)}
act.packageFacts[key] = f.Fact
continue
}
obj, err := objectpath.Object(act.Package.Types, objectpath.Path(f.Path))
if err != nil {
// Be lenient about these errors.
// For example, when analyzing io/ioutil from source,
// we may get a fact for methods on the devNull type,
// and objectpath will happily create a path for them.
// However,
// when we later load io/ioutil from export data,
// the path no longer resolves.
//
// If an exported type embeds the unexported type,
// then (part of) the unexported type will become part of the type information and our path will resolve again.
continue
}
factKey := objectFactKey{obj, act.factType(f.Fact)}
act.objectFacts[factKey] = f.Fact
}
return true
}
func factCacheKey(a *analysis.Analyzer) string {
return fmt.Sprintf("%s/facts", a.Name)
}
================================================
FILE: pkg/goanalysis/runner_action_test.go
================================================
package goanalysis
import (
"testing"
"github.com/stretchr/testify/assert"
"golang.org/x/tools/go/packages"
)
func Test_action_markDepsForAnalyzingSource(t *testing.T) {
t.Run("marks direct horizontal deps", func(t *testing.T) {
pkg := &packages.Package{PkgPath: "pkg/a"}
dep := &action{Package: pkg}
act := &action{
Package: pkg,
Deps: []*action{dep},
}
act.markDepsForAnalyzingSource()
assert.True(t, dep.needAnalyzeSource)
})
t.Run("marks transitive horizontal deps", func(t *testing.T) {
pkg := &packages.Package{PkgPath: "pkg/a"}
// Chain: act -> dep1 -> dep2
dep2 := &action{Package: pkg}
dep1 := &action{
Package: pkg,
Deps: []*action{dep2},
}
act := &action{
Package: pkg,
Deps: []*action{dep1},
}
act.markDepsForAnalyzingSource()
assert.True(t, dep1.needAnalyzeSource)
assert.True(t, dep2.needAnalyzeSource)
})
t.Run("marks deep transitive horizontal deps", func(t *testing.T) {
pkg := &packages.Package{PkgPath: "pkg/a"}
// Chain: act -> dep1 -> dep2 -> dep3 (simulates nilaway -> buildssa -> ctrlflow -> inspect)
dep3 := &action{Package: pkg}
dep2 := &action{
Package: pkg,
Deps: []*action{dep3},
}
dep1 := &action{
Package: pkg,
Deps: []*action{dep2},
}
act := &action{
Package: pkg,
Deps: []*action{dep1},
}
act.markDepsForAnalyzingSource()
assert.True(t, dep1.needAnalyzeSource)
assert.True(t, dep2.needAnalyzeSource)
assert.True(t, dep3.needAnalyzeSource)
})
t.Run("does not mark cross-package deps", func(t *testing.T) {
pkgA := &packages.Package{PkgPath: "pkg/a"}
pkgB := &packages.Package{PkgPath: "pkg/b"}
dep := &action{Package: pkgB}
act := &action{
Package: pkgA,
Deps: []*action{dep},
}
act.markDepsForAnalyzingSource()
assert.False(t, dep.needAnalyzeSource)
})
t.Run("handles cycles without infinite recursion", func(t *testing.T) {
pkg := &packages.Package{PkgPath: "pkg/a"}
dep1 := &action{Package: pkg}
dep2 := &action{Package: pkg}
dep1.Deps = []*action{dep2}
dep2.Deps = []*action{dep1}
act := &action{
Package: pkg,
Deps: []*action{dep1},
}
// Should not hang or panic
act.markDepsForAnalyzingSource()
assert.True(t, dep1.needAnalyzeSource)
assert.True(t, dep2.needAnalyzeSource)
})
t.Run("skips already marked deps", func(t *testing.T) {
pkg := &packages.Package{PkgPath: "pkg/a"}
dep := &action{
Package: pkg,
needAnalyzeSource: true, // already marked
}
act := &action{
Package: pkg,
Deps: []*action{dep},
}
// Should not recurse into already-marked dep
act.markDepsForAnalyzingSource()
assert.True(t, dep.needAnalyzeSource)
})
}
================================================
FILE: pkg/goanalysis/runner_checker.go
================================================
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// Altered copy of https://github.com/golang/tools/blob/v0.43.0/go/analysis/checker/checker.go
package goanalysis
import (
"bytes"
"encoding/gob"
"errors"
"fmt"
"go/types"
"os"
"reflect"
"time"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors"
)
// NOTE(ldez) altered: custom fields; remove 'once' and 'duration'.
// An action represents one unit of analysis work: the application of
// one analysis to one package. Actions form a DAG, both within a
// package (as different analyzers are applied, either in sequence or
// parallel), and across packages (as dependencies are analyzed).
type action struct {
Analyzer *analysis.Analyzer
Package *packages.Package
IsRoot bool // whether this is a root node of the graph
Deps []*action
Result any // computed result of Analyzer.run, if any (and if IsRoot)
Err error // error result of Analyzer.run
Diagnostics []analysis.Diagnostic
Duration time.Duration // execution time of this step
pass *analysis.Pass
objectFacts map[objectFactKey]analysis.Fact
packageFacts map[packageFactKey]analysis.Fact
// NOTE(ldez) custom fields.
runner *runner
analysisDoneCh chan struct{}
loadCachedFactsDone bool
loadCachedFactsOk bool
isInitialPkg bool
needAnalyzeSource bool
}
// NOTE(ldez) no alteration.
type objectFactKey struct {
obj types.Object
typ reflect.Type
}
// NOTE(ldez) no alteration.
type packageFactKey struct {
pkg *types.Package
typ reflect.Type
}
// NOTE(ldez) no alteration.
func (act *action) String() string {
return fmt.Sprintf("%s@%s", act.Analyzer, act.Package)
}
// NOTE(ldez) altered version of `func (act *action) execOnce()`.
func (act *action) analyze() {
defer close(act.analysisDoneCh) // unblock actions depending on this action
if !act.needAnalyzeSource {
return
}
// Record time spent in this node but not its dependencies.
// In parallel mode, due to GC/scheduler contention, the
// time is 5x higher than in sequential mode, even with a
// semaphore limiting the number of threads here.
// So use -debug=tp.
t0 := time.Now()
defer func() {
act.Duration = time.Since(t0)
analyzeDebugf("go/analysis: %s: %s: analyzed package %q in %s", act.runner.prefix, act.Analyzer.Name, act.Package.Name, time.Since(t0))
}()
// Report an error if any dependency failures.
var depErrors error
for _, dep := range act.Deps {
if dep.Err != nil {
depErrors = errors.Join(depErrors, errors.Unwrap(dep.Err))
}
}
if depErrors != nil {
act.Err = fmt.Errorf("failed prerequisites: %w", depErrors)
return
}
// Plumb the output values of the dependencies
// into the inputs of this action. Also facts.
inputs := make(map[*analysis.Analyzer]any)
act.objectFacts = make(map[objectFactKey]analysis.Fact)
act.packageFacts = make(map[packageFactKey]analysis.Fact)
for _, dep := range act.Deps {
if dep.Package == act.Package {
// Same package, different analysis (horizontal edge):
// in-memory outputs of prerequisite analyzers
// become inputs to this analysis pass.
inputs[dep.Analyzer] = dep.Result
} else if dep.Analyzer == act.Analyzer { // (always true)
// Same analysis, different package (vertical edge):
// serialized facts produced by prerequisite analysis
// become available to this analysis pass.
inheritFacts(act, dep)
}
}
// NOTE(ldez) this is not compatible with our implementation.
// Quick (nonexhaustive) check that the correct go/packages mode bits were used.
// (If there were errors, all bets are off.)
// if pkg := act.Package; pkg.Errors == nil {
// if pkg.Name == "" || pkg.PkgPath == "" || pkg.Types == nil || pkg.Fset == nil || pkg.TypesSizes == nil {
// panic(fmt.Sprintf("packages must be loaded with packages.LoadSyntax mode: Name: %v, PkgPath: %v, Types: %v, Fset: %v, TypesSizes: %v",
// pkg.Name == "", pkg.PkgPath == "", pkg.Types == nil, pkg.Fset == nil, pkg.TypesSizes == nil))
// }
// }
factsDebugf("%s: Inherited facts in %s", act, time.Since(t0))
module := &analysis.Module{} // possibly empty (non nil) in go/analysis drivers.
if mod := act.Package.Module; mod != nil {
module = analysisModuleFromPackagesModule(mod)
}
// Run the analysis.
pass := &analysis.Pass{
Analyzer: act.Analyzer,
Fset: act.Package.Fset,
Files: act.Package.Syntax,
OtherFiles: act.Package.OtherFiles,
IgnoredFiles: act.Package.IgnoredFiles,
Pkg: act.Package.Types,
TypesInfo: act.Package.TypesInfo,
TypesSizes: act.Package.TypesSizes,
TypeErrors: act.Package.TypeErrors,
Module: module,
ResultOf: inputs,
Report: func(d analysis.Diagnostic) { act.Diagnostics = append(act.Diagnostics, d) },
ImportObjectFact: act.ObjectFact,
ExportObjectFact: act.exportObjectFact,
ImportPackageFact: act.PackageFact,
ExportPackageFact: act.exportPackageFact,
AllObjectFacts: act.AllObjectFacts,
AllPackageFacts: act.AllPackageFacts,
}
pass.ReadFile = driverutil.CheckedReadFile(pass, os.ReadFile)
act.pass = pass
act.runner.passToPkgGuard.Lock()
act.runner.passToPkg[pass] = act.Package
act.runner.passToPkgGuard.Unlock()
act.Result, act.Err = func() (any, error) {
// NOTE(golangci-lint):
// It looks like there should be !pass.Analyzer.RunDespiteErrors
// but govet's cgocall crashes on it.
// Govet itself contains !pass.Analyzer.RunDespiteErrors condition here,
// but it exits before it if packages.Load have failed.
if act.Package.IllTyped {
return nil, fmt.Errorf("analysis skipped: %w", &pkgerrors.IllTypedError{Pkg: act.Package})
}
t1 := time.Now()
result, err := pass.Analyzer.Run(pass)
if err != nil {
return nil, err
}
analyzedIn := time.Since(t1)
if analyzedIn > 10*time.Millisecond {
debugf("%s: run analyzer in %s", act, analyzedIn)
}
// correct result type?
if got, want := reflect.TypeOf(result), pass.Analyzer.ResultType; got != want {
return nil, fmt.Errorf(
"internal error: on package %s, analyzer %s returned a result of type %v, but declared ResultType %v",
pass.Pkg.Path(), pass.Analyzer, got, want)
}
// resolve diagnostic URLs
for i := range act.Diagnostics {
url, err := driverutil.ResolveURL(act.Analyzer, act.Diagnostics[i])
if err != nil {
return nil, err
}
act.Diagnostics[i].URL = url
}
return result, nil
}()
// Help detect (disallowed) calls after Run.
pass.ExportObjectFact = nil
pass.ExportPackageFact = nil
err := act.persistFactsToCache()
if err != nil {
act.runner.log.Warnf("Failed to persist facts to cache: %s", err)
}
}
// NOTE(ldez) altered: logger; sanityCheck.
// inheritFacts populates act.facts with
// those it obtains from its dependency, dep.
func inheritFacts(act, dep *action) {
const sanityCheck = false
for key, fact := range dep.objectFacts {
// Filter out facts related to objects
// that are irrelevant downstream
// (equivalently: not in the compiler export data).
if !exportedFrom(key.obj, dep.Package.Types) {
factsInheritDebugf("%v: discarding %T fact from %s for %s: %s", act, fact, dep, key.obj, fact)
continue
}
// Optionally serialize/deserialize fact
// to verify that it works across address spaces.
if sanityCheck {
encodedFact, err := codeFact(fact)
if err != nil {
act.runner.log.Panicf("internal error: encoding of %T fact failed in %v: %v", fact, act, err)
}
fact = encodedFact
}
factsInheritDebugf("%v: inherited %T fact for %s: %s", act, fact, key.obj, fact)
act.objectFacts[key] = fact
}
for key, fact := range dep.packageFacts {
// TODO: filter out facts that belong to
// packages not mentioned in the export data
// to prevent side channels.
//
// The Pass.All{Object,Package}Facts accessors expose too much:
// all facts, of all types, for all dependencies in the action
// graph. Not only does the representation grow quadratically,
// but it violates the separate compilation paradigm, allowing
// analysis implementations to communicate with indirect
// dependencies that are not mentioned in the export data.
//
// It's not clear how to fix this short of a rather expensive
// filtering step after each action that enumerates all the
// objects that would appear in export data, and deletes
// facts associated with objects not in this set.
// Optionally serialize/deserialize fact
// to verify that it works across address spaces
// and is deterministic.
if sanityCheck {
encodedFact, err := codeFact(fact)
if err != nil {
act.runner.log.Panicf("internal error: encoding of %T fact failed in %v", fact, act)
}
fact = encodedFact
}
factsInheritDebugf("%v: inherited %T fact for %s: %s", act, fact, key.pkg.Path(), fact)
act.packageFacts[key] = fact
}
}
// NOTE(ldez) altered: `new` is renamed to `newFact`.
// codeFact encodes then decodes a fact,
// just to exercise that logic.
func codeFact(fact analysis.Fact) (analysis.Fact, error) {
// We encode facts one at a time.
// A real modular driver would emit all facts
// into one encoder to improve gob efficiency.
var buf bytes.Buffer
if err := gob.NewEncoder(&buf).Encode(fact); err != nil {
return nil, err
}
// Encode it twice and assert that we get the same bits.
// This helps detect nondeterministic Gob encoding (e.g. of maps).
var buf2 bytes.Buffer
if err := gob.NewEncoder(&buf2).Encode(fact); err != nil {
return nil, err
}
if !bytes.Equal(buf.Bytes(), buf2.Bytes()) {
return nil, fmt.Errorf("encoding of %T fact is nondeterministic", fact)
}
newFact := reflect.New(reflect.TypeOf(fact).Elem()).Interface().(analysis.Fact)
if err := gob.NewDecoder(&buf).Decode(newFact); err != nil {
return nil, err
}
return newFact, nil
}
// NOTE(ldez) no alteration.
// exportedFrom reports whether obj may be visible to a package that imports pkg.
// This includes not just the exported members of pkg, but also unexported
// constants, types, fields, and methods, perhaps belonging to other packages,
// that find there way into the API.
// This is an overapproximation of the more accurate approach used by
// gc export data, which walks the type graph, but it's much simpler.
//
// TODO(adonovan): do more accurate filtering by walking the type graph.
func exportedFrom(obj types.Object, pkg *types.Package) bool {
switch obj := obj.(type) {
case *types.Func:
return obj.Exported() && obj.Pkg() == pkg ||
obj.Signature().Recv() != nil
case *types.Var:
if obj.IsField() {
return true
}
// we can't filter more aggressively than this because we need
// to consider function parameters exported, but have no way
// of telling apart function parameters from local variables.
return obj.Pkg() == pkg
case *types.TypeName, *types.Const:
return true
}
return false // Nil, Builtin, Label, or PkgName
}
// NOTE(ldez) altered: logger; `act.factType`.
// ObjectFact retrieves a fact associated with obj,
// and returns true if one was found.
// Given a value ptr of type *T, where *T satisfies Fact,
// ObjectFact copies the value to *ptr.
//
// See documentation at ImportObjectFact field of [analysis.Pass].
func (act *action) ObjectFact(obj types.Object, ptr analysis.Fact) bool {
if obj == nil {
panic("nil object")
}
key := objectFactKey{obj, act.factType(ptr)}
if v, ok := act.objectFacts[key]; ok {
reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
return true
}
return false
}
// NOTE(ldez) altered: logger; `act.factType`.
// exportObjectFact implements Pass.ExportObjectFact.
func (act *action) exportObjectFact(obj types.Object, fact analysis.Fact) {
if act.pass.ExportObjectFact == nil {
act.runner.log.Panicf("%s: Pass.ExportObjectFact(%s, %T) called after Run", act, obj, fact)
}
if obj.Pkg() != act.Package.Types {
act.runner.log.Panicf("internal error: in analysis %s of package %s: Fact.Set(%s, %T): can't set facts on objects belonging another package",
act.Analyzer, act.Package, obj, fact)
}
key := objectFactKey{obj, act.factType(fact)}
act.objectFacts[key] = fact // clobber any existing entry
if isFactsExportDebug {
objstr := types.ObjectString(obj, (*types.Package).Name)
factsExportDebugf("%s: object %s has fact %s\n",
act.Package.Fset.Position(obj.Pos()), objstr, fact)
}
}
// NOTE(ldez) no alteration.
// AllObjectFacts returns a new slice containing all object facts of
// the analysis's FactTypes in unspecified order.
//
// See documentation at AllObjectFacts field of [analysis.Pass].
func (act *action) AllObjectFacts() []analysis.ObjectFact {
facts := make([]analysis.ObjectFact, 0, len(act.objectFacts))
for k, fact := range act.objectFacts {
facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: fact})
}
return facts
}
// NOTE(ldez) altered: `act.factType`.
// PackageFact retrieves a fact associated with package pkg,
// which must be this package or one of its dependencies.
//
// See documentation at ImportObjectFact field of [analysis.Pass].
func (act *action) PackageFact(pkg *types.Package, ptr analysis.Fact) bool {
if pkg == nil {
panic("nil package")
}
key := packageFactKey{pkg, act.factType(ptr)}
if v, ok := act.packageFacts[key]; ok {
reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
return true
}
return false
}
// NOTE(ldez) altered: logger; `act.factType`.
// exportPackageFact implements Pass.ExportPackageFact.
func (act *action) exportPackageFact(fact analysis.Fact) {
if act.pass.ExportPackageFact == nil {
act.runner.log.Panicf("%s: Pass.ExportPackageFact(%T) called after Run", act, fact)
}
key := packageFactKey{act.pass.Pkg, act.factType(fact)}
act.packageFacts[key] = fact // clobber any existing entry
factsDebugf("%s: package %s has fact %s\n",
act.Package.Fset.Position(act.pass.Files[0].Pos()), act.pass.Pkg.Path(), fact)
}
// NOTE(ldez) altered: add receiver to handle logs.
func (act *action) factType(fact analysis.Fact) reflect.Type {
t := reflect.TypeOf(fact)
if t.Kind() != reflect.Pointer {
act.runner.log.Fatalf("invalid Fact type: got %T, want pointer", fact)
}
return t
}
// NOTE(ldez) no alteration.
// AllPackageFacts returns a new slice containing all package
// facts of the analysis's FactTypes in unspecified order.
//
// See documentation at AllPackageFacts field of [analysis.Pass].
func (act *action) AllPackageFacts() []analysis.PackageFact {
facts := make([]analysis.PackageFact, 0, len(act.packageFacts))
for k, fact := range act.packageFacts {
facts = append(facts, analysis.PackageFact{Package: k.pkg, Fact: fact})
}
return facts
}
// NOTE(ldez) no alteration.
func analysisModuleFromPackagesModule(mod *packages.Module) *analysis.Module {
if mod == nil {
return nil
}
var modErr *analysis.ModuleError
if mod.Error != nil {
modErr = &analysis.ModuleError{
Err: mod.Error.Err,
}
}
return &analysis.Module{
Path: mod.Path,
Version: mod.Version,
Replace: analysisModuleFromPackagesModule(mod.Replace),
Time: mod.Time,
Main: mod.Main,
Indirect: mod.Indirect,
Dir: mod.Dir,
GoMod: mod.GoMod,
GoVersion: mod.GoVersion,
Error: modErr,
}
}
================================================
FILE: pkg/goanalysis/runner_loadingpackage.go
================================================
package goanalysis
import (
"context"
"errors"
"fmt"
"go/ast"
"go/build"
"go/parser"
"go/scanner"
"go/types"
"os"
"reflect"
"strings"
"sync"
"sync/atomic"
"golang.org/x/sync/errgroup"
"golang.org/x/tools/go/gcexportdata"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
"github.com/golangci/golangci-lint/v2/pkg/goutil"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const unsafePkgName = "unsafe"
// https://github.com/golang/go/blob/go1.23.8/src/internal/types/errors/codes.go#L1484
const tooNew = 151
type loadingPackage struct {
pkg *packages.Package
imports map[string]*loadingPackage
isInitial bool
log logutils.Log
actions []*action // all actions with this package
loadGuard *load.Guard
dependents int32 // number of depending on it packages
analyzeOnce sync.Once
decUseMutex sync.Mutex
}
func (lp *loadingPackage) analyzeRecursive(ctx context.Context, cancel context.CancelFunc, loadMode LoadMode, loadSem chan struct{}) {
lp.analyzeOnce.Do(func() {
// Load the direct dependencies, in parallel.
var wg sync.WaitGroup
for _, imp := range lp.imports {
wg.Go(func() {
imp.analyzeRecursive(ctx, cancel, loadMode, loadSem)
})
}
wg.Wait()
lp.analyze(ctx, cancel, loadMode, loadSem)
})
}
func (lp *loadingPackage) analyze(ctx context.Context, cancel context.CancelFunc, loadMode LoadMode, loadSem chan struct{}) {
select {
case <-ctx.Done():
return
case loadSem <- struct{}{}:
defer func() {
<-loadSem
}()
}
// Save memory on unused more fields.
defer lp.decUse(loadMode < LoadModeWholeProgram)
if err := lp.loadWithFacts(loadMode); err != nil {
// Note: this error is ignored when there is no facts loading (e.g. with 98% of linters).
// But this is not a problem because the errors are added to the package.Errors.
// You through an error, try to add it to actions, but there is no action annnddd it's gone!
werr := fmt.Errorf("failed to load package %s: %w", lp.pkg.Name, err)
// Don't need to write error to errCh, it will be extracted and reported on another layer.
// Unblock depending on actions and propagate error.
for _, act := range lp.actions {
close(act.analysisDoneCh)
act.Err = werr
}
if len(lp.actions) == 0 {
lp.log.Warnf("no action but there is an error: %v", err)
}
return
}
actsWg, ctxGroup := errgroup.WithContext(ctx)
for _, act := range lp.actions {
actsWg.Go(func() error {
act.waitUntilDependingAnalyzersWorked(ctxGroup)
select {
case <-ctxGroup.Done():
return nil
default:
}
act.analyzeSafe()
return act.Err
})
}
err := actsWg.Wait()
if err != nil {
cancel()
}
}
func (lp *loadingPackage) loadFromSource(loadMode LoadMode) error {
pkg := lp.pkg
// Many packages have few files, much fewer than there
// are CPU cores. Additionally, parsing each individual file is
// very fast. A naive parallel implementation of this loop won't
// be faster, and tends to be slower due to extra scheduling,
// bookkeeping and potentially false sharing of cache lines.
pkg.Syntax = make([]*ast.File, 0, len(pkg.CompiledGoFiles))
for _, file := range pkg.CompiledGoFiles {
f, err := parser.ParseFile(pkg.Fset, file, nil, parser.ParseComments)
if err != nil {
pkg.Errors = append(pkg.Errors, lp.convertError(err)...)
continue
}
pkg.Syntax = append(pkg.Syntax, f)
}
if len(pkg.Errors) != 0 {
pkg.IllTyped = true
return nil
}
if loadMode == LoadModeSyntax {
return nil
}
// Call NewPackage directly with explicit name.
// This avoids skew between golist and go/types when the files'
// package declarations are inconsistent.
// Subtle: we populate all Types fields with an empty Package
// before loading export data so that export data processing
// never has to create a types.Package for an indirect dependency,
// which would then require that such created packages be explicitly
// inserted back into the Import graph as a final step after export data loading.
pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name)
pkg.IllTyped = true
pkg.TypesInfo = &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Instances: make(map[*ast.Ident]types.Instance),
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
Implicits: make(map[ast.Node]types.Object),
Selections: make(map[*ast.SelectorExpr]*types.Selection),
Scopes: make(map[ast.Node]*types.Scope),
FileVersions: make(map[*ast.File]string),
}
importer := func(path string) (*types.Package, error) {
if path == unsafePkgName {
return types.Unsafe, nil
}
if path == "C" {
// go/packages doesn't tell us that cgo preprocessing
// failed. When we subsequently try to parse the package,
// we'll encounter the raw C import.
return nil, errors.New("cgo preprocessing failed")
}
imp := pkg.Imports[path]
if imp == nil {
return nil, nil
}
if len(imp.Errors) > 0 {
return nil, imp.Errors[0]
}
return imp.Types, nil
}
var goVersion string
if pkg.Module != nil && pkg.Module.GoVersion != "" {
goVersion = "go" + strings.TrimPrefix(pkg.Module.GoVersion, "go")
} else {
var err error
goVersion, err = goutil.CleanRuntimeVersion()
if err != nil {
return err
}
}
tc := &types.Config{
Importer: importerFunc(importer),
Error: func(err error) {
pkg.Errors = append(pkg.Errors, lp.convertError(err)...)
},
GoVersion: goVersion,
Sizes: types.SizesFor(build.Default.Compiler, build.Default.GOARCH),
}
_ = types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax)
// Don't handle error here: errors are adding by tc.Error function.
illTyped := len(pkg.Errors) != 0
if !illTyped {
for _, imp := range lp.imports {
if imp.pkg.IllTyped {
illTyped = true
break
}
}
}
pkg.IllTyped = illTyped
return nil
}
func (lp *loadingPackage) loadFromExportData() error {
pkg := lp.pkg
// Call NewPackage directly with explicit name.
// This avoids skew between golist and go/types when the files'
// package declarations are inconsistent.
// Subtle: we populate all Types fields with an empty Package
// before loading export data so that export data processing
// never has to create a types.Package for an indirect dependency,
// which would then require that such created packages be explicitly
// inserted back into the Import graph as a final step after export data loading.
pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name)
pkg.IllTyped = true
for path, pkg := range pkg.Imports {
if pkg.Types == nil {
return fmt.Errorf("dependency %q hasn't been loaded yet", path)
}
}
if pkg.ExportFile == "" {
return fmt.Errorf("no export data for %q", pkg.ID)
}
f, err := os.Open(pkg.ExportFile)
if err != nil {
return err
}
defer f.Close()
r, err := gcexportdata.NewReader(f)
if err != nil {
return err
}
view := make(map[string]*types.Package) // view seen by gcexportdata
seen := make(map[*packages.Package]bool) // all visited packages
var visit func(pkgs map[string]*packages.Package)
visit = func(pkgs map[string]*packages.Package) {
for _, pkg := range pkgs {
if !seen[pkg] {
seen[pkg] = true
view[pkg.PkgPath] = pkg.Types
visit(pkg.Imports)
}
}
}
visit(pkg.Imports)
tpkg, err := gcexportdata.Read(r, pkg.Fset, view, pkg.PkgPath)
if err != nil {
return err
}
pkg.Types = tpkg
pkg.IllTyped = false
return nil
}
func (lp *loadingPackage) loadWithFacts(loadMode LoadMode) error {
pkg := lp.pkg
if pkg.PkgPath == unsafePkgName {
// Fill in the blanks to avoid surprises.
pkg.Syntax = []*ast.File{}
if loadMode >= LoadModeTypesInfo {
pkg.Types = types.Unsafe
pkg.TypesInfo = new(types.Info)
}
return nil
}
if pkg.TypesInfo != nil {
// Already loaded package, e.g. because another not go/analysis linter required types for deps.
// Try load cached facts for it.
for _, act := range lp.actions {
if !act.loadCachedFacts() {
// Cached facts loading failed: analyze later the action from source.
act.needAnalyzeSource = true
factsCacheDebugf("Loading of facts for already loaded %s failed, analyze it from source later", act)
act.markDepsForAnalyzingSource()
}
}
return nil
}
if lp.isInitial {
// No need to load cached facts: the package will be analyzed from source
// because it's the initial.
return lp.loadFromSource(loadMode)
}
return lp.loadImportedPackageWithFacts(loadMode)
}
func (lp *loadingPackage) loadImportedPackageWithFacts(loadMode LoadMode) error {
pkg := lp.pkg
// Load package from export data
if loadMode >= LoadModeTypesInfo {
if err := lp.loadFromExportData(); err != nil {
// We asked Go to give us up-to-date export data, yet
// we can't load it. There must be something wrong.
//
// Attempt loading from source. This should fail (because
// otherwise there would be export data); we just want to
// get the compile errors. If loading from source succeeds
// we discard the result, anyway. Otherwise, we'll fail
// when trying to reload from export data later.
// Otherwise, it panics because uses already existing (from exported data) types.
pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name)
if srcErr := lp.loadFromSource(loadMode); srcErr != nil {
return srcErr
}
// Make sure this package can't be imported successfully
pkg.Errors = append(pkg.Errors, packages.Error{
Pos: "-",
Msg: fmt.Sprintf("could not load export data: %s", err),
Kind: packages.ParseError,
})
return nil
}
}
needLoadFromSource := false
for _, act := range lp.actions {
if act.loadCachedFacts() {
continue
}
// Cached facts loading failed: analyze later the action from source.
factsCacheDebugf("Loading of facts for %s failed, analyze it from source later", act)
act.needAnalyzeSource = true // can't be set in parallel
needLoadFromSource = true
act.markDepsForAnalyzingSource()
}
if needLoadFromSource {
// Cached facts loading failed: analyze later the action from source. To perform
// the analysis we need to load the package from source code.
// Otherwise, it panics because uses already existing (from exported data) types.
if loadMode >= LoadModeTypesInfo {
pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name)
}
return lp.loadFromSource(loadMode)
}
return nil
}
func (lp *loadingPackage) decUse(canClearTypes bool) {
lp.decUseMutex.Lock()
defer lp.decUseMutex.Unlock()
for _, act := range lp.actions {
pass := act.pass
if pass == nil {
continue
}
pass.Files = nil
pass.TypesInfo = nil
pass.TypesSizes = nil
pass.ResultOf = nil
pass.Pkg = nil
pass.OtherFiles = nil
pass.AllObjectFacts = nil
pass.AllPackageFacts = nil
pass.ImportObjectFact = nil
pass.ExportObjectFact = nil
pass.ImportPackageFact = nil
pass.ExportPackageFact = nil
act.pass = nil
act.Deps = nil
if act.Result != nil {
if isMemoryDebug {
debugf("%s: decUse: nilling act result of size %d bytes", act, sizeOfValueTreeBytes(act.Result))
}
act.Result = nil
}
}
lp.pkg.Syntax = nil
lp.pkg.TypesInfo = nil
lp.pkg.TypesSizes = nil
// Can't set lp.pkg.Imports to nil because of loadFromExportData.visit.
dependents := atomic.AddInt32(&lp.dependents, -1)
if dependents != 0 {
return
}
if canClearTypes {
// canClearTypes is set to true if we can discard type
// information after the package and its dependents have been
// processed. This is the case when no whole program checkers (unused) are
// being run.
lp.pkg.Types = nil
}
lp.pkg = nil
for _, imp := range lp.imports {
imp.decUse(canClearTypes)
}
lp.imports = nil
for _, act := range lp.actions {
if !lp.isInitial {
act.Package = nil
}
act.packageFacts = nil
act.objectFacts = nil
}
lp.actions = nil
}
func (lp *loadingPackage) convertError(err error) []packages.Error {
var errs []packages.Error
// taken from go/packages
switch err := err.(type) {
case packages.Error:
// from driver
errs = append(errs, err)
case *os.PathError:
// from parser
errs = append(errs, packages.Error{
Pos: err.Path + ":1",
Msg: err.Err.Error(),
Kind: packages.ParseError,
})
case scanner.ErrorList:
// from parser
for _, err := range err {
errs = append(errs, packages.Error{
Pos: err.Pos.String(),
Msg: err.Msg,
Kind: packages.ParseError,
})
}
case types.Error:
// from type checker
// https://github.com/golang/go/blob/go1.23.8/src/go/types/api.go#L52-L57
if int(reflect.ValueOf(err).FieldByName("go116code").Int()) == tooNew {
// https://github.com/golang/go/blob/go1.23.8/src/go/types/check.go#L380
// https://github.com/golang/go/blob/go1.23.8/src/go/types/check.go#L349
panic(err.Msg)
}
errs = append(errs, packages.Error{
Pos: err.Fset.Position(err.Pos).String(),
Msg: err.Msg,
Kind: packages.TypeError,
})
default:
// unexpected impoverished error from parser?
errs = append(errs, packages.Error{
Pos: "-",
Msg: err.Error(),
Kind: packages.UnknownError,
})
// If you see this error message, please file a bug.
lp.log.Warnf("Internal error: error %q (%T) without position", err, err)
}
return errs
}
func (lp *loadingPackage) String() string {
return fmt.Sprintf("%s@%s", lp.pkg.PkgPath, lp.pkg.Name)
}
type importerFunc func(path string) (*types.Package, error)
func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
func sizeOfValueTreeBytes(v any) int {
return sizeOfReflectValueTreeBytes(reflect.ValueOf(v), map[uintptr]struct{}{})
}
func sizeOfReflectValueTreeBytes(rv reflect.Value, visitedPtrs map[uintptr]struct{}) int {
switch rv.Kind() {
case reflect.Pointer:
ptrSize := int(rv.Type().Size())
if rv.IsNil() {
return ptrSize
}
ptr := rv.Pointer()
if _, ok := visitedPtrs[ptr]; ok {
return 0
}
visitedPtrs[ptr] = struct{}{}
return ptrSize + sizeOfReflectValueTreeBytes(rv.Elem(), visitedPtrs)
case reflect.Interface:
if rv.IsNil() {
return 0
}
return sizeOfReflectValueTreeBytes(rv.Elem(), visitedPtrs)
case reflect.Struct:
ret := 0
for i := range rv.NumField() {
ret += sizeOfReflectValueTreeBytes(rv.Field(i), visitedPtrs)
}
return ret
case reflect.Slice, reflect.Array, reflect.Chan:
return int(rv.Type().Size()) + rv.Cap()*int(rv.Type().Elem().Size())
case reflect.Map:
ret := 0
for _, key := range rv.MapKeys() {
mv := rv.MapIndex(key)
ret += sizeOfReflectValueTreeBytes(key, visitedPtrs)
ret += sizeOfReflectValueTreeBytes(mv, visitedPtrs)
}
return ret
case reflect.String:
return rv.Len()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Uintptr, reflect.Bool, reflect.Float32, reflect.Float64,
reflect.Complex64, reflect.Complex128, reflect.Func, reflect.UnsafePointer:
return int(rv.Type().Size())
case reflect.Invalid:
return 0
default:
panic("unknown rv of type " + rv.String())
}
}
================================================
FILE: pkg/goanalysis/runners.go
================================================
package goanalysis
import (
"fmt"
"go/token"
"slices"
"strings"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
"github.com/golangci/golangci-lint/v2/pkg/result"
"github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
type runAnalyzersConfig interface {
getName() string
getLinterNameForDiagnostic(*Diagnostic) string
getAnalyzers() []*analysis.Analyzer
useOriginalPackages() bool
reportIssues(*linter.Context) []*Issue
getLoadMode() LoadMode
}
func runAnalyzers(cfg runAnalyzersConfig, lintCtx *linter.Context) ([]*result.Issue, error) {
log := lintCtx.Log.Child(logutils.DebugKeyGoAnalysis)
sw := timeutils.NewStopwatch("analyzers", log)
const stagesToPrint = 10
defer sw.PrintTopStages(stagesToPrint)
runner := newRunner(cfg.getName(), log, lintCtx.PkgCache, lintCtx.LoadGuard, cfg.getLoadMode(), sw)
pkgs := lintCtx.Packages
if cfg.useOriginalPackages() {
pkgs = lintCtx.OriginalPackages
}
issues, pkgsFromCache := loadIssuesFromCache(pkgs, lintCtx, cfg.getAnalyzers())
var pkgsToAnalyze []*packages.Package
for _, pkg := range pkgs {
if !pkgsFromCache[pkg] {
pkgsToAnalyze = append(pkgsToAnalyze, pkg)
}
}
diags, errs, passToPkg := runner.run(cfg.getAnalyzers(), pkgsToAnalyze)
defer func() {
if len(errs) == 0 {
// If we try to save to cache even if we have compilation errors
// we won't see them on repeated runs.
saveIssuesToCache(pkgs, pkgsFromCache, issues, lintCtx, cfg.getAnalyzers())
}
}()
buildAllIssues := func() []*result.Issue {
var retIssues []*result.Issue
reportedIssues := cfg.reportIssues(lintCtx)
for _, reportedIssue := range reportedIssues {
if reportedIssue.Pkg == nil {
reportedIssue.Pkg = passToPkg[reportedIssue.Pass]
}
retIssues = append(retIssues, reportedIssue.Issue)
}
return slices.Concat(retIssues, buildIssues(diags, cfg.getLinterNameForDiagnostic))
}
errIssues, err := pkgerrors.BuildIssuesFromIllTypedError(errs, lintCtx)
if err != nil {
return nil, err
}
issues = append(issues, errIssues...)
issues = append(issues, buildAllIssues()...)
return issues, nil
}
func buildIssues(diags []*Diagnostic, linterNameBuilder func(diag *Diagnostic) string) []*result.Issue {
var issues []*result.Issue
for _, diag := range diags {
linterName := linterNameBuilder(diag)
var text string
if diag.Analyzer.Name == linterName {
text = diag.Message
} else {
text = fmt.Sprintf("%s: %s", diag.Analyzer.Name, diag.Message)
}
var suggestedFixes []analysis.SuggestedFix
for _, sf := range diag.SuggestedFixes {
// Skip suggested fixes on cgo files.
// The related error is: "diff has out-of-bounds edits"
// This is a temporary workaround.
if !strings.HasSuffix(diag.File.Name(), ".go") {
continue
}
nsf := analysis.SuggestedFix{Message: sf.Message}
for _, edit := range sf.TextEdits {
end := edit.End
if !end.IsValid() {
end = edit.Pos
}
// To be applied the positions need to be "adjusted" based on the file.
// This is the difference between the "displayed" positions and "effective" positions.
nsf.TextEdits = append(nsf.TextEdits, analysis.TextEdit{
Pos: token.Pos(diag.File.Offset(edit.Pos)),
End: token.Pos(diag.File.Offset(end)),
NewText: edit.NewText,
})
}
suggestedFixes = append(suggestedFixes, nsf)
}
issues = append(issues, &result.Issue{
FromLinter: linterName,
Text: text,
Pos: diag.Position,
Pkg: diag.Pkg,
SuggestedFixes: suggestedFixes,
})
if len(diag.Related) > 0 {
for _, info := range diag.Related {
relatedPos := diag.Pkg.Fset.Position(info.Pos)
if relatedPos.Filename != diag.Position.Filename {
relatedPos = diag.Position
}
issues = append(issues, &result.Issue{
FromLinter: linterName,
Text: fmt.Sprintf("%s(related information): %s", diag.Analyzer.Name, info.Message),
Pos: relatedPos,
Pkg: diag.Pkg,
})
}
}
}
return issues
}
================================================
FILE: pkg/goanalysis/runners_cache.go
================================================
package goanalysis
import (
"runtime"
"sort"
"strings"
"sync"
"sync/atomic"
"time"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/internal/cache"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
func saveIssuesToCache(allPkgs []*packages.Package, pkgsFromCache map[*packages.Package]bool,
issues []*result.Issue, lintCtx *linter.Context, analyzers []*analysis.Analyzer,
) {
startedAt := time.Now()
perPkgIssues := map[*packages.Package][]*result.Issue{}
for _, issue := range issues {
perPkgIssues[issue.Pkg] = append(perPkgIssues[issue.Pkg], issue)
}
var savedIssuesCount int64
lintResKey := getIssuesCacheKey(analyzers)
workerCount := runtime.GOMAXPROCS(-1)
var wg sync.WaitGroup
pkgCh := make(chan *packages.Package, len(allPkgs))
for range workerCount {
wg.Go(func() {
for pkg := range pkgCh {
pkgIssues := perPkgIssues[pkg]
encodedIssues := make([]EncodingIssue, 0, len(pkgIssues))
for _, issue := range pkgIssues {
encodedIssues = append(encodedIssues, EncodingIssue{
FromLinter: issue.FromLinter,
Text: issue.Text,
Severity: issue.Severity,
Pos: issue.Pos,
LineRange: issue.LineRange,
SuggestedFixes: issue.SuggestedFixes,
ExpectNoLint: issue.ExpectNoLint,
ExpectedNoLintLinter: issue.ExpectedNoLintLinter,
})
}
atomic.AddInt64(&savedIssuesCount, int64(len(encodedIssues)))
if err := lintCtx.PkgCache.Put(pkg, cache.HashModeNeedAllDeps, lintResKey, encodedIssues); err != nil {
lintCtx.Log.Infof("Failed to save package %s issues (%d) to cache: %s", pkg, len(pkgIssues), err)
} else {
issuesCacheDebugf("Saved package %s issues (%d) to cache", pkg, len(pkgIssues))
}
}
})
}
for _, pkg := range allPkgs {
if pkgsFromCache[pkg] {
continue
}
pkgCh <- pkg
}
close(pkgCh)
wg.Wait()
lintCtx.PkgCache.Close()
issuesCacheDebugf("Saved %d issues from %d packages to cache in %s", savedIssuesCount, len(allPkgs), time.Since(startedAt))
}
func loadIssuesFromCache(pkgs []*packages.Package, lintCtx *linter.Context,
analyzers []*analysis.Analyzer,
) (issuesFromCache []*result.Issue, pkgsFromCache map[*packages.Package]bool) {
startedAt := time.Now()
lintResKey := getIssuesCacheKey(analyzers)
type cacheRes struct {
issues []*result.Issue
loadErr error
}
pkgToCacheRes := make(map[*packages.Package]*cacheRes, len(pkgs))
for _, pkg := range pkgs {
pkgToCacheRes[pkg] = &cacheRes{}
}
workerCount := runtime.GOMAXPROCS(-1)
var wg sync.WaitGroup
pkgCh := make(chan *packages.Package, len(pkgs))
for range workerCount {
wg.Go(func() {
for pkg := range pkgCh {
var pkgIssues []*EncodingIssue
err := lintCtx.PkgCache.Get(pkg, cache.HashModeNeedAllDeps, lintResKey, &pkgIssues)
cacheRes := pkgToCacheRes[pkg]
cacheRes.loadErr = err
if err != nil {
continue
}
if len(pkgIssues) == 0 {
continue
}
issues := make([]*result.Issue, 0, len(pkgIssues))
for _, issue := range pkgIssues {
issues = append(issues, &result.Issue{
FromLinter: issue.FromLinter,
Text: issue.Text,
Severity: issue.Severity,
Pos: issue.Pos,
LineRange: issue.LineRange,
SuggestedFixes: issue.SuggestedFixes,
Pkg: pkg,
ExpectNoLint: issue.ExpectNoLint,
ExpectedNoLintLinter: issue.ExpectedNoLintLinter,
})
}
cacheRes.issues = issues
}
})
}
for _, pkg := range pkgs {
pkgCh <- pkg
}
close(pkgCh)
wg.Wait()
loadedIssuesCount := 0
pkgsFromCache = map[*packages.Package]bool{}
for pkg, cacheRes := range pkgToCacheRes {
if cacheRes.loadErr == nil {
loadedIssuesCount += len(cacheRes.issues)
pkgsFromCache[pkg] = true
issuesFromCache = append(issuesFromCache, cacheRes.issues...)
issuesCacheDebugf("Loaded package %s issues (%d) from cache", pkg, len(cacheRes.issues))
} else {
issuesCacheDebugf("Didn't load package %s issues from cache: %s", pkg, cacheRes.loadErr)
}
}
issuesCacheDebugf("Loaded %d issues from cache in %s, analyzing %d/%d packages",
loadedIssuesCount, time.Since(startedAt), len(pkgs)-len(pkgsFromCache), len(pkgs))
return issuesFromCache, pkgsFromCache
}
func getIssuesCacheKey(analyzers []*analysis.Analyzer) string {
return "lint/result:" + analyzersHashID(analyzers)
}
func analyzersHashID(analyzers []*analysis.Analyzer) string {
names := make([]string, 0, len(analyzers))
for _, a := range analyzers {
names = append(names, a.Name)
}
sort.Strings(names)
return strings.Join(names, ",")
}
================================================
FILE: pkg/goformat/runner.go
================================================
package goformat
import (
"bytes"
"context"
"fmt"
"io"
"io/fs"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/alecthomas/chroma/v2/quick"
rpdiff "github.com/rogpeppe/go-internal/diff"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
"github.com/golangci/golangci-lint/v2/pkg/result/processors"
)
type Runner struct {
log logutils.Log
metaFormatter *goformatters.MetaFormatter
matcher *processors.GeneratedFileMatcher
opts RunnerOptions
exitCode int
}
func NewRunner(logger logutils.Log,
metaFormatter *goformatters.MetaFormatter, matcher *processors.GeneratedFileMatcher,
opts RunnerOptions) *Runner {
return &Runner{
log: logger,
matcher: matcher,
metaFormatter: metaFormatter,
opts: opts,
}
}
func (c *Runner) Run(paths []string) error {
savedStdout, savedStderr := os.Stdout, os.Stderr
if !logutils.HaveDebugTag(logutils.DebugKeyFormattersOutput) {
// Don't allow linters and loader to print anything
log.SetOutput(io.Discard)
c.setOutputToDevNull()
defer func() {
os.Stdout, os.Stderr = savedStdout, savedStderr
}()
}
if c.opts.stdin {
return c.formatStdIn("", savedStdout, os.Stdin)
}
for _, path := range paths {
err := c.walk(path, savedStdout)
if err != nil {
return err
}
}
for pattern, count := range c.opts.excludedPathCounter {
if c.opts.warnUnused && count == 0 {
c.log.Warnf("The pattern %q match no issues", pattern)
} else {
c.log.Infof("Skipped %d issues by pattern %q", count, pattern)
}
}
return nil
}
func (c *Runner) walk(root string, stdout *os.File) error {
return filepath.Walk(root, func(path string, f fs.FileInfo, err error) error {
if err != nil {
return err
}
if f.IsDir() && skipDir(f.Name()) {
return fs.SkipDir
}
if !isGoFile(f) {
return nil
}
match, err := c.opts.MatchAnyPattern(path)
if err != nil || match {
return err
}
//nolint:gosec // See explanation below.
// `path` contains the `root` but when using `r, err := os.OpenRoot(root)`, this part is not inside the file tree of `r`.
// `filepath.Rel()` can be used but it seems overkill in the context and doesn't work well with a file.
in, err := os.Open(path)
if err != nil {
return err
}
defer func() { _ = in.Close() }()
return c.process(path, stdout, in)
})
}
func (c *Runner) process(path string, stdout io.Writer, in io.Reader) error {
input, err := io.ReadAll(in)
if err != nil {
return err
}
match, err := c.matcher.IsGeneratedFile(path, input)
if err != nil || match {
return err
}
output := c.metaFormatter.Format(path, input)
if bytes.Equal(input, output) {
return nil
}
if c.opts.diff {
newName := filepath.ToSlash(path)
oldName := newName + ".orig"
patch := rpdiff.Diff(oldName, input, newName, output)
if c.opts.colors {
err = quick.Highlight(stdout, string(patch), "diff", "terminal", "native")
if err != nil {
return err
}
} else {
_, err = stdout.Write(patch)
if err != nil {
return err
}
}
c.exitCode = 1
return nil
}
c.log.Infof("format: %s", path)
// On Windows, we need to re-set the permissions from the file. See golang/go#38225.
var perms os.FileMode
if fi, err := os.Stat(path); err == nil {
perms = fi.Mode() & os.ModePerm
}
return os.WriteFile(path, output, perms)
}
func (c *Runner) formatStdIn(path string, stdout io.Writer, in io.Reader) error {
input, err := io.ReadAll(in)
if err != nil {
return err
}
match, err := c.matcher.IsGeneratedFile(path, input)
if err != nil {
return err
}
if match {
// If the file is generated,
// the input should be written to the stdout to avoid emptied the file.
_, err = stdout.Write(input)
if err != nil {
return err
}
return nil
}
output := c.metaFormatter.Format(path, input)
_, err = stdout.Write(output)
if err != nil {
return err
}
return nil
}
func (c *Runner) setOutputToDevNull() {
devNull, err := os.Open(os.DevNull)
if err != nil {
c.log.Warnf("Can't open null device %q: %s", os.DevNull, err)
return
}
os.Stdout, os.Stderr = devNull, devNull
}
func (c *Runner) ExitCode() int {
return c.exitCode
}
type RunnerOptions struct {
basePath string
patterns []*regexp.Regexp
generated string
diff bool
colors bool
stdin bool
warnUnused bool
excludedPathCounter map[*regexp.Regexp]int
}
func NewRunnerOptions(cfg *config.Config, diff, diffColored, stdin bool) (RunnerOptions, error) {
basePath, err := fsutils.GetBasePath(context.Background(), cfg.Run.RelativePathMode, cfg.GetConfigDir())
if err != nil {
return RunnerOptions{}, fmt.Errorf("get base path: %w", err)
}
// Required to be consistent with `RunnerOptions.MatchAnyPattern`.
absBasePath, err := filepath.Abs(basePath)
if err != nil {
return RunnerOptions{}, err
}
opts := RunnerOptions{
basePath: absBasePath,
generated: cfg.Formatters.Exclusions.Generated,
diff: diff || diffColored,
colors: diffColored,
stdin: stdin,
excludedPathCounter: make(map[*regexp.Regexp]int),
warnUnused: cfg.Formatters.Exclusions.WarnUnused,
}
for _, pattern := range cfg.Formatters.Exclusions.Paths {
exp, err := regexp.Compile(fsutils.NormalizePathInRegex(pattern))
if err != nil {
return RunnerOptions{}, fmt.Errorf("compile path pattern %q: %w", pattern, err)
}
opts.patterns = append(opts.patterns, exp)
opts.excludedPathCounter[exp] = 0
}
return opts, nil
}
func (o RunnerOptions) MatchAnyPattern(path string) (bool, error) {
if len(o.patterns) == 0 {
return false, nil
}
abs, err := filepath.Abs(path)
if err != nil {
return false, err
}
rel, err := filepath.Rel(o.basePath, abs)
if err != nil {
return false, err
}
for _, pattern := range o.patterns {
if pattern.MatchString(rel) {
o.excludedPathCounter[pattern]++
return true, nil
}
}
return false, nil
}
func skipDir(name string) bool {
switch name {
case "vendor", "testdata", "node_modules":
return true
default:
return strings.HasPrefix(name, ".") && name != "."
}
}
func isGoFile(f fs.FileInfo) bool {
return !f.IsDir() && !strings.HasPrefix(f.Name(), ".") && strings.HasSuffix(f.Name(), ".go")
}
================================================
FILE: pkg/goformat/runner_test.go
================================================
package goformat
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
func TestRunnerOptions_MatchAnyPattern(t *testing.T) {
testCases := []struct {
desc string
cfg *config.Config
filename string
assertMatch assert.BoolAssertionFunc
expectedCount int
}{
{
desc: "match",
cfg: &config.Config{
Formatters: config.Formatters{
Exclusions: config.FormatterExclusions{
Paths: []string{`generated\.go`},
},
},
},
filename: "generated.go",
assertMatch: assert.True,
expectedCount: 1,
},
{
desc: "no match",
cfg: &config.Config{
Formatters: config.Formatters{
Exclusions: config.FormatterExclusions{
Paths: []string{`excluded\.go`},
},
},
},
filename: "test.go",
assertMatch: assert.False,
expectedCount: 0,
},
{
desc: "no patterns",
cfg: &config.Config{},
filename: "test.go",
assertMatch: assert.False,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
tmpDir := t.TempDir()
testFile := filepath.Join(tmpDir, test.filename)
err := os.WriteFile(testFile, []byte("package main"), 0o600)
require.NoError(t, err)
test.cfg.SetConfigDir(tmpDir)
opts, err := NewRunnerOptions(test.cfg, false, false, false)
require.NoError(t, err)
match, err := opts.MatchAnyPattern(testFile)
require.NoError(t, err)
test.assertMatch(t, match)
require.Len(t, opts.patterns, len(test.cfg.Formatters.Exclusions.Paths))
if len(opts.patterns) == 0 {
assert.Empty(t, opts.excludedPathCounter)
} else {
assert.Equal(t, test.expectedCount, opts.excludedPathCounter[opts.patterns[0]])
}
})
}
}
// File structure:
//
// tmp
// ├── project (`realDir`)
// │ ├── .golangci.yml
// │ └── test.go
// └── somewhere
// └── symlink (to "project")
func TestRunnerOptions_MatchAnyPattern_withSymlinks(t *testing.T) {
tmpDir := t.TempDir()
testFile := filepath.Join(tmpDir, "project", "test.go")
realDir := filepath.Dir(testFile)
err := os.MkdirAll(realDir, 0o755)
require.NoError(t, err)
err = os.WriteFile(testFile, []byte("package main"), 0o600)
require.NoError(t, err)
symlink := filepath.Join(tmpDir, "somewhere", "symlink")
err = os.MkdirAll(filepath.Dir(symlink), 0o755)
require.NoError(t, err)
err = os.Symlink(realDir, symlink)
require.NoError(t, err)
cfg := &config.Config{
Formatters: config.Formatters{
Exclusions: config.FormatterExclusions{
Paths: []string{`^[^/\\]+\.go$`},
},
},
}
cfg.SetConfigDir(symlink)
opts, err := NewRunnerOptions(cfg, false, false, false)
require.NoError(t, err)
match, err := opts.MatchAnyPattern(filepath.Join(symlink, "test.go"))
require.NoError(t, err)
assert.True(t, match)
require.NotEmpty(t, opts.patterns)
require.Len(t, opts.patterns, len(cfg.Formatters.Exclusions.Paths))
assert.Equal(t, 1, opts.excludedPathCounter[opts.patterns[0]])
}
================================================
FILE: pkg/goformatters/analyzer.go
================================================
package goformatters
import (
"bytes"
"fmt"
"os"
"path/filepath"
"github.com/rogpeppe/go-internal/diff"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/goformatters/internal"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
// NewAnalyzer converts a [Formatter] to an [analysis.Analyzer].
func NewAnalyzer(logger logutils.Log, doc string, formatter Formatter) *analysis.Analyzer {
return &analysis.Analyzer{
Name: formatter.Name(),
Doc: doc,
Run: func(pass *analysis.Pass) (any, error) {
for _, file := range pass.Files {
position, isGoFile := goanalysis.GetGoFilePosition(pass, file)
if !isGoFile {
continue
}
input, err := os.ReadFile(position.Filename)
if err != nil {
return nil, fmt.Errorf("unable to open file %s: %w", position.Filename, err)
}
output, err := formatter.Format(position.Filename, input)
if err != nil {
return nil, fmt.Errorf("error while running %s: %w", formatter.Name(), err)
}
if !bytes.Equal(input, output) {
newName := filepath.ToSlash(position.Filename)
oldName := newName + ".orig"
patch := diff.Diff(oldName, input, newName, output)
err = internal.ExtractDiagnosticFromPatch(pass, file, patch, logger)
if err != nil {
return nil, fmt.Errorf("can't extract issues from %s diff output %q: %w", formatter.Name(), patch, err)
}
}
}
return nil, nil
},
}
}
================================================
FILE: pkg/goformatters/formatters.go
================================================
package goformatters
type Formatter interface {
Name() string
Format(filename string, src []byte) ([]byte, error)
}
================================================
FILE: pkg/goformatters/gci/gci.go
================================================
package gci
import (
"context"
"go/format"
gcicfg "github.com/daixiang0/gci/pkg/config"
"github.com/daixiang0/gci/pkg/gci"
"github.com/daixiang0/gci/pkg/log"
"github.com/ldez/grignotin/gomod"
"github.com/golangci/golangci-lint/v2/pkg/config"
gcicfgi "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config"
"github.com/golangci/golangci-lint/v2/pkg/goformatters/internal"
)
const Name = "gci"
type Formatter struct {
config *gcicfg.Config
}
func New(settings *config.GciSettings) (*Formatter, error) {
log.InitLogger()
_ = log.L().Sync()
modPath, err := gomod.GetModulePath(context.Background())
if err != nil {
internal.FormatterLogger.Errorf("gci: %v", err)
}
cfg := gcicfgi.YamlConfig{
Cfg: gcicfg.BoolConfig{
NoInlineComments: settings.NoInlineComments,
NoPrefixComments: settings.NoPrefixComments,
CustomOrder: settings.CustomOrder,
NoLexOrder: settings.NoLexOrder,
// Should be managed with `formatters.exclusions.generated`.
SkipGenerated: false,
},
SectionStrings: settings.Sections,
ModPath: modPath,
}
parsedCfg, err := cfg.Parse()
if err != nil {
return nil, err
}
return &Formatter{config: &gcicfg.Config{
BoolConfig: parsedCfg.BoolConfig,
Sections: parsedCfg.Sections,
SectionSeparators: parsedCfg.SectionSeparators,
}}, nil
}
func (*Formatter) Name() string {
return Name
}
func (f *Formatter) Format(filename string, src []byte) ([]byte, error) {
_, formatted, err := gci.LoadFormat(src, filename, *f.config)
if err != nil {
return nil, err
}
// gci format the code only when the imports are modified,
// this produced inconsistencies.
// To be always consistent, the code should always be formatted.
// https://github.com/daixiang0/gci/blob/c4f689991095c0e54843dca76fb9c3bad58ec5c7/pkg/gci/gci.go#L148-L151
// https://github.com/daixiang0/gci/blob/c4f689991095c0e54843dca76fb9c3bad58ec5c7/pkg/gci/gci.go#L215
return format.Source(formatted)
}
================================================
FILE: pkg/goformatters/gci/internal/LICENSE
================================================
BSD 3-Clause License
Copyright (c) 2020, Xiang Dai
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: pkg/goformatters/gci/internal/config/config.go
================================================
package config
import (
"sort"
"strings"
"go.yaml.in/yaml/v3"
"github.com/daixiang0/gci/pkg/config"
"github.com/daixiang0/gci/pkg/section"
sectioni "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section"
)
var defaultOrder = map[string]int{
section.StandardType: 0,
section.DefaultType: 1,
section.CustomType: 2,
section.BlankType: 3,
section.DotType: 4,
section.AliasType: 5,
section.LocalModuleType: 6,
}
type Config struct {
config.BoolConfig
Sections section.SectionList
SectionSeparators section.SectionList
}
type YamlConfig struct {
Cfg config.BoolConfig `yaml:",inline"`
SectionStrings []string `yaml:"sections"`
SectionSeparatorStrings []string `yaml:"sectionseparators"`
// Since history issue, Golangci-lint needs Analyzer to run and GCI add an Analyzer layer to integrate.
// The ModPath param is only from analyzer.go, no need to set it in all other places.
ModPath string `yaml:"-"`
}
func (g YamlConfig) Parse() (*Config, error) {
var err error
sections, err := sectioni.Parse(g.SectionStrings)
if err != nil {
return nil, err
}
if sections == nil {
sections = sectioni.DefaultSections()
}
if err := configureSections(sections, g.ModPath); err != nil {
return nil, err
}
// if default order sorted sections
if !g.Cfg.CustomOrder {
sort.Slice(sections, func(i, j int) bool {
sectionI, sectionJ := sections[i].Type(), sections[j].Type()
if g.Cfg.NoLexOrder || strings.Compare(sectionI, sectionJ) != 0 {
return defaultOrder[sectionI] < defaultOrder[sectionJ]
}
return strings.Compare(sections[i].String(), sections[j].String()) < 0
})
}
sectionSeparators, err := sectioni.Parse(g.SectionSeparatorStrings)
if err != nil {
return nil, err
}
if sectionSeparators == nil {
sectionSeparators = section.DefaultSectionSeparators()
}
return &Config{g.Cfg, sections, sectionSeparators}, nil
}
func ParseConfig(in string) (*Config, error) {
config := YamlConfig{}
err := yaml.Unmarshal([]byte(in), &config)
if err != nil {
return nil, err
}
gciCfg, err := config.Parse()
if err != nil {
return nil, err
}
return gciCfg, nil
}
// configureSections now only do golang module path finding.
// Since history issue, Golangci-lint needs Analyzer to run and GCI add an Analyzer layer to integrate.
// The path param is from analyzer.go, in all other places should pass empty string.
func configureSections(sections section.SectionList, path string) error {
for _, sec := range sections {
switch s := sec.(type) {
case *section.LocalModule:
if err := s.Configure(path); err != nil {
return err
}
}
}
return nil
}
================================================
FILE: pkg/goformatters/gci/internal/readme.md
================================================
Code borrowed from gci and modified to use new std packages.
https://github.com/daixiang0/gci/pull/227
================================================
FILE: pkg/goformatters/gci/internal/section/parser.go
================================================
package section
import (
"errors"
"fmt"
"strings"
"github.com/daixiang0/gci/pkg/section"
)
func Parse(data []string) (section.SectionList, error) {
if len(data) == 0 {
return nil, nil
}
var list section.SectionList
var errString string
for _, d := range data {
s := strings.ToLower(d)
if len(s) == 0 {
return nil, nil
}
if s == "default" {
list = append(list, section.Default{})
} else if s == "standard" {
list = append(list, Standard{})
} else if s == "newline" {
list = append(list, section.NewLine{})
} else if strings.HasPrefix(s, "prefix(") && len(d) > 8 {
list = append(list, section.Custom{Prefix: d[7 : len(d)-1]})
} else if strings.HasPrefix(s, "commentline(") && len(d) > 13 {
list = append(list, section.Custom{Prefix: d[12 : len(d)-1]})
} else if s == "dot" {
list = append(list, section.Dot{})
} else if s == "blank" {
list = append(list, section.Blank{})
} else if s == "alias" {
list = append(list, section.Alias{})
} else if s == "localmodule" {
// pointer because we need to mutate the section at configuration time
list = append(list, §ion.LocalModule{})
} else {
errString += fmt.Sprintf(" %s", s)
}
}
if errString != "" {
return nil, errors.New(fmt.Sprintf("invalid params:%s", errString))
}
return list, nil
}
================================================
FILE: pkg/goformatters/gci/internal/section/section.go
================================================
package section
import "github.com/daixiang0/gci/pkg/section"
func DefaultSections() section.SectionList {
return section.SectionList{Standard{}, section.Default{}}
}
================================================
FILE: pkg/goformatters/gci/internal/section/standard.go
================================================
package section
import (
"github.com/daixiang0/gci/pkg/parse"
"github.com/daixiang0/gci/pkg/specificity"
)
const StandardType = "standard"
type Standard struct{}
func (s Standard) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity {
if isStandard(spec.Path) {
return specificity.StandardMatch{}
}
return specificity.MisMatch{}
}
func (s Standard) String() string {
return StandardType
}
func (s Standard) Type() string {
return StandardType
}
func isStandard(pkg string) bool {
_, ok := standardPackages[pkg]
return ok
}
================================================
FILE: pkg/goformatters/gci/internal/section/standard_list.go
================================================
package section
// Code generated based on go1.26.0 X:boringcrypto,arenas,jsonv2,runtimesecret. DO NOT EDIT.
var standardPackages = map[string]struct{}{
"archive/tar": {},
"archive/zip": {},
"arena": {},
"bufio": {},
"bytes": {},
"cmp": {},
"compress/bzip2": {},
"compress/flate": {},
"compress/gzip": {},
"compress/lzw": {},
"compress/zlib": {},
"container/heap": {},
"container/list": {},
"container/ring": {},
"context": {},
"crypto": {},
"crypto/aes": {},
"crypto/boring": {},
"crypto/cipher": {},
"crypto/des": {},
"crypto/dsa": {},
"crypto/ecdh": {},
"crypto/ecdsa": {},
"crypto/ed25519": {},
"crypto/elliptic": {},
"crypto/fips140": {},
"crypto/hkdf": {},
"crypto/hmac": {},
"crypto/hpke": {},
"crypto/md5": {},
"crypto/mlkem": {},
"crypto/mlkem/mlkemtest": {},
"crypto/pbkdf2": {},
"crypto/rand": {},
"crypto/rc4": {},
"crypto/rsa": {},
"crypto/sha1": {},
"crypto/sha256": {},
"crypto/sha3": {},
"crypto/sha512": {},
"crypto/subtle": {},
"crypto/tls": {},
"crypto/tls/fipsonly": {},
"crypto/x509": {},
"crypto/x509/pkix": {},
"database/sql": {},
"database/sql/driver": {},
"debug/buildinfo": {},
"debug/dwarf": {},
"debug/elf": {},
"debug/gosym": {},
"debug/macho": {},
"debug/pe": {},
"debug/plan9obj": {},
"embed": {},
"encoding": {},
"encoding/ascii85": {},
"encoding/asn1": {},
"encoding/base32": {},
"encoding/base64": {},
"encoding/binary": {},
"encoding/csv": {},
"encoding/gob": {},
"encoding/hex": {},
"encoding/json": {},
"encoding/json/jsontext": {},
"encoding/json/v2": {},
"encoding/pem": {},
"encoding/xml": {},
"errors": {},
"expvar": {},
"flag": {},
"fmt": {},
"go/ast": {},
"go/build": {},
"go/build/constraint": {},
"go/constant": {},
"go/doc": {},
"go/doc/comment": {},
"go/format": {},
"go/importer": {},
"go/parser": {},
"go/printer": {},
"go/scanner": {},
"go/token": {},
"go/types": {},
"go/version": {},
"hash": {},
"hash/adler32": {},
"hash/crc32": {},
"hash/crc64": {},
"hash/fnv": {},
"hash/maphash": {},
"html": {},
"html/template": {},
"image": {},
"image/color": {},
"image/color/palette": {},
"image/draw": {},
"image/gif": {},
"image/jpeg": {},
"image/png": {},
"index/suffixarray": {},
"io": {},
"io/fs": {},
"io/ioutil": {},
"iter": {},
"log": {},
"log/slog": {},
"log/syslog": {},
"maps": {},
"math": {},
"math/big": {},
"math/bits": {},
"math/cmplx": {},
"math/rand": {},
"math/rand/v2": {},
"mime": {},
"mime/multipart": {},
"mime/quotedprintable": {},
"net": {},
"net/http": {},
"net/http/cgi": {},
"net/http/cookiejar": {},
"net/http/fcgi": {},
"net/http/httptest": {},
"net/http/httptrace": {},
"net/http/httputil": {},
"net/http/pprof": {},
"net/mail": {},
"net/netip": {},
"net/rpc": {},
"net/rpc/jsonrpc": {},
"net/smtp": {},
"net/textproto": {},
"net/url": {},
"os": {},
"os/exec": {},
"os/signal": {},
"os/user": {},
"path": {},
"path/filepath": {},
"plugin": {},
"reflect": {},
"regexp": {},
"regexp/syntax": {},
"runtime": {},
"runtime/cgo": {},
"runtime/coverage": {},
"runtime/debug": {},
"runtime/metrics": {},
"runtime/pprof": {},
"runtime/race": {},
"runtime/secret": {},
"runtime/trace": {},
"slices": {},
"sort": {},
"strconv": {},
"strings": {},
"structs": {},
"sync": {},
"sync/atomic": {},
"syscall": {},
"syscall/js": {},
"testing": {},
"testing/cryptotest": {},
"testing/fstest": {},
"testing/iotest": {},
"testing/quick": {},
"testing/slogtest": {},
"testing/synctest": {},
"text/scanner": {},
"text/tabwriter": {},
"text/template": {},
"text/template/parse": {},
"time": {},
"time/tzdata": {},
"unicode": {},
"unicode/utf16": {},
"unicode/utf8": {},
"unique": {},
"unsafe": {},
"weak": {},
}
================================================
FILE: pkg/goformatters/gofmt/gofmt.go
================================================
package gofmt
import (
"github.com/golangci/gofmt/gofmt"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
const Name = "gofmt"
type Formatter struct {
options gofmt.Options
}
func New(settings *config.GoFmtSettings) *Formatter {
options := gofmt.Options{}
if settings != nil {
options.NeedSimplify = settings.Simplify
for _, rule := range settings.RewriteRules {
options.RewriteRules = append(options.RewriteRules, gofmt.RewriteRule(rule))
}
}
return &Formatter{options: options}
}
func (*Formatter) Name() string {
return Name
}
func (f *Formatter) Format(filename string, src []byte) ([]byte, error) {
return gofmt.Source(filename, src, f.options)
}
================================================
FILE: pkg/goformatters/gofumpt/gofumpt.go
================================================
package gofumpt
import (
"strings"
gofumpt "mvdan.cc/gofumpt/format"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
const Name = "gofumpt"
type Formatter struct {
options gofumpt.Options
}
func New(settings *config.GoFumptSettings, goVersion string) *Formatter {
var options gofumpt.Options
if settings != nil {
options = gofumpt.Options{
LangVersion: getLangVersion(goVersion),
ModulePath: settings.ModulePath,
ExtraRules: settings.ExtraRules,
}
}
return &Formatter{options: options}
}
func (*Formatter) Name() string {
return Name
}
func (f *Formatter) Format(_ string, src []byte) ([]byte, error) {
return gofumpt.Source(src, f.options)
}
func getLangVersion(v string) string {
return "go" + strings.TrimPrefix(v, "go")
}
================================================
FILE: pkg/goformatters/goimports/goimports.go
================================================
package goimports
import (
"strings"
"golang.org/x/tools/imports"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
const Name = "goimports"
type Formatter struct{}
func New(settings *config.GoImportsSettings) *Formatter {
if settings != nil {
imports.LocalPrefix = strings.Join(settings.LocalPrefixes, ",")
}
return &Formatter{}
}
func (*Formatter) Name() string {
return Name
}
func (*Formatter) Format(filename string, src []byte) ([]byte, error) {
// The `imports.LocalPrefix` (`settings.LocalPrefixes`) is a global var.
return imports.Process(filename, src, nil)
}
================================================
FILE: pkg/goformatters/golines/golines.go
================================================
package golines
import (
"github.com/golangci/golines/shorten"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
const Name = "golines"
type Formatter struct {
shortener *shorten.Shortener
}
func New(settings *config.GoLinesSettings) *Formatter {
cfg := &shorten.Config{}
if settings != nil {
cfg = &shorten.Config{
MaxLen: settings.MaxLen,
TabLen: settings.TabLen,
KeepAnnotations: false, // golines debug (not usable inside golangci-lint)
ShortenComments: settings.ShortenComments,
ReformatTags: settings.ReformatTags,
DotFile: "", // golines debug (not usable inside golangci-lint)
ChainSplitDots: settings.ChainSplitDots,
}
}
return &Formatter{shortener: shorten.NewShortener(cfg)}
}
func (*Formatter) Name() string {
return Name
}
func (f *Formatter) Format(_ string, src []byte) ([]byte, error) {
return f.shortener.Process(src)
}
================================================
FILE: pkg/goformatters/internal/commons.go
================================================
package internal
import "github.com/golangci/golangci-lint/v2/pkg/logutils"
// FormatterLogger must be used only when the context logger is not available.
var FormatterLogger = logutils.NewStderrLog(logutils.DebugKeyFormatter)
================================================
FILE: pkg/goformatters/internal/diff.go
================================================
package internal
import (
"bytes"
"fmt"
"go/ast"
"go/token"
"slices"
"strings"
diffpkg "github.com/sourcegraph/go-diff/diff"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type Change struct {
From, To int
NewLines []string
}
type diffLineType string
const (
diffLineAdded diffLineType = "added"
diffLineOriginal diffLineType = "original"
diffLineDeleted diffLineType = "deleted"
)
type diffLine struct {
originalNumber int // 1-based original line number
typ diffLineType
data string // "+" or "-" stripped line
}
type hunkChangesParser struct {
// needed because we merge currently added lines with the last original line
lastOriginalLine *diffLine
// if the first line of diff is an adding we save all additions to replacementLinesToPrepend
replacementLinesToPrepend []string
log logutils.Log
changes []Change
}
func (p *hunkChangesParser) parse(h *diffpkg.Hunk) []Change {
lines := parseDiffLines(h)
for i := 0; i < len(lines); {
line := lines[i]
if line.typ == diffLineOriginal {
p.handleOriginalLine(lines, line, &i)
continue
}
var deletedLines []diffLine
for ; i < len(lines) && lines[i].typ == diffLineDeleted; i++ {
deletedLines = append(deletedLines, lines[i])
}
var addedLines []string
for ; i < len(lines) && lines[i].typ == diffLineAdded; i++ {
addedLines = append(addedLines, lines[i].data)
}
if len(deletedLines) != 0 {
p.handleDeletedLines(deletedLines, addedLines)
continue
}
// no deletions, only additions
p.handleAddedOnlyLines(addedLines)
}
if len(p.replacementLinesToPrepend) != 0 {
p.log.Infof("The diff contains only additions: no original or deleted lines: %#v", lines)
return nil
}
return p.changes
}
func (p *hunkChangesParser) handleOriginalLine(lines []diffLine, line diffLine, i *int) {
if len(p.replacementLinesToPrepend) == 0 {
p.lastOriginalLine = &line
*i++
return
}
// check following added lines for the case:
// + added line 1
// original line
// + added line 2
*i++
var followingAddedLines []string
for ; *i < len(lines) && lines[*i].typ == diffLineAdded; *i++ {
followingAddedLines = append(followingAddedLines, lines[*i].data)
}
change := Change{
From: line.originalNumber,
To: line.originalNumber,
NewLines: slices.Concat(p.replacementLinesToPrepend, []string{line.data}, followingAddedLines),
}
p.changes = append(p.changes, change)
p.replacementLinesToPrepend = nil
p.lastOriginalLine = &line
}
func (p *hunkChangesParser) handleDeletedLines(deletedLines []diffLine, addedLines []string) {
change := Change{
From: deletedLines[0].originalNumber,
To: deletedLines[len(deletedLines)-1].originalNumber,
}
switch {
case len(addedLines) != 0:
change.NewLines = slices.Concat(p.replacementLinesToPrepend, addedLines)
p.replacementLinesToPrepend = nil
case len(p.replacementLinesToPrepend) != 0:
// delete-only change with possible prepending
change.NewLines = slices.Clone(p.replacementLinesToPrepend)
p.replacementLinesToPrepend = nil
}
p.changes = append(p.changes, change)
}
func (p *hunkChangesParser) handleAddedOnlyLines(addedLines []string) {
if p.lastOriginalLine == nil {
// the first line is added; the diff looks like:
// 1. + ...
// 2. - ...
// or
// 1. + ...
// 2. ...
p.replacementLinesToPrepend = addedLines
return
}
// add-only change merged into the last original line with possible prepending
change := Change{
From: p.lastOriginalLine.originalNumber,
To: p.lastOriginalLine.originalNumber,
NewLines: slices.Concat(p.replacementLinesToPrepend, []string{p.lastOriginalLine.data}, addedLines),
}
p.changes = append(p.changes, change)
p.replacementLinesToPrepend = nil
}
func parseDiffLines(h *diffpkg.Hunk) []diffLine {
lines := bytes.Split(h.Body, []byte{'\n'})
currentOriginalLineNumber := int(h.OrigStartLine)
var diffLines []diffLine
for i, line := range lines {
dl := diffLine{
originalNumber: currentOriginalLineNumber,
}
if i == len(lines)-1 && len(line) == 0 {
// handle last \n: don't add an empty original line
break
}
lineStr := string(line)
switch {
case strings.HasPrefix(lineStr, "-"):
dl.typ = diffLineDeleted
dl.data = strings.TrimPrefix(lineStr, "-")
currentOriginalLineNumber++
case strings.HasPrefix(lineStr, "+"):
dl.typ = diffLineAdded
dl.data = strings.TrimPrefix(lineStr, "+")
default:
dl.typ = diffLineOriginal
dl.data = strings.TrimPrefix(lineStr, " ")
currentOriginalLineNumber++
}
diffLines = append(diffLines, dl)
}
// if > 0, then the original file had a 'No newline at end of file' mark
if h.OrigNoNewlineAt > 0 {
dl := diffLine{
originalNumber: currentOriginalLineNumber + 1,
typ: diffLineAdded,
data: "",
}
diffLines = append(diffLines, dl)
}
return diffLines
}
func ExtractDiagnosticFromPatch(
pass *analysis.Pass,
file *ast.File,
patch []byte,
logger logutils.Log,
) error {
diffs, err := diffpkg.ParseMultiFileDiff(patch)
if err != nil {
return fmt.Errorf("can't parse patch: %w", err)
}
if len(diffs) == 0 {
return fmt.Errorf("got no diffs from patch parser: %s", patch)
}
ft := pass.Fset.File(file.Pos())
adjLine := pass.Fset.PositionFor(file.Pos(), false).Line - pass.Fset.PositionFor(file.Pos(), true).Line
for _, d := range diffs {
if len(d.Hunks) == 0 {
logger.Warnf("Got no hunks in diff %+v", d)
continue
}
for _, hunk := range d.Hunks {
p := hunkChangesParser{log: logger}
changes := p.parse(hunk)
for _, change := range changes {
pass.Report(toDiagnostic(ft, change, adjLine))
}
}
}
return nil
}
func toDiagnostic(ft *token.File, change Change, adjLine int) analysis.Diagnostic {
from := min(change.From+adjLine, ft.LineCount())
start := ft.LineStart(from)
end := goanalysis.EndOfLinePos(ft, change.To+adjLine)
return analysis.Diagnostic{
Pos: start,
End: end,
Message: "File is not properly formatted",
SuggestedFixes: []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: start,
End: end,
NewText: []byte(strings.Join(change.NewLines, "\n")),
}},
}},
}
}
================================================
FILE: pkg/goformatters/internal/diff_test.go
================================================
package internal
import (
"os"
"path/filepath"
"testing"
diffpkg "github.com/sourcegraph/go-diff/diff"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
func Test_parse(t *testing.T) {
testCases := []struct {
diff string
log logutils.Log
expected []Change
}{
{
diff: "delete_last_line.diff",
expected: []Change{{
From: 10,
To: 10,
}},
},
{
diff: "delete_only_first_lines.diff",
expected: []Change{{
From: 1,
To: 2,
}},
},
{
diff: "add_only.diff",
expected: []Change{{
From: 2,
To: 2,
NewLines: []string{
"",
"// added line",
},
}},
},
{
diff: "add_only_different_lines.diff",
expected: []Change{
{
From: 4,
To: 4,
NewLines: []string{
"",
"// add line 1",
"",
},
},
{
From: 7,
To: 7,
NewLines: []string{
" Errorf(format string, args ...interface{})",
" // add line 2",
},
},
},
},
{
diff: "add_only_in_all_diff.diff",
log: logutils.NewMockLog().
OnInfof("The diff contains only additions: no original or deleted lines: %#v", mock.Anything),
},
{
diff: "add_only_multiple_lines.diff",
expected: []Change{{
From: 4,
To: 4,
NewLines: []string{
"",
"// add line 1",
"// add line 2",
"",
},
}},
},
{
diff: "add_only_on_first_line.diff",
expected: []Change{{
From: 1,
To: 1,
NewLines: []string{
"// added line",
"package logutil",
},
}},
},
{
diff: "add_only_on_first_line_with_shared_original_line.diff",
expected: []Change{{
From: 1,
To: 1,
NewLines: []string{
"// added line 1",
"package logutil",
"// added line 2",
"// added line 3",
},
}},
},
{
diff: "replace_line.diff",
expected: []Change{{
From: 1,
To: 1,
NewLines: []string{"package test2"},
}},
},
{
diff: "replace_line_after_first_line_adding.diff",
expected: []Change{
{
From: 1,
To: 1,
NewLines: []string{
"// added line",
"package logutil",
},
},
{
From: 3,
To: 3,
NewLines: []string{
"// changed line",
},
},
},
},
{
diff: "gofmt_diff.diff",
expected: []Change{
{
From: 4,
To: 6,
NewLines: []string{
"func gofmt(a, b int) int {",
" if a != b {",
" return 1",
},
},
{
From: 8,
To: 8,
NewLines: []string{
" return 2",
},
},
},
},
}
for _, test := range testCases {
t.Run(test.diff, func(t *testing.T) {
t.Parallel()
diff, err := os.ReadFile(filepath.Join("testdata", test.diff))
require.NoError(t, err)
diffs, err := diffpkg.ParseMultiFileDiff(diff)
if err != nil {
require.NoError(t, err)
}
require.Len(t, diffs, 1)
hunks := diffs[0].Hunks
assert.NotEmpty(t, hunks)
var changes []Change
for _, hunk := range hunks {
p := hunkChangesParser{log: test.log}
changes = append(changes, p.parse(hunk)...)
}
assert.Equal(t, test.expected, changes)
})
}
}
================================================
FILE: pkg/goformatters/internal/testdata/add_only.diff
================================================
diff --git a/internal/shared/logutil/log.go b/internal/shared/logutil/log.go
index 258b340..43d04bf 100644
--- a/internal/shared/logutil/log.go
+++ b/internal/shared/logutil/log.go
@@ -1,5 +1,6 @@
package logutil
+// added line
type Func func(format string, args ...interface{})
type Log interface {
================================================
FILE: pkg/goformatters/internal/testdata/add_only_different_lines.diff
================================================
diff --git a/internal/shared/logutil/log.go b/internal/shared/logutil/log.go
index 258b340..e5ed2ad 100644
--- a/internal/shared/logutil/log.go
+++ b/internal/shared/logutil/log.go
@@ -2,9 +2,12 @@ package logutil
type Func func(format string, args ...interface{})
+// add line 1
+
type Log interface {
Fatalf(format string, args ...interface{})
Errorf(format string, args ...interface{})
+ // add line 2
Warnf(format string, args ...interface{})
Infof(format string, args ...interface{})
Debugf(key string, format string, args ...interface{})
================================================
FILE: pkg/goformatters/internal/testdata/add_only_in_all_diff.diff
================================================
diff --git a/test.go b/test.go
new file mode 100644
index 0000000..6399915
--- /dev/null
+++ b/test.go
@@ -0,0 +1,3 @@
+package test
+
+// line
================================================
FILE: pkg/goformatters/internal/testdata/add_only_multiple_lines.diff
================================================
diff --git a/internal/shared/logutil/log.go b/internal/shared/logutil/log.go
index 258b340..3b83a94 100644
--- a/internal/shared/logutil/log.go
+++ b/internal/shared/logutil/log.go
@@ -2,6 +2,9 @@ package logutil
type Func func(format string, args ...interface{})
+// add line 1
+// add line 2
+
type Log interface {
Fatalf(format string, args ...interface{})
Errorf(format string, args ...interface{})
================================================
FILE: pkg/goformatters/internal/testdata/add_only_on_first_line.diff
================================================
diff --git a/internal/shared/logutil/log.go b/internal/shared/logutil/log.go
index 258b340..97e6660 100644
--- a/internal/shared/logutil/log.go
+++ b/internal/shared/logutil/log.go
@@ -1,3 +1,4 @@
+// added line
package logutil
type Func func(format string, args ...interface{})
================================================
FILE: pkg/goformatters/internal/testdata/add_only_on_first_line_with_shared_original_line.diff
================================================
diff --git a/internal/shared/logutil/log.go b/internal/shared/logutil/log.go
index 258b340..7ff80c9 100644
--- a/internal/shared/logutil/log.go
+++ b/internal/shared/logutil/log.go
@@ -1,4 +1,7 @@
+// added line 1
package logutil
+// added line 2
+// added line 3
type Func func(format string, args ...interface{})
================================================
FILE: pkg/goformatters/internal/testdata/delete_last_line.diff
================================================
diff --git i/main.go w/main.go
index ef3cbb7..52a7925 100644
--- i/main.go
+++ w/main.go
@@ -7,4 +7,3 @@ import (
func main() {
fmt.Println("hello world")
}
-
================================================
FILE: pkg/goformatters/internal/testdata/delete_only_first_lines.diff
================================================
diff --git a/internal/shared/logutil/log.go b/internal/shared/logutil/log.go
index 258b340..0fb554e 100644
--- a/internal/shared/logutil/log.go
+++ b/internal/shared/logutil/log.go
@@ -1,5 +1,3 @@
-package logutil
-
type Func func(format string, args ...interface{})
type Log interface {
================================================
FILE: pkg/goformatters/internal/testdata/gofmt_diff.diff
================================================
diff --git a/gofmt.go b/gofmt.go
index 2c9f78d..c0d5791 100644
--- a/gofmt.go
+++ b/gofmt.go
@@ -1,9 +1,9 @@
//golangcitest:args -Egofmt
package p
- func gofmt(a, b int) int {
- if a != b {
- return 1
+func gofmt(a, b int) int {
+ if a != b {
+ return 1
}
- return 2
+ return 2
}
================================================
FILE: pkg/goformatters/internal/testdata/replace_line.diff
================================================
diff --git a/internal/shared/logutil/log.go b/internal/shared/logutil/log.go
index 258b340..c2a8516 100644
--- a/internal/shared/logutil/log.go
+++ b/internal/shared/logutil/log.go
@@ -1,4 +1,4 @@
-package logutil
+package test2
type Func func(format string, args ...interface{})
================================================
FILE: pkg/goformatters/internal/testdata/replace_line_after_first_line_adding.diff
================================================
diff --git a/internal/shared/logutil/log.go b/internal/shared/logutil/log.go
index 258b340..43fc0de 100644
--- a/internal/shared/logutil/log.go
+++ b/internal/shared/logutil/log.go
@@ -1,6 +1,7 @@
+// added line
package logutil
-type Func func(format string, args ...interface{})
+// changed line
type Log interface {
Fatalf(format string, args ...interface{})
================================================
FILE: pkg/goformatters/meta_formatter.go
================================================
package goformatters
import (
"bytes"
"fmt"
"go/format"
"slices"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goformatters/gci"
"github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt"
"github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
"github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
"github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
"github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type MetaFormatter struct {
log logutils.Log
formatters []Formatter
}
func NewMetaFormatter(log logutils.Log, cfg *config.Formatters, runCfg *config.Run) (*MetaFormatter, error) {
for _, formatter := range cfg.Enable {
if !IsFormatter(formatter) {
return nil, fmt.Errorf("invalid formatter %q", formatter)
}
}
m := &MetaFormatter{log: log}
if slices.Contains(cfg.Enable, gofmt.Name) {
m.formatters = append(m.formatters, gofmt.New(&cfg.Settings.GoFmt))
}
if slices.Contains(cfg.Enable, gofumpt.Name) {
m.formatters = append(m.formatters, gofumpt.New(&cfg.Settings.GoFumpt, runCfg.Go))
}
if slices.Contains(cfg.Enable, goimports.Name) {
m.formatters = append(m.formatters, goimports.New(&cfg.Settings.GoImports))
}
if slices.Contains(cfg.Enable, swaggo.Name) {
m.formatters = append(m.formatters, swaggo.New())
}
// gci is a last because the only goal of gci is to handle imports.
if slices.Contains(cfg.Enable, gci.Name) {
formatter, err := gci.New(&cfg.Settings.Gci)
if err != nil {
return nil, fmt.Errorf("gci: creating formatter: %w", err)
}
m.formatters = append(m.formatters, formatter)
}
// golines calls `format.Source()` internally so no need to format after it.
if slices.Contains(cfg.Enable, golines.Name) {
m.formatters = append(m.formatters, golines.New(&cfg.Settings.GoLines))
}
return m, nil
}
func (m *MetaFormatter) Format(filename string, src []byte) []byte {
if len(m.formatters) == 0 {
data, err := format.Source(src)
if err != nil {
m.log.Warnf("(fmt) formatting file %s: %v", filename, err)
return src
}
return data
}
data := bytes.Clone(src)
for _, formatter := range m.formatters {
formatted, err := formatter.Format(filename, data)
if err != nil {
m.log.Warnf("(%s) formatting file %s: %v", formatter.Name(), filename, err)
continue
}
data = formatted
}
return data
}
func IsFormatter(name string) bool {
return slices.Contains([]string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name, swaggo.Name}, name)
}
================================================
FILE: pkg/goformatters/swaggo/swaggo.go
================================================
package swaggo
import "github.com/golangci/swaggoswag"
const Name = "swaggo"
type Formatter struct {
formatter *swaggoswag.Formatter
}
func New() *Formatter {
return &Formatter{
formatter: swaggoswag.NewFormatter(),
}
}
func (*Formatter) Name() string {
return Name
}
func (f *Formatter) Format(path string, src []byte) ([]byte, error) {
return f.formatter.Format(path, src)
}
================================================
FILE: pkg/golinters/arangolint/arangolint.go
================================================
package arangolint
import (
"go.augendre.info/arangolint/pkg/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(analyzer.NewAnalyzer()).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/arangolint/arangolint_integration_test.go
================================================
package arangolint
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/arangolint/testdata/arangolint.go
================================================
//golangcitest:args -Earangolint
package arangolint
import (
"context"
"github.com/arangodb/go-driver/v2/arangodb"
)
func _() {
ctx := context.Background()
arangoClient := arangodb.NewClient(nil)
db, _ := arangoClient.GetDatabase(ctx, "name", nil)
// direct nil
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, nil) // want "missing AllowImplicit option"
trx, _ := db.BeginTransaction(ctx, arangodb.TransactionCollections{}, nil) // want "missing AllowImplicit option"
_ = trx
// direct missing
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{LockTimeout: 0}) // want "missing AllowImplicit option"
trx, _ = db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{LockTimeout: 0}) // want "missing AllowImplicit option"
// direct false
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: false})
trx, _ = db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: false})
// direct true
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: true})
trx, _ = db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: true})
// direct with other fields
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: true, LockTimeout: 0})
trx, _ = db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: true, LockTimeout: 0})
}
================================================
FILE: pkg/golinters/arangolint/testdata/arangolint_cgo.go
================================================
//golangcitest:args -Earangolint
package arangolint
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"context"
"unsafe"
"github.com/arangodb/go-driver/v2/arangodb"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
ctx := context.Background()
arangoClient := arangodb.NewClient(nil)
db, _ := arangoClient.GetDatabase(ctx, "name", nil)
// direct nil
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, nil) // want "missing AllowImplicit option"
trx, _ := db.BeginTransaction(ctx, arangodb.TransactionCollections{}, nil) // want "missing AllowImplicit option"
_ = trx
// direct missing
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{LockTimeout: 0}) // want "missing AllowImplicit option"
trx, _ = db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{LockTimeout: 0}) // want "missing AllowImplicit option"
// direct false
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: false})
trx, _ = db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: false})
// direct true
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: true})
trx, _ = db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: true})
// direct with other fields
db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: true, LockTimeout: 0})
trx, _ = db.BeginTransaction(ctx, arangodb.TransactionCollections{}, &arangodb.BeginTransactionOptions{AllowImplicit: true, LockTimeout: 0})
}
================================================
FILE: pkg/golinters/arangolint/testdata/go.mod
================================================
module arangolint
go 1.25.0
require github.com/arangodb/go-driver/v2 v2.2.0
require (
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
github.com/dchest/siphash v1.2.3 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/kkdai/maglev v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rs/zerolog v1.34.0 // indirect
golang.org/x/net v0.46.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
)
================================================
FILE: pkg/golinters/arangolint/testdata/go.sum
================================================
github.com/arangodb/go-driver/v2 v2.2.0 h1:ndG0SVwT5kAslp62F1DBywA4KomcjNV78dROAix4chY=
github.com/arangodb/go-driver/v2 v2.2.0/go.mod h1:UzpvhTGK5UQpTy29UmJz2jciiq5khct6seRNiqClstI=
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g=
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/siphash v1.2.2/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kkdai/maglev v0.2.0 h1:w6DCW0kAA6fstZqXkrBrlgIC3jeIRXkjOYea/m6EK/Y=
github.com/kkdai/maglev v0.2.0/go.mod h1:d+mt8Lmt3uqi9aRb/BnPjzD0fy+ETs1vVXiGRnqHVZ4=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
================================================
FILE: pkg/golinters/asasalint/asasalint.go
================================================
package asasalint
import (
"github.com/alingse/asasalint"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.AsasalintSettings) *goanalysis.Linter {
cfg := asasalint.LinterSetting{}
if settings != nil {
cfg.Exclude = settings.Exclude
cfg.NoBuiltinExclusions = !settings.UseBuiltinExclusions
// Should be managed with `linters.exclusions.rules`.
cfg.IgnoreTest = false
}
analyzer, err := asasalint.NewAnalyzer(cfg)
if err != nil {
internal.LinterLogger.Fatalf("asasalint: create analyzer: %v", err)
}
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/asasalint/asasalint_integration_test.go
================================================
package asasalint
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/asasalint/testdata/asasalint.go
================================================
//golangcitest:args -Easasalint
package testdata
import "fmt"
func getArgsLength(args ...interface{}) int {
// this line will not report as error
fmt.Println(args)
return len(args)
}
func checkArgsLength(args ...interface{}) int {
return getArgsLength(args) // want `pass \[\]any as any to func getArgsLength func\(args \.\.\.interface\{\}\)`
}
func someCall() {
var a = []interface{}{1, 2, 3}
fmt.Println(checkArgsLength(a...) == getArgsLength(a)) // want `pass \[\]any as any to func getArgsLength func\(args \.\.\.interface\{\}\)`
fmt.Println(checkArgsLength(a...) == getArgsLength(a...))
}
================================================
FILE: pkg/golinters/asasalint/testdata/asasalint_cgo.go
================================================
//golangcitest:args -Easasalint
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func getArgsLength(args ...interface{}) int {
// this line will not report as error
fmt.Println(args)
return len(args)
}
func checkArgsLength(args ...interface{}) int {
return getArgsLength(args) // want `pass \[\]any as any to func getArgsLength func\(args \.\.\.interface\{\}\)`
}
func someCall() {
var a = []interface{}{1, 2, 3}
fmt.Println(checkArgsLength(a...) == getArgsLength(a)) // want `pass \[\]any as any to func getArgsLength func\(args \.\.\.interface\{\}\)`
fmt.Println(checkArgsLength(a...) == getArgsLength(a...))
}
================================================
FILE: pkg/golinters/asciicheck/asciicheck.go
================================================
package asciicheck
import (
"github.com/golangci/asciicheck"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(asciicheck.NewAnalyzer()).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/asciicheck/asciicheck_integration_test.go
================================================
package asciicheck
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/asciicheck/testdata/asciicheck.go
================================================
//golangcitest:args -Easciicheck
package testdata
import (
"fmt"
"time"
)
type AsciicheckTеstStruct struct { // want `identifier "AsciicheckTеstStruct" contain non-ASCII character: U\+0435 'е'`
Date time.Time
}
type AsciicheckField struct{}
type AsciicheckJustStruct struct {
Tеst AsciicheckField // want `identifier "Tеst" contain non-ASCII character: U\+0435 'е'`
}
func AsciicheckTеstFunc() { // want `identifier "AsciicheckTеstFunc" contain non-ASCII character: U\+0435 'е'`
var tеstVar int // want `identifier "tеstVar" contain non-ASCII character: U\+0435 'е'`
tеstVar = 0
fmt.Println(tеstVar)
}
================================================
FILE: pkg/golinters/asciicheck/testdata/asciicheck_cgo.go
================================================
//golangcitest:args -Easciicheck
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"time"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type AsciicheckTеstStruct struct { // want `identifier "AsciicheckTеstStruct" contain non-ASCII character: U\+0435 'е'`
Date time.Time
}
type AsciicheckField struct{}
type AsciicheckJustStruct struct {
Tеst AsciicheckField // want `identifier "Tеst" contain non-ASCII character: U\+0435 'е'`
}
func AsciicheckTеstFunc() { // want `identifier "AsciicheckTеstFunc" contain non-ASCII character: U\+0435 'е'`
var tеstVar int // want `identifier "tеstVar" contain non-ASCII character: U\+0435 'е'`
tеstVar = 0
fmt.Println(tеstVar)
}
================================================
FILE: pkg/golinters/bidichk/bidichk.go
================================================
package bidichk
import (
"strings"
"github.com/breml/bidichk/pkg/bidichk"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.BiDiChkSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
var opts []string
if settings.LeftToRightEmbedding {
opts = append(opts, "LEFT-TO-RIGHT-EMBEDDING")
}
if settings.RightToLeftEmbedding {
opts = append(opts, "RIGHT-TO-LEFT-EMBEDDING")
}
if settings.PopDirectionalFormatting {
opts = append(opts, "POP-DIRECTIONAL-FORMATTING")
}
if settings.LeftToRightOverride {
opts = append(opts, "LEFT-TO-RIGHT-OVERRIDE")
}
if settings.RightToLeftOverride {
opts = append(opts, "RIGHT-TO-LEFT-OVERRIDE")
}
if settings.LeftToRightIsolate {
opts = append(opts, "LEFT-TO-RIGHT-ISOLATE")
}
if settings.RightToLeftIsolate {
opts = append(opts, "RIGHT-TO-LEFT-ISOLATE")
}
if settings.FirstStrongIsolate {
opts = append(opts, "FIRST-STRONG-ISOLATE")
}
if settings.PopDirectionalIsolate {
opts = append(opts, "POP-DIRECTIONAL-ISOLATE")
}
cfg = map[string]any{
"disallowed-runes": strings.Join(opts, ","),
}
}
return goanalysis.
NewLinterFromAnalyzer(bidichk.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/bidichk/bidichk_integration_test.go
================================================
package bidichk
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/bidichk/testdata/bidichk.go
================================================
//golangcitest:args -Ebidichk
package testdata
import "fmt"
func main() {
fmt.Println("LEFT-TO-RIGHT-OVERRIDE: '', it is between the single quotes, but it is not visible with a regular editor") // want "found dangerous unicode character sequence LEFT-TO-RIGHT-OVERRIDE"
}
================================================
FILE: pkg/golinters/bidichk/testdata/bidichk_cgo.go
================================================
//golangcitest:args -Ebidichk
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
fmt.Println("LEFT-TO-RIGHT-OVERRIDE: '', it is between the single quotes, but it is not visible with a regular editor") // want "found dangerous unicode character sequence LEFT-TO-RIGHT-OVERRIDE"
}
================================================
FILE: pkg/golinters/bodyclose/bodyclose.go
================================================
package bodyclose
import (
"github.com/timakin/bodyclose/passes/bodyclose"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(bodyclose.Analyzer).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/bodyclose/bodyclose_integration_test.go
================================================
package bodyclose
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/bodyclose/testdata/bodyclose.go
================================================
//golangcitest:args -Ebodyclose
package testdata
import (
"io/ioutil"
"net/http"
)
func BodycloseNotClosed() {
resp, _ := http.Get("https://google.com") // want "response body must be closed"
_, _ = ioutil.ReadAll(resp.Body)
}
================================================
FILE: pkg/golinters/bodyclose/testdata/bodyclose_cgo.go
================================================
//golangcitest:args -Ebodyclose
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"io/ioutil"
"net/http"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func BodycloseNotClosed() {
resp, _ := http.Get("https://google.com") // want "response body must be closed"
_, _ = ioutil.ReadAll(resp.Body)
}
================================================
FILE: pkg/golinters/canonicalheader/canonicalheader.go
================================================
package canonicalheader
import (
"github.com/lasiar/canonicalheader"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(canonicalheader.Analyzer).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/canonicalheader/canonicalheader_test.go
================================================
package canonicalheader_test
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/canonicalheader/testdata/canonicalheader.go
================================================
//golangcitest:args -Ecanonicalheader
package testdata
import "net/http"
func canonicalheader() {
v := http.Header{}
v.Get("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Set("Test-HEader", "value") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Add("Test-HEader", "value") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Del("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Values("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Values("Sec-WebSocket-Accept")
v.Set("Test-Header", "value")
v.Add("Test-Header", "value")
v.Del("Test-Header")
v.Values("Test-Header")
}
================================================
FILE: pkg/golinters/canonicalheader/testdata/canonicalheader_cgo.go
================================================
//golangcitest:args -Ecanonicalheader
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"net/http"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func canonicalheader() {
v := http.Header{}
v.Get("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Set("Test-HEader", "value") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Add("Test-HEader", "value") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Del("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Values("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"`
v.Values("Sec-WebSocket-Accept")
v.Set("Test-Header", "value")
v.Add("Test-Header", "value")
v.Del("Test-Header")
v.Values("Test-Header")
}
================================================
FILE: pkg/golinters/canonicalheader/testdata/fix/in/canonicalheader.go
================================================
//golangcitest:args -Ecanonicalheader
//golangcitest:expected_exitcode 0
package testdata
import "net/http"
func canonicalheader() {
v := http.Header{}
v.Get("Test-HEader")
v.Set("Test-HEader", "value")
v.Add("Test-HEader", "value")
v.Del("Test-HEader")
v.Values("Test-HEader")
v.Values("Sec-WebSocket-Accept")
v.Set("Test-Header", "value")
v.Add("Test-Header", "value")
v.Del("Test-Header")
v.Values("Test-Header")
}
================================================
FILE: pkg/golinters/canonicalheader/testdata/fix/out/canonicalheader.go
================================================
//golangcitest:args -Ecanonicalheader
//golangcitest:expected_exitcode 0
package testdata
import "net/http"
func canonicalheader() {
v := http.Header{}
v.Get("Test-Header")
v.Set("Test-Header", "value")
v.Add("Test-Header", "value")
v.Del("Test-Header")
v.Values("Test-Header")
v.Values("Sec-WebSocket-Accept")
v.Set("Test-Header", "value")
v.Add("Test-Header", "value")
v.Del("Test-Header")
v.Values("Test-Header")
}
================================================
FILE: pkg/golinters/containedctx/containedctx.go
================================================
package containedctx
import (
"github.com/sivchari/containedctx"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(containedctx.Analyzer).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/containedctx/containedctx_integration_test.go
================================================
package containedctx
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/containedctx/testdata/containedctx.go
================================================
//golangcitest:args -Econtainedctx
package testdata
import "context"
type ok struct {
i int
s string
}
type ng struct {
ctx context.Context // want "found a struct that contains a context.Context field"
}
type empty struct{}
================================================
FILE: pkg/golinters/containedctx/testdata/containedctx_cgo.go
================================================
//golangcitest:args -Econtainedctx
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"context"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type ok struct {
i int
s string
}
type ng struct {
ctx context.Context // want "found a struct that contains a context.Context field"
}
type empty struct{}
================================================
FILE: pkg/golinters/contextcheck/contextcheck.go
================================================
package contextcheck
import (
"github.com/kkHAIKE/contextcheck"
"golang.org/x/tools/go/analysis/passes/ctrlflow"
"golang.org/x/tools/go/analysis/passes/inspect"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
)
func New() *goanalysis.Linter {
analyzer := contextcheck.NewAnalyzer(contextcheck.Configuration{})
// TODO(ldez) there is a problem with this linter:
// I think the problem related to facts.
// The BuildSSA pass has been changed inside (0.39.0):
// https://github.com/golang/tools/commit/b74c09864920a69a4d2f6ef0ecb4f9cff226893a
analyzer.Requires = append(analyzer.Requires, ctrlflow.Analyzer, inspect.Analyzer)
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithContextSetter(func(lintCtx *linter.Context) {
analyzer.Run = contextcheck.NewRun(lintCtx.Packages, false)
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/contextcheck/contextcheck_integration_test.go
================================================
package contextcheck
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/contextcheck/testdata/contextcheck.go
================================================
//golangcitest:args -Econtextcheck
package testdata
import "context"
type MyString string
func contextcheckCase1(ctx context.Context) {
funcWithoutCtx() // want "Function `funcWithoutCtx` should pass the context parameter"
}
func contextcheckCase2(ctx context.Context) {
ctx = context.WithValue(ctx, MyString("aaa"), "aaaaaa")
funcWithCtx(ctx)
defer func() {
funcWithCtx(ctx)
}()
func(ctx context.Context) {
funcWithCtx(ctx)
}(ctx)
funcWithCtx(context.Background()) // want "Non-inherited new context, use function like `context.WithXXX` instead"
}
func contextcheckCase3(ctx context.Context) {
func() {
funcWithCtx(ctx)
}()
ctx = context.Background() // want "Non-inherited new context, use function like `context.WithXXX` instead"
funcWithCtx(ctx)
}
func contextcheckCase4(ctx context.Context) {
ctx, cancel := getNewCtx(ctx)
defer cancel()
funcWithCtx(ctx)
}
func funcWithCtx(ctx context.Context) {}
func funcWithoutCtx() {
funcWithCtx(context.TODO())
}
func getNewCtx(ctx context.Context) (newCtx context.Context, cancel context.CancelFunc) {
return context.WithCancel(ctx)
}
================================================
FILE: pkg/golinters/contextcheck/testdata/contextcheck_cgo.go
================================================
//golangcitest:args -Econtextcheck
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"context"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func contextcheckCase1(ctx context.Context) {
funcWithoutCtx() // want "Function `funcWithoutCtx` should pass the context parameter"
}
func funcWithCtx(ctx context.Context) {}
func funcWithoutCtx() {
funcWithCtx(context.TODO())
}
================================================
FILE: pkg/golinters/copyloopvar/copyloopvar.go
================================================
package copyloopvar
import (
"github.com/karamaru-alpha/copyloopvar"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.CopyLoopVarSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"check-alias": settings.CheckAlias,
}
}
return goanalysis.
NewLinterFromAnalyzer(copyloopvar.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/copyloopvar/copyloopvar_integration_test.go
================================================
package copyloopvar
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/copyloopvar/testdata/copyloopvar.go
================================================
//go:build go1.22
//golangcitest:args -Ecopyloopvar
package testdata
import "fmt"
func copyloopvarCase1() {
slice := []int{1, 2, 3}
fns := make([]func(), 0, len(slice)*2)
for i, v := range slice {
i := i // want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
v := v // want `The copy of the 'for' variable "v" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(v)
})
_v := v
_ = _v
}
for _, fn := range fns {
fn()
}
}
func copyloopvarCase2() {
loopCount := 3
fns := make([]func(), 0, loopCount)
for i := 1; i <= loopCount; i++ {
i := i // want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
}
for _, fn := range fns {
fn()
}
}
================================================
FILE: pkg/golinters/copyloopvar/testdata/copyloopvar.yml
================================================
version: "2"
linters:
settings:
copyloopvar:
check-alias: true
================================================
FILE: pkg/golinters/copyloopvar/testdata/copyloopvar_cgo.go
================================================
//go:build go1.22
//golangcitest:args -Ecopyloopvar
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func copyloopvarCase2() {
loopCount := 3
fns := make([]func(), 0, loopCount)
for i := 1; i <= loopCount; i++ {
i := i // want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
}
for _, fn := range fns {
fn()
}
}
================================================
FILE: pkg/golinters/copyloopvar/testdata/copyloopvar_custom.go
================================================
//go:build go1.22
//golangcitest:args -Ecopyloopvar
//golangcitest:config_path testdata/copyloopvar.yml
package testdata
import "fmt"
func copyloopvarCase1() {
slice := []int{1, 2, 3}
fns := make([]func(), 0, len(slice)*2)
for i, v := range slice {
i := i // want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
v := v // want `The copy of the 'for' variable "v" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(v)
})
_v := v // want `The copy of the 'for' variable "v" can be deleted \(Go 1\.22\+\)`
_ = _v
}
for _, fn := range fns {
fn()
}
}
func copyloopvarCase2() {
loopCount := 3
fns := make([]func(), 0, loopCount)
for i := 1; i <= loopCount; i++ {
i := i // want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
}
for _, fn := range fns {
fn()
}
}
================================================
FILE: pkg/golinters/copyloopvar/testdata/fix/in/copyloopvar.go
================================================
//golangcitest:args -Ecopyloopvar
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
func _() {
slice := []int{1, 2, 3}
fns := make([]func(), 0, len(slice)*2)
for i, v := range slice {
i := i // want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
v := v // want `The copy of the 'for' variable "v" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(v)
})
_v := v
_ = _v
}
for _, fn := range fns {
fn()
}
}
func _() {
loopCount := 3
fns := make([]func(), 0, loopCount)
for i := 1; i <= loopCount; i++ {
i := i // want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
}
for _, fn := range fns {
fn()
}
}
================================================
FILE: pkg/golinters/copyloopvar/testdata/fix/out/copyloopvar.go
================================================
//golangcitest:args -Ecopyloopvar
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
func _() {
slice := []int{1, 2, 3}
fns := make([]func(), 0, len(slice)*2)
for i, v := range slice {
// want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
// want `The copy of the 'for' variable "v" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(v)
})
_v := v
_ = _v
}
for _, fn := range fns {
fn()
}
}
func _() {
loopCount := 3
fns := make([]func(), 0, loopCount)
for i := 1; i <= loopCount; i++ {
// want `The copy of the 'for' variable "i" can be deleted \(Go 1\.22\+\)`
fns = append(fns, func() {
fmt.Println(i)
})
}
for _, fn := range fns {
fn()
}
}
================================================
FILE: pkg/golinters/cyclop/cyclop.go
================================================
package cyclop
import (
"github.com/bkielbasa/cyclop/pkg/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.CyclopSettings) *goanalysis.Linter {
cfg := map[string]any{}
if settings != nil {
// Should be managed with `linters.exclusions.rules`.
cfg["skipTests"] = false
if settings.MaxComplexity != 0 {
cfg["maxComplexity"] = settings.MaxComplexity
}
if settings.PackageAverage != 0 {
cfg["packageAverage"] = settings.PackageAverage
}
}
return goanalysis.
NewLinterFromAnalyzer(analyzer.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/cyclop/cyclop_integration_test.go
================================================
package cyclop
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/cyclop/testdata/cyclop.go
================================================
//golangcitest:args -Ecyclop
//golangcitest:config_path testdata/cyclop.yml
package testdata
func cyclopComplexFunc(s string) { // want "calculated cyclomatic complexity for function cyclopComplexFunc is 22, max is 15"
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
}
================================================
FILE: pkg/golinters/cyclop/testdata/cyclop.yml
================================================
version: "2"
linters:
settings:
cyclop:
max-complexity: 15
================================================
FILE: pkg/golinters/cyclop/testdata/cyclop_cgo.go
================================================
//golangcitest:args -Ecyclop
//golangcitest:config_path testdata/cyclop.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func cyclopComplexFunc(s string) { // want "calculated cyclomatic complexity for function cyclopComplexFunc is 22, max is 15"
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
}
================================================
FILE: pkg/golinters/decorder/decorder.go
================================================
package decorder
import (
"strings"
"gitlab.com/bosi/decorder"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.DecorderSettings) *goanalysis.Linter {
// disable all rules/checks by default
cfg := map[string]any{
"ignore-underscore-vars": false,
"disable-dec-num-check": true,
"disable-type-dec-num-check": false,
"disable-const-dec-num-check": false,
"disable-var-dec-num-check": false,
"disable-dec-order-check": true,
"disable-init-func-first-check": true,
}
if settings != nil {
cfg["dec-order"] = strings.Join(settings.DecOrder, ",")
cfg["ignore-underscore-vars"] = settings.IgnoreUnderscoreVars
cfg["disable-dec-num-check"] = settings.DisableDecNumCheck
cfg["disable-type-dec-num-check"] = settings.DisableTypeDecNumCheck
cfg["disable-const-dec-num-check"] = settings.DisableConstDecNumCheck
cfg["disable-var-dec-num-check"] = settings.DisableVarDecNumCheck
cfg["disable-dec-order-check"] = settings.DisableDecOrderCheck
cfg["disable-init-func-first-check"] = settings.DisableInitFuncFirstCheck
}
return goanalysis.
NewLinterFromAnalyzer(decorder.Analyzer).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/decorder/decorder_integration_test.go
================================================
package decorder
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/decorder/testdata/decorder.go
================================================
//golangcitest:args -Edecorder
//golangcitest:expected_exitcode 0
package testdata
import "math"
const (
decoh = math.MaxInt64
decoi = 1
)
var decoj = 1
var decok = 1
type decol int
func decom() {
const decon = 1
}
func init() {}
================================================
FILE: pkg/golinters/decorder/testdata/decorder_cgo.go
================================================
//golangcitest:args -Edecorder
//golangcitest:config_path testdata/decorder_custom.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"math"
"unsafe"
)
const (
decoc = math.MaxInt64
decod = 1
)
var decoa = 1
var decob = 1 // want "multiple \"var\" declarations are not allowed; use parentheses instead"
type decoe int // want "type must not be placed after const"
func decof() {
const decog = 1
}
func init() {} // want "init func must be the first function in file"
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
================================================
FILE: pkg/golinters/decorder/testdata/decorder_custom.go
================================================
//golangcitest:args -Edecorder
//golangcitest:config_path testdata/decorder_custom.yml
package testdata
import "math"
const (
decoc = math.MaxInt64
decod = 1
)
var decoa = 1
var decob = 1 // want "multiple \"var\" declarations are not allowed; use parentheses instead"
type decoe int // want "type must not be placed after const"
func decof() {
const decog = 1
}
func init() {} // want "init func must be the first function in file"
================================================
FILE: pkg/golinters/decorder/testdata/decorder_custom.yml
================================================
version: "2"
linters:
settings:
decorder:
dec-order:
- type
- const
- var
- func
disable-dec-order-check: false
disable-init-func-first-check: false
disable-dec-num-check: false
================================================
FILE: pkg/golinters/depguard/depguard.go
================================================
package depguard
import (
"strings"
"github.com/OpenPeeDeeP/depguard/v2"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
)
func New(settings *config.DepGuardSettings, replacer *strings.Replacer) *goanalysis.Linter {
conf := depguard.LinterSettings{}
if settings != nil {
for s, rule := range settings.Rules {
var extendedPatterns []string
for _, file := range rule.Files {
extendedPatterns = append(extendedPatterns, replacer.Replace(file))
}
list := &depguard.List{
ListMode: rule.ListMode,
Files: extendedPatterns,
Allow: rule.Allow,
}
// because of bug with Viper parsing (split on dot) we use a list of struct instead of a map.
// https://github.com/spf13/viper/issues/324
// https://github.com/golangci/golangci-lint/issues/3749#issuecomment-1492536630
deny := map[string]string{}
for _, r := range rule.Deny {
deny[r.Pkg] = r.Desc
}
list.Deny = deny
conf[s] = list
}
}
analyzer := depguard.NewUncompiledAnalyzer(&conf)
return goanalysis.
NewLinterFromAnalyzer(analyzer.Analyzer).
WithContextSetter(func(lintCtx *linter.Context) {
err := analyzer.Compile()
if err != nil {
lintCtx.Log.Errorf("create analyzer: %v", err)
}
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/depguard/depguard_integration_test.go
================================================
package depguard
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/depguard/testdata/depguard.go
================================================
//golangcitest:args -Edepguard
//golangcitest:config_path testdata/depguard.yml
package testdata
import (
"compress/gzip" // want "import 'compress/gzip' is not allowed from list 'main': nope"
"log" // want "import 'log' is not allowed from list 'main': don't use log"
"golang.org/x/tools/go/analysis" // want "import 'golang.org/x/tools/go/analysis' is not allowed from list 'main': example import with dot"
)
func SpewDebugInfo() {
log.Println(gzip.BestCompression)
_ = analysis.Analyzer{}
}
================================================
FILE: pkg/golinters/depguard/testdata/depguard.yml
================================================
version: "2"
linters:
settings:
depguard:
rules:
main:
deny:
- pkg: compress
desc: "nope"
- pkg: log
desc: "don't use log"
- pkg: "golang.org/x/tools/go/analysis"
desc: "example import with dot"
================================================
FILE: pkg/golinters/depguard/testdata/depguard_additional_guards.go
================================================
//golangcitest:args -Edepguard
//golangcitest:config_path testdata/depguard_additional_guards.yml
package testdata
import (
"compress/gzip" // want "import 'compress/gzip' is not allowed from list 'main': nope"
"fmt" // want "import 'fmt' is not allowed from list 'main': nope"
"log" // want "import 'log' is not allowed from list 'main': don't use log"
"strings" // want "import 'strings' is not allowed from list 'main': nope"
"golang.org/x/tools/go/analysis" // want "import 'golang.org/x/tools/go/analysis' is not allowed from list 'main': example import with dot"
)
func SpewDebugInfo() {
log.Println(gzip.BestCompression)
log.Println(fmt.Sprintf("SpewDebugInfo"))
log.Println(strings.ToLower("SpewDebugInfo"))
_ = analysis.Analyzer{}
}
================================================
FILE: pkg/golinters/depguard/testdata/depguard_additional_guards.yml
================================================
version: "2"
linters:
settings:
depguard:
rules:
main:
deny:
- pkg: fmt
desc: "nope"
- pkg: strings
desc: "nope"
- pkg: compress
desc: "nope"
- pkg: log
desc: "don't use log"
- pkg: "golang.org/x/tools/go/analysis"
desc: "example import with dot"
================================================
FILE: pkg/golinters/depguard/testdata/depguard_cgo.go
================================================
//golangcitest:args -Edepguard
//golangcitest:config_path testdata/depguard.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"compress/gzip" // want "import 'compress/gzip' is not allowed from list 'main': nope"
"log" // want "import 'log' is not allowed from list 'main': don't use log"
"unsafe"
"golang.org/x/tools/go/analysis" // want "import 'golang.org/x/tools/go/analysis' is not allowed from list 'main': example import with dot"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func SpewDebugInfo() {
log.Println(gzip.BestCompression)
_ = analysis.Analyzer{}
}
================================================
FILE: pkg/golinters/depguard/testdata/depguard_ignore_file_rules.go
================================================
//golangcitest:args -Edepguard
//golangcitest:config_path testdata/depguard_ignore_file_rules.yml
//golangcitest:expected_exitcode 0
package testdata
// NOTE - No lint errors because this file is ignored
import (
"compress/gzip"
"log"
"golang.org/x/tools/go/analysis"
)
func SpewDebugInfo() {
log.Println(gzip.BestCompression)
_ = analysis.Analyzer{}
}
================================================
FILE: pkg/golinters/depguard/testdata/depguard_ignore_file_rules.yml
================================================
version: "2"
linters:
settings:
depguard:
rules:
main:
files:
- "!**/*_ignore_file_rules.go"
deny:
- pkg: compress
desc: "nope"
- pkg: log
desc: "don't use log"
- pkg: "golang.org/x/tools/go/analysis"
desc: "example import with dot"
================================================
FILE: pkg/golinters/dogsled/dogsled.go
================================================
package dogsled
import (
"go/ast"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.DogsledSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: "dogsled",
Doc: "Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())",
Run: func(pass *analysis.Pass) (any, error) {
return run(pass, settings.MaxBlankIdentifiers)
},
Requires: []*analysis.Analyzer{inspect.Analyzer},
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func run(pass *analysis.Pass, maxBlanks int) (any, error) {
insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
if !ok {
return nil, nil
}
for node := range insp.PreorderSeq((*ast.FuncDecl)(nil)) {
funcDecl, ok := node.(*ast.FuncDecl)
if !ok {
continue
}
if funcDecl.Body == nil {
continue
}
for _, expr := range funcDecl.Body.List {
assgnStmt, ok := expr.(*ast.AssignStmt)
if !ok {
continue
}
numBlank := 0
for _, left := range assgnStmt.Lhs {
ident, ok := left.(*ast.Ident)
if !ok {
continue
}
if ident.Name == "_" {
numBlank++
}
}
if numBlank > maxBlanks {
pass.Reportf(assgnStmt.Pos(), "declaration has %v blank identifiers", numBlank)
}
}
}
return nil, nil
}
================================================
FILE: pkg/golinters/dogsled/dogsled_integration_test.go
================================================
package dogsled
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/dogsled/testdata/dogsled.go
================================================
//golangcitest:args -Edogsled
package testdata
func Dogsled() {
_ = ret1()
_, _ = ret2()
_, _, _ = ret3() // want "declaration has 3 blank identifiers"
_, _, _, _ = ret4() // want "declaration has 4 blank identifiers"
}
func ret1() (a int) {
return 1
}
func ret2() (a, b int) {
return 1, 2
}
func ret3() (a, b, c int) {
return 1, 2, 3
}
func ret4() (a, b, c, d int) {
return 1, 2, 3, 4
}
================================================
FILE: pkg/golinters/dogsled/testdata/dogsled_cgo.go
================================================
//golangcitest:args -Edogsled
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
_ = ret1()
_, _ = ret2()
_, _, _ = ret3() // want "declaration has 3 blank identifiers"
_, _, _, _ = ret4() // want "declaration has 4 blank identifiers"
}
func ret1() (a int) {
return 1
}
func ret2() (a, b int) {
return 1, 2
}
func ret3() (a, b, c int) {
return 1, 2, 3
}
func ret4() (a, b, c, d int) {
return 1, 2, 3, 4
}
================================================
FILE: pkg/golinters/dupl/dupl.go
================================================
package dupl
import (
"fmt"
"go/token"
"sync"
duplAPI "github.com/golangci/dupl/lib"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/fsutils"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "dupl"
func New(settings *config.DuplSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []*goanalysis.Issue
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: "Detects duplicate fragments of code.",
Run: func(pass *analysis.Pass) (any, error) {
issues, err := runDupl(pass, settings)
if err != nil {
return nil, err
}
if len(issues) == 0 {
return nil, nil
}
mu.Lock()
resIssues = append(resIssues, issues...)
mu.Unlock()
return nil, nil
},
}).
WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
return resIssues
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func runDupl(pass *analysis.Pass, settings *config.DuplSettings) ([]*goanalysis.Issue, error) {
issues, err := duplAPI.Run(internal.GetGoFileNames(pass), settings.Threshold)
if err != nil {
return nil, err
}
if len(issues) == 0 {
return nil, nil
}
res := make([]*goanalysis.Issue, 0, len(issues))
for _, i := range issues {
toFilename, err := fsutils.ShortestRelPath(i.To.Filename(), "")
if err != nil {
return nil, fmt.Errorf("failed to get shortest rel path for %q: %w", i.To.Filename(), err)
}
dupl := fmt.Sprintf("%s:%d-%d", toFilename, i.To.LineStart(), i.To.LineEnd())
text := fmt.Sprintf("%d-%d lines are duplicate of %s",
i.From.LineStart(), i.From.LineEnd(),
internal.FormatCode(dupl))
res = append(res, goanalysis.NewIssue(&result.Issue{
Pos: token.Position{
Filename: i.From.Filename(),
Line: i.From.LineStart(),
},
LineRange: &result.Range{
From: i.From.LineStart(),
To: i.From.LineEnd(),
},
Text: text,
FromLinter: linterName,
}, pass))
}
return res, nil
}
================================================
FILE: pkg/golinters/dupl/dupl_integration_test.go
================================================
package dupl
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/dupl/testdata/dupl.go
================================================
//golangcitest:args -Edupl
//golangcitest:config_path testdata/dupl.yml
package testdata
type DuplLogger struct{}
func (DuplLogger) level() int {
return 1
}
func (DuplLogger) Debug(args ...interface{}) {}
func (DuplLogger) Info(args ...interface{}) {}
func (logger *DuplLogger) First(args ...interface{}) { // want "14-23 lines are duplicate of `.*dupl.go:25-34`"
if logger.level() >= 0 {
logger.Debug(args...)
logger.Debug(args...)
logger.Debug(args...)
logger.Debug(args...)
logger.Debug(args...)
logger.Debug(args...)
}
}
func (logger *DuplLogger) Second(args ...interface{}) { // want "25-34 lines are duplicate of `.*dupl.go:14-23`"
if logger.level() >= 1 {
logger.Info(args...)
logger.Info(args...)
logger.Info(args...)
logger.Info(args...)
logger.Info(args...)
logger.Info(args...)
}
}
================================================
FILE: pkg/golinters/dupl/testdata/dupl.yml
================================================
version: "2"
linters:
settings:
dupl:
threshold: 20
================================================
FILE: pkg/golinters/dupl/testdata/dupl_cgo.go
================================================
//golangcitest:args -Edupl
//golangcitest:config_path testdata/dupl.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type DuplLogger struct{}
func (DuplLogger) level() int {
return 1
}
func (DuplLogger) Debug(args ...interface{}) {}
func (DuplLogger) Info(args ...interface{}) {}
func (logger *DuplLogger) First(args ...interface{}) { // want "34-43 lines are duplicate of `.*dupl_cgo.go:45-54`"
if logger.level() >= 0 {
logger.Debug(args...)
logger.Debug(args...)
logger.Debug(args...)
logger.Debug(args...)
logger.Debug(args...)
logger.Debug(args...)
}
}
func (logger *DuplLogger) Second(args ...interface{}) { // want "45-54 lines are duplicate of `.*dupl_cgo.go:34-43`"
if logger.level() >= 1 {
logger.Info(args...)
logger.Info(args...)
logger.Info(args...)
logger.Info(args...)
logger.Info(args...)
logger.Info(args...)
}
}
================================================
FILE: pkg/golinters/dupword/dupword.go
================================================
package dupword
import (
"strings"
"github.com/Abirdcfly/dupword"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.DupWordSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"keyword": strings.Join(settings.Keywords, ","),
"ignore": strings.Join(settings.Ignore, ","),
"comments-only": settings.CommentsOnly,
}
}
return goanalysis.
NewLinterFromAnalyzer(dupword.NewAnalyzer()).
WithDesc("Checks for duplicate words in the source code").
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/dupword/dupword_integration_test.go
================================================
package dupword
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/dupword/testdata/dupword.go
================================================
//golangcitest:args -Edupword
package testdata
import "fmt"
func duplicateWordInComments() {
// this line include duplicated word the the // want `Duplicate words \(the\) found`
fmt.Println("hello")
}
func duplicateWordInStr() {
a := "this line include duplicate word and and" // want `Duplicate words \(and\) found`
b := "print the\n the line, print the the \n\t the line. and and" // want `Duplicate words \(and,the\) found`
fmt.Println(a, b)
}
================================================
FILE: pkg/golinters/dupword/testdata/dupword_cgo.go
================================================
//golangcitest:args -Edupword
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func duplicateWordInComments() {
// this line include duplicated word the the // want `Duplicate words \(the\) found`
fmt.Println("hello")
}
================================================
FILE: pkg/golinters/dupword/testdata/dupword_comments_only.go
================================================
//golangcitest:args -Edupword
//golangcitest:config_path testdata/dupword_comments_only.yml
package testdata
import "fmt"
func _() {
// want +2 `Duplicate words \(and\) found`
// want +2 `Duplicate words \(and,the\) found`
// this line include duplicate word and and
// print the\n the line, print the the \n\t the line. and and
a := "this line include duplicate word and and"
b := "print the\n the line, print the the \n\t the line. and and"
fmt.Println(a, b)
}
================================================
FILE: pkg/golinters/dupword/testdata/dupword_comments_only.yml
================================================
version: "2"
linters:
settings:
dupword:
comments-only: true
================================================
FILE: pkg/golinters/dupword/testdata/dupword_ignore.go
================================================
//golangcitest:args -Edupword
//golangcitest:config_path testdata/dupword_ignore.yml
package testdata
import "fmt"
func duplicateWordInComments() {
// this line include duplicated word the the
fmt.Println("hello")
}
func duplicateWordInStr() {
a := "this line include duplicate word and and" // want `Duplicate words \(and\) found`
b := "print the\n the line, print the the \n\t the line. and and" // want `Duplicate words \(and\) found`
fmt.Println(a, b)
}
================================================
FILE: pkg/golinters/dupword/testdata/dupword_ignore.yml
================================================
version: "2"
linters:
settings:
dupword:
ignore:
- "the"
================================================
FILE: pkg/golinters/dupword/testdata/fix/in/dupword.go
================================================
//golangcitest:args -Edupword
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
func duplicateWordInComments() {
// this line include duplicated word the the
fmt.Println("hello")
}
func duplicateWordInStr() {
a := "this line include duplicate word and and"
b := "print the\n the line, print the the \n\t the line. and and"
fmt.Println(a, b)
}
================================================
FILE: pkg/golinters/dupword/testdata/fix/out/dupword.go
================================================
//golangcitest:args -Edupword
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
func duplicateWordInComments() {
// this line include duplicated word the
fmt.Println("hello")
}
func duplicateWordInStr() {
a := "this line include duplicate word and"
b := "print the\n line, print the line. and"
fmt.Println(a, b)
}
================================================
FILE: pkg/golinters/durationcheck/durationcheck.go
================================================
package durationcheck
import (
"github.com/charithe/durationcheck"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(durationcheck.Analyzer).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/durationcheck/durationcheck_integration_test.go
================================================
package durationcheck
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/durationcheck/testdata/durationcheck.go
================================================
//golangcitest:args -Edurationcheck
package testdata
import (
"fmt"
"time"
)
type durationCheckData struct {
i int
d time.Duration
}
func durationcheckCase01() {
dcd := durationCheckData{i: 10}
_ = time.Duration(dcd.i) * time.Second
}
func durationcheckCase02() {
dcd := durationCheckData{d: 10 * time.Second}
_ = dcd.d * time.Second // want "Multiplication of durations: `dcd.d \\* time.Second`"
}
func durationcheckCase03() {
seconds := 10
fmt.Print(time.Duration(seconds) * time.Second)
}
func durationcheckCase04(someDuration time.Duration) {
timeToWait := someDuration * time.Second // want "Multiplication of durations: `someDuration \\* time.Second`"
time.Sleep(timeToWait)
}
func durationcheckCase05() {
someDuration := 2 * time.Second
timeToWait := someDuration * time.Second // want "Multiplication of durations: `someDuration \\* time.Second`"
time.Sleep(timeToWait)
}
================================================
FILE: pkg/golinters/durationcheck/testdata/durationcheck_cgo.go
================================================
//golangcitest:args -Edurationcheck
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"time"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type durationCheckData struct {
i int
d time.Duration
}
func durationcheckCase01() {
dcd := durationCheckData{i: 10}
_ = time.Duration(dcd.i) * time.Second
}
func durationcheckCase02() {
dcd := durationCheckData{d: 10 * time.Second}
_ = dcd.d * time.Second // want "Multiplication of durations: `dcd.d \\* time.Second`"
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck.go
================================================
package embeddedstructfieldcheck
import (
"github.com/manuelarte/embeddedstructfieldcheck/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.EmbeddedStructFieldCheckSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
analyzer.ForbidMutexCheck: settings.ForbidMutex,
analyzer.EmptyLineCheck: settings.EmptyLine,
}
}
return goanalysis.
NewLinterFromAnalyzer(analyzer.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck_integration_test.go
================================================
package embeddedstructfieldcheck
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_comments.go
================================================
//golangcitest:args -Eembeddedstructfieldcheck
package testdata
import "time"
type ValidStructWithSingleLineComments struct {
// time.Time Single line comment
time.Time
// version Single line comment
version int
}
type StructWithSingleLineComments struct {
// time.Time Single line comment
time.Time // want `there must be an empty line separating embedded fields from regular fields`
// version Single line comment
version int
}
type StructWithMultiLineComments struct {
// time.Time Single line comment
time.Time // want `there must be an empty line separating embedded fields from regular fields`
// version Single line comment
// very long comment
version int
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_mutex.go
================================================
//golangcitest:args -Eembeddedstructfieldcheck
//golangcitest:config_path testdata/embeddedstructfieldcheck_mutex.yml
package testdata
import "sync"
type MutextEmbedded struct {
sync.Mutex // want `sync.Mutex should not be embedded`
}
type MutextNotEmbedded struct {
mu sync.Mutex
}
type PointerMutextEmbedded struct {
*sync.Mutex // want `sync.Mutex should not be embedded`
}
type RWMutextEmbedded struct {
sync.RWMutex // want `sync.RWMutex should not be embedded`
}
type RWMutextNotEmbedded struct {
mu sync.RWMutex
}
type PointerRWMutextEmbedded struct {
*sync.RWMutex // want `sync.RWMutex should not be embedded`
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_mutex.yml
================================================
version: "2"
linters:
settings:
embeddedstructfieldcheck:
forbid-mutex: true
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_simple.go
================================================
//golangcitest:args -Eembeddedstructfieldcheck
package testdata
import (
"context"
"time"
)
type ValidStruct struct {
time.Time
version int
}
type NoSpaceStruct struct {
time.Time // want `there must be an empty line separating embedded fields from regular fields`
version int
}
type NotSortedStruct struct {
version int
time.Time // want `embedded fields should be listed before regular fields`
}
type MixedEmbeddedAndNotEmbedded struct {
context.Context
name string
time.Time // want `embedded fields should be listed before regular fields`
age int
}
type EmbeddedWithPointers struct {
*time.Time // want `there must be an empty line separating embedded fields from regular fields`
version int
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_special_cases.go
================================================
//golangcitest:args -Eembeddedstructfieldcheck
package testdata
import "time"
func myFunction() {
type myType struct {
version int
time.Time // want `embedded fields should be listed before regular fields`
}
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/fix/in/comments.go
================================================
//golangcitest:args -Eembeddedstructfieldcheck
//golangcitest:expected_exitcode 0
package testdata
import "time"
type ValidStructWithSingleLineComments struct {
// time.Time Single line comment
time.Time
// version Single line comment
version int
}
type StructWithSingleLineComments struct {
// time.Time Single line comment
time.Time // want `there must be an empty line separating embedded fields from regular fields`
// version Single line comment
version int
}
type StructWithMultiLineComments struct {
// time.Time Single line comment
time.Time // want `there must be an empty line separating embedded fields from regular fields`
// version Single line comment
// very long comment
version int
}
type A struct {
// comment
ValidStructWithSingleLineComments
// C is foo
StructWithSingleLineComments // want `there must be an empty line separating embedded fields from regular fields`
D string
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/fix/in/simple.go
================================================
//golangcitest:args -Eembeddedstructfieldcheck
//golangcitest:expected_exitcode 0
package testdata
import (
"time"
)
type ValidStruct struct {
time.Time
version int
}
type NoSpaceStruct struct {
time.Time // want `there must be an empty line separating embedded fields from regular fields`
version int
}
type EmbeddedWithPointers struct {
*time.Time // want `there must be an empty line separating embedded fields from regular fields`
version int
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/fix/out/comments.go
================================================
//golangcitest:args -Eembeddedstructfieldcheck
//golangcitest:expected_exitcode 0
package testdata
import "time"
type ValidStructWithSingleLineComments struct {
// time.Time Single line comment
time.Time
// version Single line comment
version int
}
type StructWithSingleLineComments struct {
// time.Time Single line comment
time.Time // want `there must be an empty line separating embedded fields from regular fields`
// version Single line comment
version int
}
type StructWithMultiLineComments struct {
// time.Time Single line comment
time.Time // want `there must be an empty line separating embedded fields from regular fields`
// version Single line comment
// very long comment
version int
}
type A struct {
// comment
ValidStructWithSingleLineComments
// C is foo
StructWithSingleLineComments // want `there must be an empty line separating embedded fields from regular fields`
D string
}
================================================
FILE: pkg/golinters/embeddedstructfieldcheck/testdata/fix/out/simple.go
================================================
//golangcitest:args -Eembeddedstructfieldcheck
//golangcitest:expected_exitcode 0
package testdata
import (
"time"
)
type ValidStruct struct {
time.Time
version int
}
type NoSpaceStruct struct {
time.Time // want `there must be an empty line separating embedded fields from regular fields`
version int
}
type EmbeddedWithPointers struct {
*time.Time // want `there must be an empty line separating embedded fields from regular fields`
version int
}
================================================
FILE: pkg/golinters/err113/err113.go
================================================
package err113
import (
"github.com/Djarvur/go-err113"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(err113.NewAnalyzer()).
WithDesc("Check errors handling expressions").
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/err113/err113_integration_test.go
================================================
package err113
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/err113/testdata/err113.go
================================================
//golangcitest:args -Eerr113
package testdata
import "os"
func SimpleEqual(e1, e2 error) bool {
return e1 == e2 // want `do not compare errors directly "e1 == e2", use "errors.Is\(e1, e2\)" instead`
}
func SimpleNotEqual(e1, e2 error) bool {
return e1 != e2 // want `do not compare errors directly "e1 != e2", use "!errors.Is\(e1, e2\)" instead`
}
func CheckGoerr13Import(e error) bool {
f, err := os.Create("f.txt")
if err != nil {
return err == e // want `do not compare errors directly "err == e", use "errors.Is\(err, e\)" instead`
}
f.Close()
return false
}
================================================
FILE: pkg/golinters/err113/testdata/err113_cgo.go
================================================
//golangcitest:args -Eerr113
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"os"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func CheckGoerr13Import(e error) bool {
f, err := os.Create("f.txt")
if err != nil {
return err == e // want `do not compare errors directly "err == e", use "errors.Is\(err, e\)" instead`
}
f.Close()
return false
}
================================================
FILE: pkg/golinters/err113/testdata/fix/in/err113.go
================================================
//golangcitest:args -Eerr113
//golangcitest:expected_exitcode 0
package testdata
import "os"
func SimpleEqual(e1, e2 error) bool {
return e1 == e2
}
func SimpleNotEqual(e1, e2 error) bool {
return e1 != e2
}
func CheckGoerr13Import(e error) bool {
f, err := os.Create("f.txt")
if err != nil {
return err == e
}
f.Close()
return false
}
================================================
FILE: pkg/golinters/err113/testdata/fix/out/err113.go
================================================
//golangcitest:args -Eerr113
//golangcitest:expected_exitcode 0
package testdata
import "os"
func SimpleEqual(e1, e2 error) bool {
return errors.Is(e1, e2)
}
func SimpleNotEqual(e1, e2 error) bool {
return !errors.Is(e1, e2)
}
func CheckGoerr13Import(e error) bool {
f, err := os.Create("f.txt")
if err != nil {
return errors.Is(err, e)
}
f.Close()
return false
}
================================================
FILE: pkg/golinters/errcheck/errcheck.go
================================================
package errcheck
import (
"cmp"
"fmt"
"regexp"
"sync"
"github.com/kisielk/errcheck/errcheck"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "errcheck"
func New(settings *config.ErrcheckSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []*goanalysis.Issue
analyzer := &analysis.Analyzer{
Name: linterName,
Doc: "errcheck is a program for checking for unchecked errors in Go code. " +
"These unchecked errors can be critical bugs in some cases",
Run: goanalysis.DummyRun,
}
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithContextSetter(func(lintCtx *linter.Context) {
checker := getChecker(settings)
checker.Tags = lintCtx.Cfg.Run.BuildTags
analyzer.Run = func(pass *analysis.Pass) (any, error) {
issues := runErrCheck(pass, checker, settings.Verbose)
if len(issues) == 0 {
return nil, nil
}
mu.Lock()
resIssues = append(resIssues, issues...)
mu.Unlock()
return nil, nil
}
}).
WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
return resIssues
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func runErrCheck(pass *analysis.Pass, checker *errcheck.Checker, verbose bool) []*goanalysis.Issue {
pkg := &packages.Package{
Fset: pass.Fset,
Syntax: pass.Files,
Types: pass.Pkg,
TypesInfo: pass.TypesInfo,
}
lintIssues := checker.CheckPackage(pkg).Unique()
if len(lintIssues.UncheckedErrors) == 0 {
return nil
}
issues := make([]*goanalysis.Issue, len(lintIssues.UncheckedErrors))
for i, err := range lintIssues.UncheckedErrors {
text := "Error return value is not checked"
if err.FuncName != "" {
code := cmp.Or(err.SelectorName, err.FuncName)
if verbose {
code = err.FuncName
}
text = fmt.Sprintf("Error return value of %s is not checked", internal.FormatCode(code))
}
issues[i] = goanalysis.NewIssue(
&result.Issue{
FromLinter: linterName,
Text: text,
Pos: err.Pos,
},
pass,
)
}
return issues
}
func getChecker(errCfg *config.ErrcheckSettings) *errcheck.Checker {
checker := errcheck.Checker{
Exclusions: errcheck.Exclusions{
BlankAssignments: !errCfg.CheckAssignToBlank,
TypeAssertions: !errCfg.CheckTypeAssertions,
SymbolRegexpsByPackage: map[string]*regexp.Regexp{},
},
}
if !errCfg.DisableDefaultExclusions {
checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errcheck.DefaultExcludedSymbols...)
}
checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errCfg.ExcludeFunctions...)
return &checker
}
================================================
FILE: pkg/golinters/errcheck/errcheck_integration_test.go
================================================
package errcheck
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/errcheck/testdata/errcheck.go
================================================
//golangcitest:args -Eerrcheck
package testdata
import (
"bytes"
"net/http"
"os"
)
func RetErr() error {
return nil
}
func MissedErrorCheck() {
RetErr() // want "Error return value is not checked"
}
func IgnoreCloseMissingErrHandling() error {
f, err := os.Open("t.go")
if err != nil {
return err
}
f.Close() // want "Error return value of `f.Close` is not checked"
return nil
}
func IgnoreCloseInDeferMissingErrHandling() {
resp, err := http.Get("http://example.com/")
if err != nil {
panic(err)
}
defer resp.Body.Close() // want "Error return value of `resp.Body.Close` is not checked"
panic(resp)
}
func IgnoreStdxWrite() {
os.Stdout.Write([]byte{}) // want "Error return value of `os.Stdout.Write` is not checked"
os.Stderr.Write([]byte{}) // want "Error return value of `os.Stderr.Write` is not checked"
}
func IgnoreBufferWrites(buf *bytes.Buffer) {
buf.WriteString("x")
}
================================================
FILE: pkg/golinters/errcheck/testdata/errcheck_cgo.go
================================================
//golangcitest:args -Eerrcheck
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func RetErr() error {
return nil
}
func MissedErrorCheck() {
RetErr() // want "Error return value is not checked"
}
================================================
FILE: pkg/golinters/errcheck/testdata/errcheck_exclude_functions.go
================================================
//golangcitest:args -Eerrcheck
//golangcitest:config_path testdata/errcheck_exclude_functions.yml
package testdata
import (
"io/ioutil"
)
func TestErrcheckExcludeFunctions() []byte {
ret, _ := ioutil.ReadFile("f.txt")
ioutil.ReadDir("dir")
return ret
}
func TestErrcheckNoExcludeFunctions() []byte {
ret, _ := ioutil.ReadAll(nil) // want "Error return value of `ioutil.ReadAll` is not checked"
return ret
}
================================================
FILE: pkg/golinters/errcheck/testdata/errcheck_exclude_functions.yml
================================================
version: "2"
linters:
settings:
errcheck:
check-blank: true
exclude-functions:
- io/ioutil.ReadFile
- io/ioutil.ReadDir
================================================
FILE: pkg/golinters/errcheck/testdata/errcheck_ignore_default.go
================================================
//golangcitest:args -Eerrcheck
//golangcitest:config_path testdata/errcheck_ignore_default.yml
package testdata
import (
"crypto/sha256"
"fmt"
"os"
)
func TestErrcheckIgnoreHashWriteByDefault() []byte {
h := sha256.New()
h.Write([]byte("food"))
return h.Sum(nil)
}
func TestErrcheckIgnoreFmtByDefault(s string) int {
n, _ := fmt.Println(s)
return n
}
func TestErrcheckNoIgnoreOs() {
_, _ = os.Open("f.txt") // want "Error return value of `os.Open` is not checked"
}
================================================
FILE: pkg/golinters/errcheck/testdata/errcheck_ignore_default.yml
================================================
version: "2"
linters:
settings:
errcheck:
check-blank: true
================================================
FILE: pkg/golinters/errcheck/testdata/errcheck_type_assertions.go
================================================
//golangcitest:args -Eerrcheck
//golangcitest:config_path testdata/errcheck_type_assertions.yml
//golangcitest:expected_exitcode 1
package testdata
func ErrorTypeAssertion(filter map[string]interface{}) bool {
return filter["messages_sent.messageid"].(map[string]interface{})["$ne"] != nil // want "Error return value is not checked"
}
================================================
FILE: pkg/golinters/errcheck/testdata/errcheck_type_assertions.yml
================================================
version: "2"
linters:
settings:
errcheck:
check-type-assertions: true
================================================
FILE: pkg/golinters/errchkjson/errchkjson.go
================================================
package errchkjson
import (
"github.com/breml/errchkjson"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ErrChkJSONSettings) *goanalysis.Linter {
cfg := map[string]any{
"omit-safe": true,
}
if settings != nil {
cfg = map[string]any{
"omit-safe": !settings.CheckErrorFreeEncoding,
"report-no-exported": settings.ReportNoExported,
}
}
return goanalysis.
NewLinterFromAnalyzer(errchkjson.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/errchkjson/errchkjson_integration_test.go
================================================
package errchkjson
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/errchkjson/testdata/errchkjson.go
================================================
//golangcitest:args -Eerrchkjson
//golangcitest:config_path testdata/errchkjson.yml
package testdata
import (
"encoding"
"encoding/json"
"fmt"
"io/ioutil"
"unsafe"
)
type marshalText struct{}
func (mt marshalText) MarshalText() ([]byte, error) {
return []byte(`mt`), nil
}
var _ encoding.TextMarshaler = marshalText(struct{}{})
// JSONMarshalSafeTypesWithNoSafe contains a multitude of test cases to marshal different combinations of types to JSON,
// that are safe, that is, they will never return an error, if these types are marshaled to JSON.
func JSONMarshalSafeTypesWithNoSafe() {
var err error
_, _ = json.Marshal(nil) // want "Error return value of `encoding/json.Marshal` is not checked"
json.Marshal(nil) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(nil) // nil is safe and check-error-free-encoding is false
_ = err
_, _ = json.MarshalIndent(nil, "", " ") // want "Error return value of `encoding/json.MarshalIndent` is not checked"
json.MarshalIndent(nil, "", " ") // want "Error return value of `encoding/json.MarshalIndent` is not checked"
_, err = json.MarshalIndent(nil, "", " ") // nil is safe and check-error-free-encoding is false
_ = err
enc := json.NewEncoder(ioutil.Discard)
_ = enc.Encode(nil) // want "Error return value of `\\([*]encoding/json.Encoder\\).Encode` is not checked"
enc.Encode(nil) // want "Error return value of `\\([*]encoding/json.Encoder\\).Encode` is not checked"
err = enc.Encode(nil) // nil is safe and check-error-free-encoding is false
_ = err
var b bool
_, _ = json.Marshal(b) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(b) // bool is safe and check-error-free-encoding is false
_ = err
var i int
_, _ = json.Marshal(i) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(i) // int is safe and check-error-free-encoding is false
_ = err
var i8 int8
_, _ = json.Marshal(i8) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(i8) // int8 is safe and check-error-free-encoding is false
_ = err
var i16 int16
_, _ = json.Marshal(i16) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(i16) // int16 is safe and check-error-free-encoding is false
_ = err
var i32 int32
_, _ = json.Marshal(i32) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(i32) // int32 / rune is safe and check-error-free-encoding is false
_ = err
var i64 int64
_, _ = json.Marshal(i64) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(i64) // int64 is safe and check-error-free-encoding is false
_ = err
var ui uint
_, _ = json.Marshal(ui) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(ui) // uint is safe and check-error-free-encoding is false
_ = err
var ui8 uint8
_, _ = json.Marshal(ui8) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(ui8) // uint8 is safe and check-error-free-encoding is false
_ = err
var ui16 uint16
_, _ = json.Marshal(ui16) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(ui16) // uint16 is safe and check-error-free-encoding is false
_ = err
var ui32 uint32
_, _ = json.Marshal(ui32) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(ui32) // uint32 is safe and check-error-free-encoding is false
_ = err
var ui64 uint64
_, _ = json.Marshal(ui64) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(ui64) // uint64 is safe and check-error-free-encoding is false
_ = err
var uiptr uintptr
_, _ = json.Marshal(uiptr) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(uiptr) // uintptr is safe and check-error-free-encoding is false
_ = err
var str string
_, _ = json.Marshal(str) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(str) // string is safe and check-error-free-encoding is false
_ = err
var strSlice []string
_, _ = json.Marshal(strSlice) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(strSlice) // []string is safe and check-error-free-encoding is false
_ = err
var intSlice []int
_, _ = json.Marshal(intSlice) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(intSlice) // []int is safe and check-error-free-encoding is false
_ = err
var boolSlice []bool
_, _ = json.Marshal(boolSlice) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(boolSlice) // []bool is safe and check-error-free-encoding is false
_ = err
var strArray [10]string
_, _ = json.Marshal(strArray) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(strArray) // [10]string is safe and check-error-free-encoding is false
_ = err
var intArray [10]int
_, _ = json.Marshal(intArray) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(intArray) // [10]int is safe and check-error-free-encoding is false
_ = err
var boolArray [10]bool
_, _ = json.Marshal(boolArray) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(boolArray) // [10]bool is safe and check-error-free-encoding is false
_ = err
var basicStruct struct {
Bool bool
Int int
Int8 int8
Int16 int16
Int32 int32 // also rune
Int64 int64
Uint uint
Uint8 uint8 // also byte
Uint16 uint16
Uint32 uint32
Uint64 uint64
Uintptr uintptr
String string
}
_, _ = json.Marshal(basicStruct) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(basicStruct) // struct containing only safe basic types is safe and check-error-free-encoding is false
_ = err
var ptrStruct struct {
Bool *bool
Int *int
Int8 *int8
Int16 *int16
Int32 *int32
Int64 *int64
Uint *uint
Uint8 *uint8
Uint16 *uint16
Uint32 *uint32
Uint64 *uint64
Uintptr *uintptr
String *string
}
_, _ = json.Marshal(ptrStruct) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(ptrStruct) // struct containing pointer to only safe basic types is safe and check-error-free-encoding is false
_ = err
var mapStrStr map[string]string
_, _ = json.Marshal(mapStrStr) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(mapStrStr) // map[string]string is safe and check-error-free-encoding is false
_ = err
var mapStrInt map[string]int
_, _ = json.Marshal(mapStrInt) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(mapStrInt) // map[string]int is safe and check-error-free-encoding is false
_ = err
var mapStrBool map[string]bool
_, _ = json.Marshal(mapStrBool) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(mapStrBool) // map[string]bool is safe and check-error-free-encoding is false
_ = err
var mapIntStr map[int]string
_, _ = json.Marshal(mapIntStr) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(mapIntStr) // map[int]string is safe and check-error-free-encoding is false
_ = err
var mapIntInt map[int]int
_, _ = json.Marshal(mapIntInt) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(mapIntInt) // map[int]int is safe and check-error-free-encoding is false
_ = err
var mapIntBool map[int]bool
_, _ = json.Marshal(mapIntBool) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(mapIntBool) // map[int]bool is safe and check-error-free-encoding is false
_ = err
type innerStruct struct {
Bool bool
Int int
String string
StrSlice []string
IntSlice []int
BoolSlice []bool
StrArray [10]string
IntArray [10]int
BoolArray [10]bool
MapStrStr map[string]string
MapStrInt map[string]int
MapStrBool map[string]bool
MapIntStr map[int]string
MapIntInt map[int]int
MapIntBool map[int]bool
}
var outerStruct struct {
Bool bool
Int int
String string
StrSlice []string
IntSlice []int
BoolSlice []bool
StrArray [10]string
IntArray [10]int
BoolArray [10]bool
MapStrStr map[string]string
MapStrInt map[string]int
MapStrBool map[string]bool
MapIntStr map[int]string
MapIntInt map[int]int
MapIntBool map[int]bool
InnerStruct innerStruct
}
_, _ = json.Marshal(outerStruct) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(outerStruct) // struct with only safe types is safe and check-error-free-encoding is false
_ = err
}
type (
structKey struct{ id int }
ExportedUnsafeAndInvalidStruct struct { // unsafe unexported but omitted
F64 float64
F64Ptr *float64
F64Slice []float64
F64Array [10]float64
MapStrF64 map[string]float64
MapEIStr map[interface{}]string
Number json.Number
NumberPtr *json.Number
NumberSlice []json.Number
MapNumberStr map[json.Number]string
Ei interface{}
Stringer fmt.Stringer
Mt marshalText
MapMarshalTextString map[marshalText]string
C128 complex128
C128Ptr *complex128
C128Slice []complex128
C128Array [10]complex128
MapBoolStr map[bool]string
MapF64Str map[float64]string
F func()
Ch chan struct{}
UnsafePtr unsafe.Pointer
MapStructStr map[structKey]string
}
)
// JSONMarshalSafeStructWithUnexportedFieldsWithNoSafe contains a struct with unexported, unsafe fields.
func JSONMarshalSaveStructWithUnexportedFieldsWithNoSafe() {
var err error
var unexportedInStruct struct {
Bool bool // safe exported
f64 float64 // unsafe unexported
f64Ptr *float64 // unsafe unexported
f64Slice []float64 // unsafe unexported
f64Array [10]float64 // unsafe unexported
mapStrF64 map[string]float64 // unsafe unexported
mapEIStr map[interface{}]string // unsafe unexported
number json.Number // unsafe unexported
numberPtr *json.Number // unsafe unexported
numberSlice []json.Number // unsafe unexported
mapNumberStr map[json.Number]string // unsafe unexported
ei interface{} // unsafe unexported
stringer fmt.Stringer // unsafe unexported
mt marshalText // unsafe unexported
mapMarshalTextString map[marshalText]string // unsafe unexported
unexportedStruct ExportedUnsafeAndInvalidStruct // unsafe unexported
unexportedStructPtr *ExportedUnsafeAndInvalidStruct // unsafe unexported
c128 complex128 // invalid unexported
c128Slice []complex128 // invalid unexported
c128Array [10]complex128 // invalid unexported
mapBoolStr map[bool]string // invalid unexported
mapF64Str map[float64]string // invalid unexported
f func() // invalid unexported
ch chan struct{} // invalid unexported
unsafePtr unsafe.Pointer // invalid unexported
mapStructStr map[structKey]string // invalid unexported
}
_ = unexportedInStruct.f64
_ = unexportedInStruct.f64Ptr
_ = unexportedInStruct.f64Slice
_ = unexportedInStruct.f64Array
_ = unexportedInStruct.mapStrF64
_ = unexportedInStruct.mapEIStr
_ = unexportedInStruct.number
_ = unexportedInStruct.numberPtr
_ = unexportedInStruct.numberSlice
_ = unexportedInStruct.mapNumberStr
_ = unexportedInStruct.ei
_ = unexportedInStruct.stringer
_ = unexportedInStruct.mt
_ = unexportedInStruct.mapMarshalTextString
_ = unexportedInStruct.unexportedStruct
_ = unexportedInStruct.unexportedStructPtr
_ = unexportedInStruct.c128
_ = unexportedInStruct.c128Slice
_ = unexportedInStruct.c128Array
_ = unexportedInStruct.mapBoolStr
_ = unexportedInStruct.mapF64Str
_ = unexportedInStruct.f
_ = unexportedInStruct.ch
_ = unexportedInStruct.unsafePtr
_ = unexportedInStruct.mapStructStr[structKey{1}]
_, _ = json.Marshal(unexportedInStruct) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(unexportedInStruct) // struct containing unsafe but unexported fields is safe
_ = err
}
// JSONMarshalSafeStructWithOmittedFieldsWithNoSafe contains a struct with omitted, unsafe fields.
func JSONMarshalSaveStructWithOmittedFieldsWithNoSafe() {
var err error
var omitInStruct struct {
Bool bool // safe exported
F64 float64 `json:"-"` // unsafe exported but omitted
F64Ptr *float64 `json:"-"` // unsafe exported but omitted
F64Slice []float64 `json:"-"` // unsafe exported but omitted
F64Array [10]float64 `json:"-"` // unsafe exported but omitted
MapStrF64 map[string]float64 `json:"-"` // unsafe exported but omitted
MapEIStr map[interface{}]string `json:"-"` // unsafe exported but omitted
Number json.Number `json:"-"` // unsafe exported but omitted
NumberPtr *json.Number `json:"-"` // unsafe exported but omitted
NumberSlice []json.Number `json:"-"` // unsafe exported but omitted
MapNumberStr map[json.Number]string `json:"-"` // unsafe exported but omitted
Ei interface{} `json:"-"` // unsafe exported but omitted
Stringer fmt.Stringer `json:"-"` // unsafe exported but omitted
Mt marshalText `json:"-"` // unsafe exported but omitted
MapMarshalTextString map[marshalText]string `json:"-"` // unsafe exported but omitted
ExportedStruct ExportedUnsafeAndInvalidStruct `json:"-"` // unsafe exported but omitted
ExportedStructPtr *ExportedUnsafeAndInvalidStruct `json:"-"` // unsafe exported but omitted
C128 complex128 `json:"-"` // invalid exported but omitted
C128Slice []complex128 `json:"-"` // invalid exported but omitted
C128Array [10]complex128 `json:"-"` // invalid exported but omitted
MapBoolStr map[bool]string `json:"-"` // invalid exported but omitted
MapF64Str map[float64]string `json:"-"` // invalid exported but omitted
F func() `json:"-"` // invalid exported but omitted
Ch chan struct{} `json:"-"` // invalid exported but omitted
UnsafePtr unsafe.Pointer `json:"-"` // invalid exported but omitted
MapStructStr map[structKey]string `json:"-"` // invalid exported but omitted
}
_ = omitInStruct.MapStructStr[structKey{1}]
_, _ = json.Marshal(omitInStruct) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(omitInStruct) // struct containing unsafe but omitted, exported fields is safe and check-error-free-encoding is false
_ = err
}
// JSONMarshalUnsafeTypes contains a multitude of test cases to marshal different combinations of types to JSON,
// that can potentially lead to json.Marshal returning an error.
func JSONMarshalUnsafeTypes() {
var err error
var f32 float32
json.Marshal(f32) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, _ = json.Marshal(f32) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(f32) // err is checked
_ = err
var f64 float64
_, _ = json.Marshal(f64) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(f64) // err is checked
_ = err
var f32Slice []float32
_, _ = json.Marshal(f32Slice) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(f32Slice) // err is checked
_ = err
var f64Slice []float64
_, _ = json.Marshal(f64Slice) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(f64Slice) // err is checked
_ = err
var f32Array [10]float32
_, _ = json.Marshal(f32Array) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(f32Array) // err is checked
_ = err
var f64Array [10]float64
_, _ = json.Marshal(f64Array) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(f64Array) // err is checked
_ = err
var structPtrF32 struct {
F32 *float32
}
_, _ = json.Marshal(structPtrF32) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(structPtrF32) // err is checked
_ = err
var structPtrF64 struct {
F64 *float64
}
_, _ = json.Marshal(structPtrF64) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(structPtrF64) // err is checked
_ = err
var mapStrF32 map[string]float32
_, _ = json.Marshal(mapStrF32) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(mapStrF32) // err is checked
_ = err
var mapStrF64 map[string]float64
_, _ = json.Marshal(mapStrF64) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(mapStrF64) // err is checked
_ = err
var mapEIStr map[interface{}]string
_, _ = json.Marshal(mapEIStr) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` as map key found"
_, err = json.Marshal(mapEIStr) // err is checked
_ = err
var mapStringerStr map[fmt.Stringer]string
_, _ = json.Marshal(mapStringerStr) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `fmt.Stringer` as map key found"
_, err = json.Marshal(mapStringerStr) // err is checked
_ = err
var number json.Number
_, _ = json.Marshal(number) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
_, err = json.Marshal(number) // err is checked
_ = err
var numberSlice []json.Number
_, _ = json.Marshal(numberSlice) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
_, err = json.Marshal(numberSlice) // err is checked
_ = err
var mapNumberStr map[json.Number]string
_, _ = json.Marshal(mapNumberStr) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` as map key found"
_, err = json.Marshal(mapNumberStr) // err is checked
_ = err
var mapStrNumber map[string]json.Number
_, _ = json.Marshal(mapStrNumber) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
_, err = json.Marshal(mapStrNumber) // err is checked
_ = err
var ei interface{}
_, _ = json.Marshal(ei) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found"
_, err = json.Marshal(ei) // err is checked
_ = err
var eiptr *interface{}
_, _ = json.Marshal(eiptr) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `*interface{}` found"
_, err = json.Marshal(eiptr) // err is checked
_ = err
var stringer fmt.Stringer
_, _ = json.Marshal(stringer) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `fmt.Stringer` found"
_, err = json.Marshal(stringer) // err is checked
_ = err
var structWithEmptyInterface struct {
EmptyInterface interface{}
}
_, _ = json.Marshal(structWithEmptyInterface) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found"
_, err = json.Marshal(structWithEmptyInterface) // err is checked
_ = err
var mt marshalText
_, _ = json.Marshal(mt) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `[a-z-]+.marshalText` found"
_, err = json.Marshal(mt) // err is checked
_ = err
var mapMarshalTextString map[marshalText]string
_, _ = json.Marshal(mapMarshalTextString) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `[a-z-]+.marshalText` as map key found"
_, err = json.Marshal(mapMarshalTextString) // err is checked
_ = err
}
// JSONMarshalInvalidTypes contains a multitude of test cases to marshal different combinations of types to JSON,
// that are invalid and not supported by json.Marshal, that is they will always return an error, if these types used
// with json.Marshal.
func JSONMarshalInvalidTypes() {
var err error
var c64 complex64
json.Marshal(c64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, _ = json.Marshal(c64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, err = json.Marshal(c64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_ = err
var c128 complex128
_, _ = json.Marshal(c128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_, err = json.Marshal(c128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_ = err
var sliceC64 []complex64
_, _ = json.Marshal(sliceC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, err = json.Marshal(sliceC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_ = err
var sliceC128 []complex128
_, _ = json.Marshal(sliceC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_, err = json.Marshal(sliceC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_ = err
var arrayC64 []complex64
_, _ = json.Marshal(arrayC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, err = json.Marshal(arrayC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_ = err
var arrayC128 []complex128
_, _ = json.Marshal(arrayC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_, err = json.Marshal(arrayC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_ = err
var structPtrC64 struct {
C64 *complex64
}
_, _ = json.Marshal(structPtrC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, err = json.Marshal(structPtrC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_ = err
var structPtrC128 struct {
C128 *complex128
}
_, _ = json.Marshal(structPtrC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_, err = json.Marshal(structPtrC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_ = err
var mapBoolStr map[bool]string
_, _ = json.Marshal(mapBoolStr) // want "`encoding/json.Marshal` for unsupported type `bool` as map key found"
_, err = json.Marshal(mapBoolStr) // want "`encoding/json.Marshal` for unsupported type `bool` as map key found"
_ = err
var mapF32Str map[float32]string
_, _ = json.Marshal(mapF32Str) // want "`encoding/json.Marshal` for unsupported type `float32` as map key found"
_, err = json.Marshal(mapF32Str) // want "`encoding/json.Marshal` for unsupported type `float32` as map key found"
_ = err
var mapF64Str map[float64]string
_, _ = json.Marshal(mapF64Str) // want "`encoding/json.Marshal` for unsupported type `float64` as map key found"
_, err = json.Marshal(mapF64Str) // want "`encoding/json.Marshal` for unsupported type `float64` as map key found"
_ = err
var mapC64Str map[complex64]string
_, _ = json.Marshal(mapC64Str) // want "`encoding/json.Marshal` for unsupported type `complex64` as map key found"
_, err = json.Marshal(mapC64Str) // want "`encoding/json.Marshal` for unsupported type `complex64` as map key found"
_ = err
var mapC128Str map[complex128]string
_, _ = json.Marshal(mapC128Str) // want "`encoding/json.Marshal` for unsupported type `complex128` as map key found"
_, err = json.Marshal(mapC128Str) // want "`encoding/json.Marshal` for unsupported type `complex128` as map key found"
_ = err
mapStructStr := map[structKey]string{structKey{1}: "str"}
_, _ = json.Marshal(mapStructStr) // want "`encoding/json.Marshal` for unsupported type `[a-z-]+.structKey` as map key found"
_, err = json.Marshal(mapStructStr) // want "`encoding/json.Marshal` for unsupported type `[a-z-]+.structKey` as map key found"
_ = err
f := func() {}
_, _ = json.Marshal(f) // want "`encoding/json.Marshal` for unsupported type `func\\(\\)` found"
_, err = json.Marshal(f) // want "`encoding/json.Marshal` for unsupported type `func\\(\\)` found"
_ = err
var ch chan struct{} = make(chan struct{})
_, _ = json.Marshal(ch) // want "`encoding/json.Marshal` for unsupported type `chan struct{}` found"
_, err = json.Marshal(ch) // want "`encoding/json.Marshal` for unsupported type `chan struct{}` found"
_ = err
var unsafePtr unsafe.Pointer
_, _ = json.Marshal(unsafePtr) // want "`encoding/json.Marshal` for unsupported type `unsafe.Pointer` found"
_, err = json.Marshal(unsafePtr) // want "`encoding/json.Marshal` for unsupported type `unsafe.Pointer` found"
_ = err
}
// NotJSONMarshal contains other go ast node types, that are not considered by errchkjson
func NotJSONMarshal() {
s := fmt.Sprintln("I am not considered by errchkjson")
_ = s
f := func() bool { return false }
_ = f()
}
// JSONMarshalStructWithoutExportedFields contains a struct without exported fields.
func JSONMarshalStructWithoutExportedFields() {
var err error
var withoutExportedFields struct {
privateField bool
ExportedButOmittedField bool `json:"-"`
}
_, err = json.Marshal(withoutExportedFields)
_ = err
}
// JSONMarshalStructWithoutExportedFields contains a struct without exported fields.
func JSONMarshalStructWithNestedStructWithoutExportedFields() {
var err error
var withNestedStructWithoutExportedFields struct {
ExportedStruct struct {
privatField bool
}
}
_, err = json.Marshal(withNestedStructWithoutExportedFields)
_ = err
}
================================================
FILE: pkg/golinters/errchkjson/testdata/errchkjson.yml
================================================
version: "2"
issues:
max-issues-per-linter: 100
================================================
FILE: pkg/golinters/errchkjson/testdata/errchkjson_cgo.go
================================================
//golangcitest:args -Eerrchkjson
//golangcitest:config_path testdata/errchkjson.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"encoding/json"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
var err error
_, _ = json.Marshal(nil) // want "Error return value of `encoding/json.Marshal` is not checked"
json.Marshal(nil) // want "Error return value of `encoding/json.Marshal` is not checked"
_, err = json.Marshal(nil) // nil is safe and check-error-free-encoding is false
_ = err
}
================================================
FILE: pkg/golinters/errchkjson/testdata/errchkjson_check_error_free_encoding.go
================================================
//golangcitest:args -Eerrchkjson
//golangcitest:config_path testdata/errchkjson_check_error_free_encoding.yml
package testdata
import (
"encoding"
"encoding/json"
"fmt"
"io/ioutil"
"unsafe"
)
type marshalText struct{}
func (mt marshalText) MarshalText() ([]byte, error) {
return []byte(`mt`), nil
}
var _ encoding.TextMarshaler = marshalText(struct{}{})
// JSONMarshalSafeTypes contains a multitude of test cases to marshal different combinations of types to JSON,
// that are safe, that is, they will never return an error, if these types are marshaled to JSON.
func JSONMarshalSafeTypes() {
var err error
_, _ = json.Marshal(nil) // nil is safe
json.Marshal(nil) // nil is safe
_, err = json.Marshal(nil) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
_, _ = json.MarshalIndent(nil, "", " ") // nil is safe
json.MarshalIndent(nil, "", " ") // nil is safe
_, err = json.MarshalIndent(nil, "", " ") // want "Error return value of `encoding/json.MarshalIndent` is checked but passed argument is safe"
_ = err
enc := json.NewEncoder(ioutil.Discard)
_ = enc.Encode(nil) // want "Error return value of `\\([*]encoding/json.Encoder\\).Encode` is not checked"
enc.Encode(nil) // want "Error return value of `\\([*]encoding/json.Encoder\\).Encode` is not checked"
err = enc.Encode(nil)
_ = err
var b bool
_, _ = json.Marshal(b) // bool is safe
_, err = json.Marshal(b) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var i int
_, _ = json.Marshal(i) // int is safe
_, err = json.Marshal(i) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var i8 int8
_, _ = json.Marshal(i8) // int8 is safe
_, err = json.Marshal(i8) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var i16 int16
_, _ = json.Marshal(i16) // int16 is safe
_, err = json.Marshal(i16) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var i32 int32
_, _ = json.Marshal(i32) // int32 / rune is safe
_, err = json.Marshal(i32) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var i64 int64
_, _ = json.Marshal(i64) // int64 is safe
_, err = json.Marshal(i64) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var ui uint
_, _ = json.Marshal(ui) // uint is safe
_, err = json.Marshal(ui) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var ui8 uint8
_, _ = json.Marshal(ui8) // uint8 / byte is safe
_, err = json.Marshal(ui8) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var ui16 uint16
_, _ = json.Marshal(ui16) // uint16 is safe
_, err = json.Marshal(ui16) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var ui32 uint32
_, _ = json.Marshal(ui32) // uint32 / rune is safe
_, err = json.Marshal(ui32) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var ui64 uint64
_, _ = json.Marshal(ui64) // uint64 is safe
_, err = json.Marshal(ui64) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var uiptr uintptr
_, _ = json.Marshal(uiptr) // uintptr is safe
_, err = json.Marshal(uiptr) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var str string
_, _ = json.Marshal(str) // string is safe
_, err = json.Marshal(str) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var strSlice []string
_, _ = json.Marshal(strSlice) // []string is safe
_, err = json.Marshal(strSlice) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var intSlice []int
_, _ = json.Marshal(intSlice) // []int is safe
_, err = json.Marshal(intSlice) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var boolSlice []bool
_, _ = json.Marshal(boolSlice) // []bool is safe
_, err = json.Marshal(boolSlice) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var strArray [10]string
_, _ = json.Marshal(strArray) // [10]string is safe
_, err = json.Marshal(strArray) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var intArray [10]int
_, _ = json.Marshal(intArray) // [10]int is safe
_, err = json.Marshal(intArray) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var boolArray [10]bool
_, _ = json.Marshal(boolArray) // [10]bool is safe
_, err = json.Marshal(boolArray) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var basicStruct struct {
Bool bool
Int int
Int8 int8
Int16 int16
Int32 int32 // also rune
Int64 int64
Uint uint
Uint8 uint8 // also byte
Uint16 uint16
Uint32 uint32
Uint64 uint64
Uintptr uintptr
String string
}
_, _ = json.Marshal(basicStruct) // struct containing only safe basic types is safe
_, err = json.Marshal(basicStruct) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var ptrStruct struct {
Bool *bool
Int *int
Int8 *int8
Int16 *int16
Int32 *int32
Int64 *int64
Uint *uint
Uint8 *uint8
Uint16 *uint16
Uint32 *uint32
Uint64 *uint64
Uintptr *uintptr
String *string
}
_, _ = json.Marshal(ptrStruct) // struct containing pointer to only safe basic types is safe
_, err = json.Marshal(ptrStruct) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var mapStrStr map[string]string
_, _ = json.Marshal(mapStrStr) // map[string]string is safe
_, err = json.Marshal(mapStrStr) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var mapStrInt map[string]int
_, _ = json.Marshal(mapStrInt) // map[string]int is safe
_, err = json.Marshal(mapStrInt) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var mapStrBool map[string]bool
_, _ = json.Marshal(mapStrBool) // map[string]bool is safe
_, err = json.Marshal(mapStrBool) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var mapIntStr map[int]string
_, _ = json.Marshal(mapIntStr) // map[int]string is safe
_, err = json.Marshal(mapIntStr) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var mapIntInt map[int]int
_, _ = json.Marshal(mapIntInt) // map[int]int is safe
_, err = json.Marshal(mapIntInt) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
var mapIntBool map[int]bool
_, _ = json.Marshal(mapIntBool) // map[int]bool is safe
_, err = json.Marshal(mapIntBool) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
type innerStruct struct {
Bool bool
Int int
String string
StrSlice []string
IntSlice []int
BoolSlice []bool
StrArray [10]string
IntArray [10]int
BoolArray [10]bool
MapStrStr map[string]string
MapStrInt map[string]int
MapStrBool map[string]bool
MapIntStr map[int]string
MapIntInt map[int]int
MapIntBool map[int]bool
}
var outerStruct struct {
Bool bool
Int int
String string
StrSlice []string
IntSlice []int
BoolSlice []bool
StrArray [10]string
IntArray [10]int
BoolArray [10]bool
MapStrStr map[string]string
MapStrInt map[string]int
MapStrBool map[string]bool
MapIntStr map[int]string
MapIntInt map[int]int
MapIntBool map[int]bool
InnerStruct innerStruct
}
_, _ = json.Marshal(outerStruct) // struct with only safe types
_, err = json.Marshal(outerStruct) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
}
type (
structKey struct{ id int }
ExportedUnsafeAndInvalidStruct struct { // unsafe unexported but omitted
F64 float64
F64Ptr *float64
F64Slice []float64
F64Array [10]float64
MapStrF64 map[string]float64
MapEIStr map[interface{}]string
Number json.Number
NumberPtr *json.Number
NumberSlice []json.Number
MapNumberStr map[json.Number]string
Ei interface{}
Stringer fmt.Stringer
Mt marshalText
MapMarshalTextString map[marshalText]string
C128 complex128
C128Ptr *complex128
C128Slice []complex128
C128Array [10]complex128
MapBoolStr map[bool]string
MapF64Str map[float64]string
F func()
Ch chan struct{}
UnsafePtr unsafe.Pointer
MapStructStr map[structKey]string
}
)
// JSONMarshalSaveStructWithUnexportedFields contains a struct with unexported, unsafe fields.
func JSONMarshalSaveStructWithUnexportedFields() {
var err error
var unexportedInStruct struct {
Bool bool // safe exported
f64 float64 // unsafe unexported
f64Ptr *float64 // unsafe unexported
f64Slice []float64 // unsafe unexported
f64Array [10]float64 // unsafe unexported
mapStrF64 map[string]float64 // unsafe unexported
mapEIStr map[interface{}]string // unsafe unexported
number json.Number // unsafe unexported
numberPtr *json.Number // unsafe unexported
numberSlice []json.Number // unsafe unexported
mapNumberStr map[json.Number]string // unsafe unexported
ei interface{} // unsafe unexported
stringer fmt.Stringer // unsafe unexported
mt marshalText // unsafe unexported
mapMarshalTextString map[marshalText]string // unsafe unexported
unexportedStruct ExportedUnsafeAndInvalidStruct // unsafe unexported
unexportedStructPtr *ExportedUnsafeAndInvalidStruct // unsafe unexported
c128 complex128 // invalid unexported
c128Slice []complex128 // invalid unexported
c128Array [10]complex128 // invalid unexported
mapBoolStr map[bool]string // invalid unexported
mapF64Str map[float64]string // invalid unexported
f func() // invalid unexported
ch chan struct{} // invalid unexported
unsafePtr unsafe.Pointer // invalid unexported
mapStructStr map[structKey]string // invalid unexported
}
_ = unexportedInStruct.f64
_ = unexportedInStruct.f64Ptr
_ = unexportedInStruct.f64Slice
_ = unexportedInStruct.f64Array
_ = unexportedInStruct.mapStrF64
_ = unexportedInStruct.mapEIStr
_ = unexportedInStruct.number
_ = unexportedInStruct.numberPtr
_ = unexportedInStruct.numberSlice
_ = unexportedInStruct.mapNumberStr
_ = unexportedInStruct.ei
_ = unexportedInStruct.stringer
_ = unexportedInStruct.mt
_ = unexportedInStruct.mapMarshalTextString
_ = unexportedInStruct.unexportedStruct
_ = unexportedInStruct.unexportedStructPtr
_ = unexportedInStruct.c128
_ = unexportedInStruct.c128Slice
_ = unexportedInStruct.c128Array
_ = unexportedInStruct.mapBoolStr
_ = unexportedInStruct.mapF64Str
_ = unexportedInStruct.f
_ = unexportedInStruct.ch
_ = unexportedInStruct.unsafePtr
_ = unexportedInStruct.mapStructStr[structKey{1}]
_, _ = json.Marshal(unexportedInStruct) // struct containing unsafe but unexported fields is safe
_, err = json.Marshal(unexportedInStruct) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
}
// JSONMarshalSaveStructWithOmittedFields contains a struct with omitted, unsafe fields.
func JSONMarshalSaveStructWithOmittedFields() {
var err error
var omitInStruct struct {
Bool bool // safe exported
F64 float64 `json:"-"` // unsafe exported but omitted
F64Ptr *float64 `json:"-"` // unsafe exported but omitted
F64Slice []float64 `json:"-"` // unsafe exported but omitted
F64Array [10]float64 `json:"-"` // unsafe exported but omitted
MapStrF64 map[string]float64 `json:"-"` // unsafe exported but omitted
MapEIStr map[interface{}]string `json:"-"` // unsafe exported but omitted
Number json.Number `json:"-"` // unsafe exported but omitted
NumberPtr *json.Number `json:"-"` // unsafe exported but omitted
NumberSlice []json.Number `json:"-"` // unsafe exported but omitted
MapNumberStr map[json.Number]string `json:"-"` // unsafe exported but omitted
Ei interface{} `json:"-"` // unsafe exported but omitted
Stringer fmt.Stringer `json:"-"` // unsafe exported but omitted
Mt marshalText `json:"-"` // unsafe exported but omitted
MapMarshalTextString map[marshalText]string `json:"-"` // unsafe exported but omitted
ExportedStruct ExportedUnsafeAndInvalidStruct `json:"-"` // unsafe exported but omitted
ExportedStructPtr *ExportedUnsafeAndInvalidStruct `json:"-"` // unsafe exported but omitted
C128 complex128 `json:"-"` // invalid exported but omitted
C128Slice []complex128 `json:"-"` // invalid exported but omitted
C128Array [10]complex128 `json:"-"` // invalid exported but omitted
MapBoolStr map[bool]string `json:"-"` // invalid exported but omitted
MapF64Str map[float64]string `json:"-"` // invalid exported but omitted
F func() `json:"-"` // invalid exported but omitted
Ch chan struct{} `json:"-"` // invalid exported but omitted
UnsafePtr unsafe.Pointer `json:"-"` // invalid exported but omitted
MapStructStr map[structKey]string `json:"-"` // invalid exported but omitted
}
_ = omitInStruct.MapStructStr[structKey{1}]
_, _ = json.Marshal(omitInStruct) // struct containing unsafe but omitted, exported fields is safe
_, err = json.Marshal(omitInStruct) // want "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
_ = err
}
// JSONMarshalUnsafeTypes contains a multitude of test cases to marshal different combinations of types to JSON,
// that can potentially lead to json.Marshal returning an error.
func JSONMarshalUnsafeTypes() {
var err error
var f32 float32
json.Marshal(f32) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, _ = json.Marshal(f32) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(f32) // err is checked
_ = err
var f64 float64
_, _ = json.Marshal(f64) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(f64) // err is checked
_ = err
var f32Slice []float32
_, _ = json.Marshal(f32Slice) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(f32Slice) // err is checked
_ = err
var f64Slice []float64
_, _ = json.Marshal(f64Slice) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(f64Slice) // err is checked
_ = err
var f32Array [10]float32
_, _ = json.Marshal(f32Array) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(f32Array) // err is checked
_ = err
var f64Array [10]float64
_, _ = json.Marshal(f64Array) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(f64Array) // err is checked
_ = err
var structPtrF32 struct {
F32 *float32
}
_, _ = json.Marshal(structPtrF32) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(structPtrF32) // err is checked
_ = err
var structPtrF64 struct {
F64 *float64
}
_, _ = json.Marshal(structPtrF64) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(structPtrF64) // err is checked
_ = err
var mapStrF32 map[string]float32
_, _ = json.Marshal(mapStrF32) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
_, err = json.Marshal(mapStrF32) // err is checked
_ = err
var mapStrF64 map[string]float64
_, _ = json.Marshal(mapStrF64) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
_, err = json.Marshal(mapStrF64) // err is checked
_ = err
var mapEIStr map[interface{}]string
_, _ = json.Marshal(mapEIStr) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` as map key found"
_, err = json.Marshal(mapEIStr) // err is checked
_ = err
var mapStringerStr map[fmt.Stringer]string
_, _ = json.Marshal(mapStringerStr) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `fmt.Stringer` as map key found"
_, err = json.Marshal(mapStringerStr) // err is checked
_ = err
var number json.Number
_, _ = json.Marshal(number) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
_, err = json.Marshal(number) // err is checked
_ = err
var numberSlice []json.Number
_, _ = json.Marshal(numberSlice) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
_, err = json.Marshal(numberSlice) // err is checked
_ = err
var mapNumberStr map[json.Number]string
_, _ = json.Marshal(mapNumberStr) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` as map key found"
_, err = json.Marshal(mapNumberStr) // err is checked
_ = err
var mapStrNumber map[string]json.Number
_, _ = json.Marshal(mapStrNumber) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
_, err = json.Marshal(mapStrNumber) // err is checked
_ = err
var ei interface{}
_, _ = json.Marshal(ei) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found"
_, err = json.Marshal(ei) // err is checked
_ = err
var eiptr *interface{}
_, _ = json.Marshal(eiptr) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `*interface{}` found"
_, err = json.Marshal(eiptr) // err is checked
_ = err
var stringer fmt.Stringer
_, _ = json.Marshal(stringer) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `fmt.Stringer` found"
_, err = json.Marshal(stringer) // err is checked
_ = err
var structWithEmptyInterface struct {
EmptyInterface interface{}
}
_, _ = json.Marshal(structWithEmptyInterface) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found"
_, err = json.Marshal(structWithEmptyInterface) // err is checked
_ = err
var mt marshalText
_, _ = json.Marshal(mt) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `[a-z-]+.marshalText` found"
_, err = json.Marshal(mt) // err is checked
_ = err
var mapMarshalTextString map[marshalText]string
_, _ = json.Marshal(mapMarshalTextString) // want "Error return value of `encoding/json.Marshal` is not checked: unsafe type `[a-z-]+.marshalText` as map key found"
_, err = json.Marshal(mapMarshalTextString) // err is checked
_ = err
}
// JSONMarshalInvalidTypes contains a multitude of test cases to marshal different combinations of types to JSON,
// that are invalid and not supported by json.Marshal, that is they will always return an error, if these types used
// with json.Marshal.
func JSONMarshalInvalidTypes() {
var err error
var c64 complex64
json.Marshal(c64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, _ = json.Marshal(c64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, err = json.Marshal(c64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_ = err
var c128 complex128
_, _ = json.Marshal(c128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_, err = json.Marshal(c128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_ = err
var sliceC64 []complex64
_, _ = json.Marshal(sliceC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, err = json.Marshal(sliceC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_ = err
var sliceC128 []complex128
_, _ = json.Marshal(sliceC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_, err = json.Marshal(sliceC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_ = err
var arrayC64 []complex64
_, _ = json.Marshal(arrayC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, err = json.Marshal(arrayC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_ = err
var arrayC128 []complex128
_, _ = json.Marshal(arrayC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_, err = json.Marshal(arrayC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_ = err
var structPtrC64 struct {
C64 *complex64
}
_, _ = json.Marshal(structPtrC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_, err = json.Marshal(structPtrC64) // want "`encoding/json.Marshal` for unsupported type `complex64` found"
_ = err
var structPtrC128 struct {
C128 *complex128
}
_, _ = json.Marshal(structPtrC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_, err = json.Marshal(structPtrC128) // want "`encoding/json.Marshal` for unsupported type `complex128` found"
_ = err
var mapBoolStr map[bool]string
_, _ = json.Marshal(mapBoolStr) // want "`encoding/json.Marshal` for unsupported type `bool` as map key found"
_, err = json.Marshal(mapBoolStr) // want "`encoding/json.Marshal` for unsupported type `bool` as map key found"
_ = err
var mapF32Str map[float32]string
_, _ = json.Marshal(mapF32Str) // want "`encoding/json.Marshal` for unsupported type `float32` as map key found"
_, err = json.Marshal(mapF32Str) // want "`encoding/json.Marshal` for unsupported type `float32` as map key found"
_ = err
var mapF64Str map[float64]string
_, _ = json.Marshal(mapF64Str) // want "`encoding/json.Marshal` for unsupported type `float64` as map key found"
_, err = json.Marshal(mapF64Str) // want "`encoding/json.Marshal` for unsupported type `float64` as map key found"
_ = err
var mapC64Str map[complex64]string
_, _ = json.Marshal(mapC64Str) // want "`encoding/json.Marshal` for unsupported type `complex64` as map key found"
_, err = json.Marshal(mapC64Str) // want "`encoding/json.Marshal` for unsupported type `complex64` as map key found"
_ = err
var mapC128Str map[complex128]string
_, _ = json.Marshal(mapC128Str) // want "`encoding/json.Marshal` for unsupported type `complex128` as map key found"
_, err = json.Marshal(mapC128Str) // want "`encoding/json.Marshal` for unsupported type `complex128` as map key found"
_ = err
mapStructStr := map[structKey]string{structKey{1}: "str"}
_, _ = json.Marshal(mapStructStr) // want "`encoding/json.Marshal` for unsupported type `[a-z-]+.structKey` as map key found"
_, err = json.Marshal(mapStructStr) // want "`encoding/json.Marshal` for unsupported type `[a-z-]+.structKey` as map key found"
_ = err
f := func() {}
_, _ = json.Marshal(f) // want "`encoding/json.Marshal` for unsupported type `func\\(\\)` found"
_, err = json.Marshal(f) // want "`encoding/json.Marshal` for unsupported type `func\\(\\)` found"
_ = err
var ch chan struct{} = make(chan struct{})
_, _ = json.Marshal(ch) // want "`encoding/json.Marshal` for unsupported type `chan struct{}` found"
_, err = json.Marshal(ch) // want "`encoding/json.Marshal` for unsupported type `chan struct{}` found"
_ = err
var unsafePtr unsafe.Pointer
_, _ = json.Marshal(unsafePtr) // want "`encoding/json.Marshal` for unsupported type `unsafe.Pointer` found"
_, err = json.Marshal(unsafePtr) // want "`encoding/json.Marshal` for unsupported type `unsafe.Pointer` found"
_ = err
}
// NotJSONMarshal contains other go ast node types, that are not considered by errchkjson
func NotJSONMarshal() {
s := fmt.Sprintln("I am not considered by errchkjson")
_ = s
f := func() bool { return false }
_ = f()
}
================================================
FILE: pkg/golinters/errchkjson/testdata/errchkjson_check_error_free_encoding.yml
================================================
version: "2"
issues:
max-issues-per-linter: 100
linters:
settings:
errchkjson:
check-error-free-encoding: true
================================================
FILE: pkg/golinters/errchkjson/testdata/errchkjson_no_exported.go
================================================
//golangcitest:args -Eerrchkjson
//golangcitest:config_path testdata/errchkjson_no_exported.yml
package testdata
import (
"encoding/json"
)
// JSONMarshalStructWithoutExportedFields contains a struct without exported fields.
func JSONMarshalStructWithoutExportedFields() {
var withoutExportedFields struct {
privateField bool
ExportedButOmittedField bool `json:"-"`
}
_, err := json.Marshal(withoutExportedFields) // want "Error argument passed to `encoding/json.Marshal` does not contain any exported field"
_ = err
}
// JSONMarshalStructWithNestedStructWithoutExportedFields contains a struct without exported fields.
func JSONMarshalStructWithNestedStructWithoutExportedFields() {
var withNestedStructWithoutExportedFields struct {
ExportedStruct struct {
privatField bool
}
}
_, err := json.Marshal(withNestedStructWithoutExportedFields)
_ = err
}
================================================
FILE: pkg/golinters/errchkjson/testdata/errchkjson_no_exported.yml
================================================
version: "2"
linters:
settings:
errchkjson:
report-no-exported: true
================================================
FILE: pkg/golinters/errname/errname.go
================================================
package errname
import (
"github.com/Antonboom/errname/pkg/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(analyzer.New()).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/errname/errname_integration_test.go
================================================
package errname
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/errname/testdata/errname.go
================================================
//golangcitest:args -Eerrname
package testdata
import (
"errors"
"fmt"
)
var (
EOF = errors.New("end of file")
ErrEndOfFile = errors.New("end of file")
errEndOfFile = errors.New("end of file")
EndOfFileError = errors.New("end of file") // want "the sentinel error name `EndOfFileError` should conform to the `ErrXxx` format"
ErrorEndOfFile = errors.New("end of file") // want "the sentinel error name `ErrorEndOfFile` should conform to the `ErrXxx` format"
EndOfFileErr = errors.New("end of file") // want "the sentinel error name `EndOfFileErr` should conform to the `ErrXxx` format"
endOfFileError = errors.New("end of file") // want "the sentinel error name `endOfFileError` should conform to the `errXxx` format"
errorEndOfFile = errors.New("end of file") // want "the sentinel error name `errorEndOfFile` should conform to the `errXxx` format"
)
const maxSize = 256
var (
ErrOutOfSize = fmt.Errorf("out of size (max %d)", maxSize)
errOutOfSize = fmt.Errorf("out of size (max %d)", maxSize)
OutOfSizeError = fmt.Errorf("out of size (max %d)", maxSize) // want "the sentinel error name `OutOfSizeError` should conform to the `ErrXxx` format"
outOfSizeError = fmt.Errorf("out of size (max %d)", maxSize) // want "the sentinel error name `outOfSizeError` should conform to the `errXxx` format"
)
func errInsideFuncIsNotSentinel() error {
var lastErr error
return lastErr
}
type NotErrorType struct{}
func (t NotErrorType) Set() {}
func (t NotErrorType) Get() {}
type DNSConfigError struct{}
func (D DNSConfigError) Error() string { return "DNS config error" }
type someTypeWithoutPtr struct{} // want "the error type name `someTypeWithoutPtr` should conform to the `xxxError` format"
func (s someTypeWithoutPtr) Error() string { return "someTypeWithoutPtr" }
type SomeTypeWithoutPtr struct{} // want "the error type name `SomeTypeWithoutPtr` should conform to the `XxxError` format"
func (s SomeTypeWithoutPtr) Error() string { return "SomeTypeWithoutPtr" }
type someTypeWithPtr struct{} // want "the error type name `someTypeWithPtr` should conform to the `xxxError` format"
func (s *someTypeWithPtr) Error() string { return "someTypeWithPtr" }
type SomeTypeWithPtr struct{} // want "the error type name `SomeTypeWithPtr` should conform to the `XxxError` format"
func (s *SomeTypeWithPtr) Error() string { return "SomeTypeWithPtr" }
================================================
FILE: pkg/golinters/errname/testdata/errname_cgo.go
================================================
//golangcitest:args -Eerrname
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"errors"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
var (
EOF = errors.New("end of file")
ErrEndOfFile = errors.New("end of file")
errEndOfFile = errors.New("end of file")
EndOfFileError = errors.New("end of file") // want "the sentinel error name `EndOfFileError` should conform to the `ErrXxx` format"
ErrorEndOfFile = errors.New("end of file") // want "the sentinel error name `ErrorEndOfFile` should conform to the `ErrXxx` format"
EndOfFileErr = errors.New("end of file") // want "the sentinel error name `EndOfFileErr` should conform to the `ErrXxx` format"
endOfFileError = errors.New("end of file") // want "the sentinel error name `endOfFileError` should conform to the `errXxx` format"
errorEndOfFile = errors.New("end of file") // want "the sentinel error name `errorEndOfFile` should conform to the `errXxx` format"
)
================================================
FILE: pkg/golinters/errorlint/errorlint.go
================================================
package errorlint
import (
"codeberg.org/polyfloyd/go-errorlint/errorlint"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ErrorLintSettings) *goanalysis.Linter {
var opts []errorlint.Option
if settings != nil {
ae := toAllowPairs(settings.AllowedErrors)
if len(ae) > 0 {
opts = append(opts, errorlint.WithAllowedErrors(ae))
}
aew := toAllowPairs(settings.AllowedErrorsWildcard)
if len(aew) > 0 {
opts = append(opts, errorlint.WithAllowedWildcard(aew))
}
}
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"errorf": settings.Errorf,
"errorf-multi": settings.ErrorfMulti,
"asserts": settings.Asserts,
"comparison": settings.Comparison,
}
}
return goanalysis.
NewLinterFromAnalyzer(errorlint.NewAnalyzer(opts...)).
WithDesc("Find code that can cause problems with the error wrapping scheme introduced in Go 1.13.").
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func toAllowPairs(data []config.ErrorLintAllowPair) []errorlint.AllowPair {
var pairs []errorlint.AllowPair
for _, allowedError := range data {
pairs = append(pairs, errorlint.AllowPair(allowedError))
}
return pairs
}
================================================
FILE: pkg/golinters/errorlint/errorlint_integration_test.go
================================================
package errorlint
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/errorlint/testdata/errorlint.go
================================================
//golangcitest:args -Eerrorlint
package testdata
import (
"errors"
"fmt"
"log"
)
var errLintFoo = errors.New("foo")
type errLintBar struct{}
func (*errLintBar) Error() string {
return "bar"
}
func errorLintAll() {
err := func() error { return nil }()
if err == errLintFoo { // want "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errCompare")
}
err = errors.New("oops")
fmt.Errorf("error: %v", err) // want "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors"
switch err.(type) { // want "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *errLintBar:
log.Println("errLintBar")
}
}
================================================
FILE: pkg/golinters/errorlint/testdata/errorlint_asserts.go
================================================
//golangcitest:args -Eerrorlint
//golangcitest:config_path testdata/errorlint_asserts.yml
package testdata
import (
"errors"
"log"
)
type myError struct{}
func (*myError) Error() string {
return "foo"
}
func errorLintDoAnotherThing() error {
return &myError{}
}
func errorLintAsserts() {
err := errorLintDoAnotherThing()
var me *myError
if errors.As(err, &me) {
log.Println("myError")
}
_, ok := err.(*myError) // want "type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors"
if ok {
log.Println("myError")
}
switch err.(type) { // want "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError")
}
switch errorLintDoAnotherThing().(type) { // want "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError")
}
switch t := err.(type) { // want "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError", t)
}
switch t := errorLintDoAnotherThing().(type) { // want "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError", t)
}
}
================================================
FILE: pkg/golinters/errorlint/testdata/errorlint_asserts.yml
================================================
version: "2"
linters:
settings:
errorlint:
errorf: false
asserts: true
comparison: false
================================================
FILE: pkg/golinters/errorlint/testdata/errorlint_cgo.go
================================================
//golangcitest:args -Eerrorlint
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"errors"
"fmt"
"log"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
var errLintFoo = errors.New("foo")
type errLintBar struct{}
func (*errLintBar) Error() string {
return "bar"
}
func errorLintAll() {
err := func() error { return nil }()
if err == errLintFoo { // want "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errCompare")
}
err = errors.New("oops")
fmt.Errorf("error: %v", err) // want "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors"
switch err.(type) { // want "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *errLintBar:
log.Println("errLintBar")
}
}
================================================
FILE: pkg/golinters/errorlint/testdata/errorlint_comparison.go
================================================
//golangcitest:args -Eerrorlint
//golangcitest:config_path testdata/errorlint_comparison.yml
package testdata
import (
"errors"
"log"
)
var errCompare = errors.New("foo")
func errorLintDoThing() error {
return errCompare
}
func errorLintComparison() {
err := errorLintDoThing()
if errors.Is(err, errCompare) {
log.Println("errCompare")
}
if err == nil {
log.Println("nil")
}
if err != nil {
log.Println("nil")
}
if nil == err {
log.Println("nil")
}
if nil != err {
log.Println("nil")
}
if err == errCompare { // want "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errCompare")
}
if err != errCompare { // want "comparing with != will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("not errCompare")
}
if errCompare == err { // want "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errCompare")
}
if errCompare != err { // want "comparing with != will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("not errCompare")
}
switch err {
case errCompare: // want "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors"
log.Println("errCompare")
}
switch errorLintDoThing() {
case errCompare: // want "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors"
log.Println("errCompare")
}
}
================================================
FILE: pkg/golinters/errorlint/testdata/errorlint_comparison.yml
================================================
version: "2"
linters:
settings:
errorlint:
errorf: false
asserts: false
comparison: true
================================================
FILE: pkg/golinters/errorlint/testdata/errorlint_errorf.go
================================================
//golangcitest:args -Eerrorlint
//golangcitest:config_path testdata/errorlint_errorf.yml
package testdata
import (
"errors"
"fmt"
)
type customError struct{}
func (customError) Error() string {
return "oops"
}
func errorLintErrorf() {
err := errors.New("oops")
fmt.Errorf("error: %w", err)
fmt.Errorf("error: %v", err) // want "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors"
fmt.Errorf("%v %v", err, err) // want "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors"
fmt.Errorf("error: %s", err.Error())
customError := customError{}
fmt.Errorf("error: %s", customError.Error())
strErr := "oops"
fmt.Errorf("%v", strErr)
}
================================================
FILE: pkg/golinters/errorlint/testdata/errorlint_errorf.yml
================================================
version: "2"
linters:
settings:
errorlint:
errorf: true
asserts: false
comparison: false
================================================
FILE: pkg/golinters/errorlint/testdata/fix/in/errorlint.go
================================================
//golangcitest:args -Eerrorlint
//golangcitest:expected_exitcode 0
package testdata
import (
"errors"
"fmt"
)
func Good() error {
err := errors.New("oops")
return fmt.Errorf("error: %w", err)
}
func NonWrappingVerb() error {
err := errors.New("oops")
return fmt.Errorf("error: %v", err)
}
func NonWrappingTVerb() error {
err := errors.New("oops")
return fmt.Errorf("error: %T", err)
}
func DoubleNonWrappingVerb() error {
err := errors.New("oops")
return fmt.Errorf("%v %v", err, err)
}
func ErrorOneWrap() error {
err1 := errors.New("oops1")
err2 := errors.New("oops2")
err3 := errors.New("oops3")
return fmt.Errorf("%v, %w, %v", err1, err2, err3)
}
func ValidNonWrappingTVerb() error {
err1 := errors.New("oops1")
err2 := errors.New("oops2")
err3 := errors.New("oops3")
return fmt.Errorf("%w, %T, %w", err1, err2, err3)
}
func ErrorMultipleWraps() error {
err1 := errors.New("oops1")
err2 := errors.New("oops2")
err3 := errors.New("oops3")
return fmt.Errorf("%w, %w, %w", err1, err2, err3)
}
func ErrorMultipleWrapsWithCustomError() error {
err1 := errors.New("oops1")
err2 := MyError{}
err3 := errors.New("oops3")
return fmt.Errorf("%w, %w, %w", err1, err2, err3)
}
func ErrorStringFormat() error {
err := errors.New("oops")
return fmt.Errorf("error: %s", err.Error())
}
func ErrorStringFormatCustomError() error {
err := MyError{}
return fmt.Errorf("error: %s", err.Error())
}
func NotAnError() error {
err := "oops"
return fmt.Errorf("%v", err)
}
type MyError struct{}
func (MyError) Error() string {
return "oops"
}
func ErrorIndexReset() error {
err := errors.New("oops1")
return fmt.Errorf("%[1]v %d %f %[1]v, %d, %f", err, 1, 2.2)
}
func ErrorIndexResetGood() error {
err := errors.New("oops1")
return fmt.Errorf("%[1]w %d %f %[1]w, %d, %f", err, 1, 2.2)
}
================================================
FILE: pkg/golinters/errorlint/testdata/fix/out/errorlint.go
================================================
//golangcitest:args -Eerrorlint
//golangcitest:expected_exitcode 0
package testdata
import (
"errors"
"fmt"
)
func Good() error {
err := errors.New("oops")
return fmt.Errorf("error: %w", err)
}
func NonWrappingVerb() error {
err := errors.New("oops")
return fmt.Errorf("error: %w", err)
}
func NonWrappingTVerb() error {
err := errors.New("oops")
return fmt.Errorf("error: %T", err)
}
func DoubleNonWrappingVerb() error {
err := errors.New("oops")
return fmt.Errorf("%w %w", err, err)
}
func ErrorOneWrap() error {
err1 := errors.New("oops1")
err2 := errors.New("oops2")
err3 := errors.New("oops3")
return fmt.Errorf("%w, %w, %w", err1, err2, err3)
}
func ValidNonWrappingTVerb() error {
err1 := errors.New("oops1")
err2 := errors.New("oops2")
err3 := errors.New("oops3")
return fmt.Errorf("%w, %T, %w", err1, err2, err3)
}
func ErrorMultipleWraps() error {
err1 := errors.New("oops1")
err2 := errors.New("oops2")
err3 := errors.New("oops3")
return fmt.Errorf("%w, %w, %w", err1, err2, err3)
}
func ErrorMultipleWrapsWithCustomError() error {
err1 := errors.New("oops1")
err2 := MyError{}
err3 := errors.New("oops3")
return fmt.Errorf("%w, %w, %w", err1, err2, err3)
}
func ErrorStringFormat() error {
err := errors.New("oops")
return fmt.Errorf("error: %s", err.Error())
}
func ErrorStringFormatCustomError() error {
err := MyError{}
return fmt.Errorf("error: %s", err.Error())
}
func NotAnError() error {
err := "oops"
return fmt.Errorf("%v", err)
}
type MyError struct{}
func (MyError) Error() string {
return "oops"
}
func ErrorIndexReset() error {
err := errors.New("oops1")
return fmt.Errorf("%[1]w %d %f %[1]w, %d, %f", err, 1, 2.2)
}
func ErrorIndexResetGood() error {
err := errors.New("oops1")
return fmt.Errorf("%[1]w %d %f %[1]w, %d, %f", err, 1, 2.2)
}
================================================
FILE: pkg/golinters/exhaustive/exhaustive.go
================================================
package exhaustive
import (
"github.com/nishanths/exhaustive"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ExhaustiveSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
exhaustive.CheckFlag: settings.Check,
exhaustive.DefaultSignifiesExhaustiveFlag: settings.DefaultSignifiesExhaustive,
exhaustive.IgnoreEnumMembersFlag: settings.IgnoreEnumMembers,
exhaustive.IgnoreEnumTypesFlag: settings.IgnoreEnumTypes,
exhaustive.PackageScopeOnlyFlag: settings.PackageScopeOnly,
exhaustive.ExplicitExhaustiveMapFlag: settings.ExplicitExhaustiveMap,
exhaustive.ExplicitExhaustiveSwitchFlag: settings.ExplicitExhaustiveSwitch,
exhaustive.DefaultCaseRequiredFlag: settings.DefaultCaseRequired,
// Should be managed with `linters.exclusions.generated`.
exhaustive.CheckGeneratedFlag: true,
}
}
return goanalysis.
NewLinterFromAnalyzer(exhaustive.Analyzer).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/exhaustive/exhaustive_integration_test.go
================================================
package exhaustive
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/exhaustive/testdata/exhaustive.go
================================================
//golangcitest:args -Eexhaustive
package testdata
type Direction int
const (
North Direction = iota
East
South
West
)
func processDirection(d Direction) {
switch d { // want "missing cases in switch of type testdata.Direction: testdata.East, testdata.West"
case North, South:
}
}
================================================
FILE: pkg/golinters/exhaustive/testdata/exhaustive_cgo.go
================================================
//go:build ignore
// TODO(ldez) the linter doesn't support cgo.
//golangcitest:args -Eexhaustive
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type Direction int
const (
North Direction = iota
East
South
West
)
func processDirection(d Direction) {
switch d { // want "missing cases in switch of type testdata.Direction: testdata.East, testdata.West"
case North, South:
}
}
================================================
FILE: pkg/golinters/exhaustive/testdata/exhaustive_default.go
================================================
//golangcitest:args -Eexhaustive
//golangcitest:config_path testdata/exhaustive_default.yml
//golangcitest:expected_exitcode 0
package testdata
type Direction int
const (
North Direction = iota
East
South
West
)
// Should not report missing cases in the switch statement below even though
// some enum members (East, West) are not listed, because the switch statement
// has a 'default' case and the default-signifies-exhaustive setting is true.
func processDirectionDefault(d Direction) {
switch d {
case North, South:
default:
}
}
================================================
FILE: pkg/golinters/exhaustive/testdata/exhaustive_default.yml
================================================
version: "2"
linters:
settings:
exhaustive:
default-signifies-exhaustive: true
================================================
FILE: pkg/golinters/exhaustive/testdata/exhaustive_generated.go
================================================
// Code generated by some program. DO NOT EDIT.
//golangcitest:args -Eexhaustive
//golangcitest:expected_exitcode 0
package testdata
// Should not report missing cases in the switch statement below, because this
// is a generated file as indicated by the above comment
// (golang.org/s/generatedcode), and check-generated setting is false.
type Direction int
const (
North Direction = iota
East
South
West
)
func processDirectionGenerated(d Direction) {
switch d {
case North, South:
}
}
================================================
FILE: pkg/golinters/exhaustive/testdata/exhaustive_ignore_enum_members.go
================================================
//golangcitest:args -Eexhaustive
//golangcitest:config_path testdata/exhaustive_ignore_enum_members.yml
package testdata
type Direction int
const (
North Direction = iota
East
South
West
)
// Should only report East as missing because the enum member West is ignored
// using the ignore-enum-members setting.
func processDirectionIgnoreEnumMembers(d Direction) {
switch d { // want "missing cases in switch of type testdata.Direction: testdata.East"
case North, South:
}
}
================================================
FILE: pkg/golinters/exhaustive/testdata/exhaustive_ignore_enum_members.yml
================================================
version: "2"
linters:
settings:
exhaustive:
ignore-enum-members: "West$"
================================================
FILE: pkg/golinters/exhaustruct/exhaustruct.go
================================================
package exhaustruct
import (
exhaustruct "dev.gaijin.team/go/exhaustruct/v4/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.ExhaustructSettings) *goanalysis.Linter {
cfg := exhaustruct.Config{}
if settings != nil {
cfg.IncludeRx = settings.Include
cfg.ExcludeRx = settings.Exclude
cfg.AllowEmpty = settings.AllowEmpty
cfg.AllowEmptyRx = settings.AllowEmptyRx
cfg.AllowEmptyReturns = settings.AllowEmptyReturns
cfg.AllowEmptyDeclarations = settings.AllowEmptyDeclarations
}
analyzer, err := exhaustruct.NewAnalyzer(cfg)
if err != nil {
internal.LinterLogger.Fatalf("exhaustruct configuration: %v", err)
}
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/exhaustruct/exhaustruct_integration_test.go
================================================
package exhaustruct
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/exhaustruct/testdata/exhaustruct.go
================================================
//golangcitest:args -Eexhaustruct
package testdata
import "time"
type Exhaustruct struct {
A string
B int
c bool // private field inside the same package are not ignored
D float64
E time.Time
}
func exhaustruct() {
// pass
_ = Exhaustruct{
A: "a",
B: 0,
c: false,
D: 1.0,
E: time.Now(),
}
// failPrivate
_ = Exhaustruct{ // want "testdata.Exhaustruct is missing field c"
A: "a",
B: 0,
D: 1.0,
E: time.Now(),
}
// fail
_ = Exhaustruct{ // want "testdata.Exhaustruct is missing field B"
A: "a",
c: false,
D: 1.0,
E: time.Now(),
}
// failMultiple
_ = Exhaustruct{ // want "testdata.Exhaustruct is missing fields B, D"
A: "a",
c: false,
E: time.Now(),
}
}
================================================
FILE: pkg/golinters/exhaustruct/testdata/exhaustruct_cgo.go
================================================
//golangcitest:args -Eexhaustruct
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"time"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type Exhaustruct struct {
A string
B int
c bool // private field inside the same package are not ignored
D float64
E time.Time
}
func exhaustruct() {
// pass
_ = Exhaustruct{
A: "a",
B: 0,
c: false,
D: 1.0,
E: time.Now(),
}
// failPrivate
_ = Exhaustruct{ // want "testdata.Exhaustruct is missing field c"
A: "a",
B: 0,
D: 1.0,
E: time.Now(),
}
// fail
_ = Exhaustruct{ // want "testdata.Exhaustruct is missing field B"
A: "a",
c: false,
D: 1.0,
E: time.Now(),
}
// failMultiple
_ = Exhaustruct{ // want "testdata.Exhaustruct is missing fields B, D"
A: "a",
c: false,
E: time.Now(),
}
}
================================================
FILE: pkg/golinters/exhaustruct/testdata/exhaustruct_custom.go
================================================
//golangcitest:args -Eexhaustruct
//golangcitest:config_path testdata/exhaustruct_custom.yml
package testdata
import "time"
type ExhaustructCustom struct {
A string
B int
c bool // private field inside the same package are not ignored
D float64
E time.Time
}
func exhaustructCustom() {
// pass
_ = ExhaustructCustom{
A: "a",
B: 0,
c: false,
D: 1.0,
E: time.Now(),
}
// fail
_ = ExhaustructCustom{ // want "testdata.ExhaustructCustom is missing field B"
A: "a",
c: false,
D: 1.0,
E: time.Now(),
}
// failMultiple
_ = ExhaustructCustom{ // want "testdata.ExhaustructCustom is missing fields B, D"
A: "a",
c: false,
E: time.Now(),
}
// failPrivate
_ = ExhaustructCustom{ // want "testdata.ExhaustructCustom is missing field c"
A: "a",
B: 0,
D: 1.0,
E: time.Now(),
}
}
type ExhaustructCustom1 struct {
A string
B int
c bool // private field inside the same package are not ignored
D float64
E time.Time
}
func exhaustructCustom1() {
// pass
_ = ExhaustructCustom{
A: "a",
B: 0,
c: false,
D: 1.0,
E: time.Now(),
}
// fail
_ = ExhaustructCustom1{
A: "a",
c: false,
D: 1.0,
E: time.Now(),
}
// failMultiple
_ = ExhaustructCustom1{
A: "a",
c: false,
E: time.Now(),
}
// failPrivate
_ = ExhaustructCustom1{
A: "a",
B: 0,
D: 1.0,
E: time.Now(),
}
}
type ExhaustructCustom2 struct {
A string
B int
c bool // private field inside the same package are not ignored
D float64
E time.Time
}
func exhaustructCustom2() {
// pass
_ = ExhaustructCustom2{
A: "a",
B: 0,
c: false,
D: 1.0,
E: time.Now(),
}
// fail
_ = ExhaustructCustom2{
A: "a",
c: false,
D: 1.0,
E: time.Now(),
}
// failMultiple
_ = ExhaustructCustom2{
A: "a",
c: false,
E: time.Now(),
}
// failPrivate
_ = ExhaustructCustom2{
A: "a",
B: 0,
D: 1.0,
E: time.Now(),
}
}
================================================
FILE: pkg/golinters/exhaustruct/testdata/exhaustruct_custom.yml
================================================
version: "2"
linters:
settings:
exhaustruct:
include:
- .*\.ExhaustructCustom
exclude:
- .*\.ExhaustructCustom[\d]{1,2}
================================================
FILE: pkg/golinters/exptostd/exptostd.go
================================================
package exptostd
import (
"github.com/ldez/exptostd"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(exptostd.NewAnalyzer()).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/exptostd/exptostd_integration_test.go
================================================
package exptostd
import (
"testing"
// Without this dependency, the analyzer tests related to fix fails.
// The packages `slices` have been randomly chosen to import `golang.org/x/exp`.
_ "golang.org/x/exp/slices"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/exptostd/testdata/exptostd.go
================================================
//golangcitest:args -Eexptostd
package testdata
import (
"fmt"
"golang.org/x/exp/maps" // want `Import statement 'golang.org/x/exp/maps' may be replaced by 'maps'`
"golang.org/x/exp/slices" // want `Import statement 'golang.org/x/exp/slices' may be replaced by 'slices'`
)
func _(m, a map[string]string) {
maps.Clone(m) // want `golang.org/x/exp/maps.Clone\(\) can be replaced by maps.Clone\(\)`
maps.Keys(m) // want `golang.org/x/exp/maps\.Keys\(\) can be replaced by slices\.AppendSeq\(make\(\[\]T, 0, len\(data\)\), maps\.Keys\(data\)\)`
maps.Values(m) // want `golang.org/x/exp/maps\.Values\(\) can be replaced by slices\.AppendSeq\(make\(\[\]T, 0, len\(data\)\), maps\.Values\(data\)\)`
maps.Equal(m, a) // want `golang.org/x/exp/maps.Equal\(\) can be replaced by maps.Equal\(\)`
maps.EqualFunc(m, a, func(i, j string) bool { // want `golang.org/x/exp/maps.EqualFunc\(\) can be replaced by maps.EqualFunc\(\)`
return true
})
maps.Copy(m, a) // want `golang.org/x/exp/maps.Copy\(\) can be replaced by maps.Copy\(\)`
maps.DeleteFunc(m, func(_, _ string) bool { // want `golang.org/x/exp/maps.DeleteFunc\(\) can be replaced by maps.DeleteFunc\(\)`
return true
})
maps.Clear(m) // want `golang.org/x/exp/maps.Clear\(\) can be replaced by clear\(\)`
fmt.Println("Hello")
}
func _(a, b []string) {
slices.Equal(a, b)
slices.EqualFunc(a, b, func(_ string, _ string) bool {
return true
})
slices.Compare(a, b)
slices.CompareFunc(a, b, func(_ string, _ string) int {
return 0
})
slices.Index(a, "a")
slices.IndexFunc(a, func(_ string) bool {
return true
})
slices.Contains(a, "a")
slices.ContainsFunc(a, func(_ string) bool {
return true
})
slices.Insert(a, 0, "a", "b")
slices.Delete(a, 0, 1)
slices.DeleteFunc(a, func(_ string) bool {
return true
})
slices.Replace(a, 0, 1, "a")
slices.Clone(a)
slices.Compact(a)
slices.CompactFunc(a, func(_ string, _ string) bool {
return true
})
slices.Grow(a, 2)
slices.Clip(a)
slices.Reverse(a)
slices.Sort(a)
slices.SortFunc(a, func(_, _ string) int {
return 0
})
slices.SortStableFunc(a, func(_, _ string) int {
return 0
})
slices.IsSorted(a)
slices.IsSortedFunc(a, func(_, _ string) int {
return 0
})
slices.Min(a)
slices.MinFunc(a, func(_, _ string) int {
return 0
})
slices.Max(a)
slices.MaxFunc(a, func(_, _ string) int {
return 0
})
slices.BinarySearch(a, "a")
slices.BinarySearchFunc(a, b, func(_ string, _ []string) int {
return 0
})
}
================================================
FILE: pkg/golinters/exptostd/testdata/exptostd_cgo.go
================================================
//golangcitest:args -Eexptostd
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
"golang.org/x/exp/maps" // want `Import statement 'golang.org/x/exp/maps' may be replaced by 'maps'`
"golang.org/x/exp/slices" // want `Import statement 'golang.org/x/exp/slices' may be replaced by 'slices'`
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _(m, a map[string]string) {
maps.Clone(m) // want `golang.org/x/exp/maps.Clone\(\) can be replaced by maps.Clone\(\)`
maps.Keys(m) // want `golang.org/x/exp/maps\.Keys\(\) can be replaced by slices\.AppendSeq\(make\(\[\]T, 0, len\(data\)\), maps\.Keys\(data\)\)`
maps.Values(m) // want `golang.org/x/exp/maps\.Values\(\) can be replaced by slices\.AppendSeq\(make\(\[\]T, 0, len\(data\)\), maps\.Values\(data\)\)`
maps.Equal(m, a) // want `golang.org/x/exp/maps.Equal\(\) can be replaced by maps.Equal\(\)`
maps.EqualFunc(m, a, func(i, j string) bool { // want `golang.org/x/exp/maps.EqualFunc\(\) can be replaced by maps.EqualFunc\(\)`
return true
})
maps.Copy(m, a) // want `golang.org/x/exp/maps.Copy\(\) can be replaced by maps.Copy\(\)`
maps.DeleteFunc(m, func(_, _ string) bool { // want `golang.org/x/exp/maps.DeleteFunc\(\) can be replaced by maps.DeleteFunc\(\)`
return true
})
maps.Clear(m) // want `golang.org/x/exp/maps.Clear\(\) can be replaced by clear\(\)`
fmt.Println("Hello")
}
func _(a, b []string) {
slices.Equal(a, b)
slices.EqualFunc(a, b, func(_ string, _ string) bool {
return true
})
slices.Compare(a, b)
slices.CompareFunc(a, b, func(_ string, _ string) int {
return 0
})
slices.Index(a, "a")
slices.IndexFunc(a, func(_ string) bool {
return true
})
slices.Contains(a, "a")
slices.ContainsFunc(a, func(_ string) bool {
return true
})
slices.Insert(a, 0, "a", "b")
slices.Delete(a, 0, 1)
slices.DeleteFunc(a, func(_ string) bool {
return true
})
slices.Replace(a, 0, 1, "a")
slices.Clone(a)
slices.Compact(a)
slices.CompactFunc(a, func(_ string, _ string) bool {
return true
})
slices.Grow(a, 2)
slices.Clip(a)
slices.Reverse(a)
slices.Sort(a)
slices.SortFunc(a, func(_, _ string) int {
return 0
})
slices.SortStableFunc(a, func(_, _ string) int {
return 0
})
slices.IsSorted(a)
slices.IsSortedFunc(a, func(_, _ string) int {
return 0
})
slices.Min(a)
slices.MinFunc(a, func(_, _ string) int {
return 0
})
slices.Max(a)
slices.MaxFunc(a, func(_, _ string) int {
return 0
})
slices.BinarySearch(a, "a")
slices.BinarySearchFunc(a, b, func(_ string, _ []string) int {
return 0
})
}
================================================
FILE: pkg/golinters/exptostd/testdata/fix/in/exptostd.go
================================================
//golangcitest:args -Eexptostd
package testdata
import (
"fmt"
"golang.org/x/exp/maps" // want `Import statement 'golang.org/x/exp/maps' may be replaced by 'maps'`
"golang.org/x/exp/slices" // want `Import statement 'golang.org/x/exp/slices' may be replaced by 'slices'`
)
func _(m, a map[string]string) {
maps.Clone(m) // want `golang.org/x/exp/maps.Clone\(\) can be replaced by maps.Clone\(\)`
maps.Equal(m, a) // want `golang.org/x/exp/maps.Equal\(\) can be replaced by maps.Equal\(\)`
maps.EqualFunc(m, a, func(i, j string) bool { // want `golang.org/x/exp/maps.EqualFunc\(\) can be replaced by maps.EqualFunc\(\)`
return true
})
maps.Copy(m, a) // want `golang.org/x/exp/maps.Copy\(\) can be replaced by maps.Copy\(\)`
maps.DeleteFunc(m, func(_, _ string) bool { // want `golang.org/x/exp/maps.DeleteFunc\(\) can be replaced by maps.DeleteFunc\(\)`
return true
})
maps.Clear(m) // want `golang.org/x/exp/maps.Clear\(\) can be replaced by clear\(\)`
fmt.Println("Hello")
}
func _(a, b []string) {
slices.Equal(a, b)
slices.EqualFunc(a, b, func(_ string, _ string) bool {
return true
})
slices.Compare(a, b)
slices.CompareFunc(a, b, func(_ string, _ string) int {
return 0
})
slices.Index(a, "a")
slices.IndexFunc(a, func(_ string) bool {
return true
})
slices.Contains(a, "a")
slices.ContainsFunc(a, func(_ string) bool {
return true
})
slices.Insert(a, 0, "a", "b")
slices.Delete(a, 0, 1)
slices.DeleteFunc(a, func(_ string) bool {
return true
})
slices.Replace(a, 0, 1, "a")
slices.Clone(a)
slices.Compact(a)
slices.CompactFunc(a, func(_ string, _ string) bool {
return true
})
slices.Grow(a, 2)
slices.Clip(a)
slices.Reverse(a)
slices.Sort(a)
slices.SortFunc(a, func(_, _ string) int {
return 0
})
slices.SortStableFunc(a, func(_, _ string) int {
return 0
})
slices.IsSorted(a)
slices.IsSortedFunc(a, func(_, _ string) int {
return 0
})
slices.Min(a)
slices.MinFunc(a, func(_, _ string) int {
return 0
})
slices.Max(a)
slices.MaxFunc(a, func(_, _ string) int {
return 0
})
slices.BinarySearch(a, "a")
slices.BinarySearchFunc(a, b, func(_ string, _ []string) int {
return 0
})
}
================================================
FILE: pkg/golinters/exptostd/testdata/fix/out/exptostd.go
================================================
//golangcitest:args -Eexptostd
package testdata
import (
"fmt"
"maps" // want `Import statement 'golang.org/x/exp/maps' may be replaced by 'maps'`
"slices" // want `Import statement 'golang.org/x/exp/slices' may be replaced by 'slices'`
)
func _(m, a map[string]string) {
maps.Clone(m) // want `golang.org/x/exp/maps.Clone\(\) can be replaced by maps.Clone\(\)`
maps.Equal(m, a) // want `golang.org/x/exp/maps.Equal\(\) can be replaced by maps.Equal\(\)`
maps.EqualFunc(m, a, func(i, j string) bool { // want `golang.org/x/exp/maps.EqualFunc\(\) can be replaced by maps.EqualFunc\(\)`
return true
})
maps.Copy(m, a) // want `golang.org/x/exp/maps.Copy\(\) can be replaced by maps.Copy\(\)`
maps.DeleteFunc(m, func(_, _ string) bool { // want `golang.org/x/exp/maps.DeleteFunc\(\) can be replaced by maps.DeleteFunc\(\)`
return true
})
clear(m) // want `golang.org/x/exp/maps.Clear\(\) can be replaced by clear\(\)`
fmt.Println("Hello")
}
func _(a, b []string) {
slices.Equal(a, b)
slices.EqualFunc(a, b, func(_ string, _ string) bool {
return true
})
slices.Compare(a, b)
slices.CompareFunc(a, b, func(_ string, _ string) int {
return 0
})
slices.Index(a, "a")
slices.IndexFunc(a, func(_ string) bool {
return true
})
slices.Contains(a, "a")
slices.ContainsFunc(a, func(_ string) bool {
return true
})
slices.Insert(a, 0, "a", "b")
slices.Delete(a, 0, 1)
slices.DeleteFunc(a, func(_ string) bool {
return true
})
slices.Replace(a, 0, 1, "a")
slices.Clone(a)
slices.Compact(a)
slices.CompactFunc(a, func(_ string, _ string) bool {
return true
})
slices.Grow(a, 2)
slices.Clip(a)
slices.Reverse(a)
slices.Sort(a)
slices.SortFunc(a, func(_, _ string) int {
return 0
})
slices.SortStableFunc(a, func(_, _ string) int {
return 0
})
slices.IsSorted(a)
slices.IsSortedFunc(a, func(_, _ string) int {
return 0
})
slices.Min(a)
slices.MinFunc(a, func(_, _ string) int {
return 0
})
slices.Max(a)
slices.MaxFunc(a, func(_, _ string) int {
return 0
})
slices.BinarySearch(a, "a")
slices.BinarySearchFunc(a, b, func(_ string, _ []string) int {
return 0
})
}
================================================
FILE: pkg/golinters/exptostd/testdata/go.mod
================================================
module exptostd
go 1.25.0
require golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6
================================================
FILE: pkg/golinters/exptostd/testdata/go.sum
================================================
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
================================================
FILE: pkg/golinters/fatcontext/fatcontext.go
================================================
package fatcontext
import (
"go.augendre.info/fatcontext/pkg/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.FatcontextSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
analyzer.FlagCheckStructPointers: settings.CheckStructPointers,
}
}
return goanalysis.
NewLinterFromAnalyzer(analyzer.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/fatcontext/fatcontext_integration_test.go
================================================
package fatcontext
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/fatcontext/testdata/fatcontext.go
================================================
//golangcitest:args -Efatcontext
package testdata
import "context"
func example() {
ctx := context.Background()
for i := 0; i < 10; i++ {
ctx := context.WithValue(ctx, "key", i)
ctx = context.WithValue(ctx, "other", "val")
}
for i := 0; i < 10; i++ {
ctx = context.WithValue(ctx, "key", i) // want "nested context in loop"
ctx = context.WithValue(ctx, "other", "val")
}
for item := range []string{"one", "two", "three"} {
ctx = wrapContext(ctx) // want "nested context in loop"
ctx := context.WithValue(ctx, "key", item)
ctx = wrapContext(ctx)
}
for {
ctx = wrapContext(ctx) // want "nested context in loop"
break
}
}
func wrapContext(ctx context.Context) context.Context {
return context.WithoutCancel(ctx)
}
// storing contexts in a struct isn't recommended, but local copies of a non-pointer struct should act like local copies of a context.
func inStructs(ctx context.Context) {
for i := 0; i < 10; i++ {
c := struct{ Ctx context.Context }{ctx}
c.Ctx = context.WithValue(c.Ctx, "key", i)
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
for i := 0; i < 10; i++ {
c := []struct{ Ctx context.Context }{{ctx}}
c[0].Ctx = context.WithValue(c[0].Ctx, "key", i)
c[0].Ctx = context.WithValue(c[0].Ctx, "other", "val")
}
c := struct{ Ctx context.Context }{ctx}
for i := 0; i < 10; i++ {
c := c
c.Ctx = context.WithValue(c.Ctx, "key", i)
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
pc := &struct{ Ctx context.Context }{ctx}
for i := 0; i < 10; i++ {
c := pc
c.Ctx = context.WithValue(c.Ctx, "key", i) // want "nested context in loop"
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
r := []struct{ Ctx context.Context }{{ctx}}
for i := 0; i < 10; i++ {
r[0].Ctx = context.WithValue(r[0].Ctx, "key", i) // want "nested context in loop"
r[0].Ctx = context.WithValue(r[0].Ctx, "other", "val")
}
rp := []*struct{ Ctx context.Context }{{ctx}}
for i := 0; i < 10; i++ {
rp[0].Ctx = context.WithValue(rp[0].Ctx, "key", i) // want "nested context in loop"
rp[0].Ctx = context.WithValue(rp[0].Ctx, "other", "val")
}
}
================================================
FILE: pkg/golinters/fatcontext/testdata/fatcontext_cgo.go
================================================
//golangcitest:args -Efatcontext
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"context"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
ctx := context.Background()
for i := 0; i < 10; i++ {
ctx := context.WithValue(ctx, "key", i)
ctx = context.WithValue(ctx, "other", "val")
}
for i := 0; i < 10; i++ {
ctx = context.WithValue(ctx, "key", i) // want "nested context in loop"
ctx = context.WithValue(ctx, "other", "val")
}
for item := range []string{"one", "two", "three"} {
ctx = wrapContext(ctx) // want "nested context in loop"
ctx := context.WithValue(ctx, "key", item)
ctx = wrapContext(ctx)
}
for {
ctx = wrapContext(ctx) // want "nested context in loop"
break
}
}
func wrapContext(ctx context.Context) context.Context {
return context.WithoutCancel(ctx)
}
================================================
FILE: pkg/golinters/fatcontext/testdata/fatcontext_structpointer.go
================================================
//golangcitest:args -Efatcontext
//golangcitest:config_path testdata/fatcontext_structpointer.yml
package testdata
import (
"context"
)
type Container struct {
Ctx context.Context
}
func something() func(*Container) {
return func(r *Container) {
ctx := r.Ctx
ctx = context.WithValue(ctx, "key", "val")
r.Ctx = ctx // want "potential nested context in struct pointer"
}
}
func blah(r *Container) {
ctx := r.Ctx
ctx = context.WithValue(ctx, "key", "val")
r.Ctx = ctx // want "potential nested context in struct pointer"
}
================================================
FILE: pkg/golinters/fatcontext/testdata/fatcontext_structpointer.yml
================================================
version: "2"
linters:
settings:
fatcontext:
check-struct-pointers: true
================================================
FILE: pkg/golinters/fatcontext/testdata/fix/in/fatcontext.go
================================================
//golangcitest:args -Efatcontext
//golangcitest:expected_exitcode 0
package testdata
import "context"
func example() {
ctx := context.Background()
for i := 0; i < 10; i++ {
ctx := context.WithValue(ctx, "key", i)
ctx = context.WithValue(ctx, "other", "val")
}
for i := 0; i < 10; i++ {
ctx = context.WithValue(ctx, "key", i)
ctx = context.WithValue(ctx, "other", "val")
}
for item := range []string{"one", "two", "three"} {
ctx = wrapContext(ctx)
ctx := context.WithValue(ctx, "key", item)
ctx = wrapContext(ctx)
}
for {
ctx = wrapContext(ctx)
break
}
}
func wrapContext(ctx context.Context) context.Context {
return context.WithoutCancel(ctx)
}
// storing contexts in a struct isn't recommended, but local copies of a non-pointer struct should act like local copies of a context.
func inStructs(ctx context.Context) {
for i := 0; i < 10; i++ {
c := struct{ Ctx context.Context }{ctx}
c.Ctx = context.WithValue(c.Ctx, "key", i)
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
for i := 0; i < 10; i++ {
c := []struct{ Ctx context.Context }{{ctx}}
c[0].Ctx = context.WithValue(c[0].Ctx, "key", i)
c[0].Ctx = context.WithValue(c[0].Ctx, "other", "val")
}
c := struct{ Ctx context.Context }{ctx}
for i := 0; i < 10; i++ {
c := c
c.Ctx = context.WithValue(c.Ctx, "key", i)
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
pc := &struct{ Ctx context.Context }{ctx}
for i := 0; i < 10; i++ {
c := pc
c.Ctx = context.WithValue(c.Ctx, "key", i)
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
r := []struct{ Ctx context.Context }{{ctx}}
for i := 0; i < 10; i++ {
r[0].Ctx = context.WithValue(r[0].Ctx, "key", i)
r[0].Ctx = context.WithValue(r[0].Ctx, "other", "val")
}
rp := []*struct{ Ctx context.Context }{{ctx}}
for i := 0; i < 10; i++ {
rp[0].Ctx = context.WithValue(rp[0].Ctx, "key", i)
rp[0].Ctx = context.WithValue(rp[0].Ctx, "other", "val")
}
}
================================================
FILE: pkg/golinters/fatcontext/testdata/fix/out/fatcontext.go
================================================
//golangcitest:args -Efatcontext
//golangcitest:expected_exitcode 0
package testdata
import "context"
func example() {
ctx := context.Background()
for i := 0; i < 10; i++ {
ctx := context.WithValue(ctx, "key", i)
ctx = context.WithValue(ctx, "other", "val")
}
for i := 0; i < 10; i++ {
ctx := context.WithValue(ctx, "key", i)
ctx = context.WithValue(ctx, "other", "val")
}
for item := range []string{"one", "two", "three"} {
ctx := wrapContext(ctx)
ctx := context.WithValue(ctx, "key", item)
ctx = wrapContext(ctx)
}
for {
ctx := wrapContext(ctx)
break
}
}
func wrapContext(ctx context.Context) context.Context {
return context.WithoutCancel(ctx)
}
// storing contexts in a struct isn't recommended, but local copies of a non-pointer struct should act like local copies of a context.
func inStructs(ctx context.Context) {
for i := 0; i < 10; i++ {
c := struct{ Ctx context.Context }{ctx}
c.Ctx = context.WithValue(c.Ctx, "key", i)
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
for i := 0; i < 10; i++ {
c := []struct{ Ctx context.Context }{{ctx}}
c[0].Ctx = context.WithValue(c[0].Ctx, "key", i)
c[0].Ctx = context.WithValue(c[0].Ctx, "other", "val")
}
c := struct{ Ctx context.Context }{ctx}
for i := 0; i < 10; i++ {
c := c
c.Ctx = context.WithValue(c.Ctx, "key", i)
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
pc := &struct{ Ctx context.Context }{ctx}
for i := 0; i < 10; i++ {
c := pc
c.Ctx := context.WithValue(c.Ctx, "key", i)
c.Ctx = context.WithValue(c.Ctx, "other", "val")
}
r := []struct{ Ctx context.Context }{{ctx}}
for i := 0; i < 10; i++ {
r[0].Ctx := context.WithValue(r[0].Ctx, "key", i)
r[0].Ctx = context.WithValue(r[0].Ctx, "other", "val")
}
rp := []*struct{ Ctx context.Context }{{ctx}}
for i := 0; i < 10; i++ {
rp[0].Ctx := context.WithValue(rp[0].Ctx, "key", i)
rp[0].Ctx = context.WithValue(rp[0].Ctx, "other", "val")
}
}
================================================
FILE: pkg/golinters/forbidigo/forbidigo.go
================================================
package forbidigo
import (
"fmt"
"github.com/ashanbrown/forbidigo/v2/forbidigo"
"go.yaml.in/yaml/v3"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const linterName = "forbidigo"
func New(settings *config.ForbidigoSettings) *goanalysis.Linter {
// Without AnalyzeTypes, LoadModeSyntax is enough.
// But we cannot make this depend on the settings and have to mirror the mode chosen in GetAllSupportedLinterConfigs,
// therefore, we have to use LoadModeTypesInfo in all cases.
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: "Forbids identifiers",
Run: func(pass *analysis.Pass) (any, error) {
err := runForbidigo(pass, settings)
if err != nil {
return nil, err
}
return nil, nil
},
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func runForbidigo(pass *analysis.Pass, settings *config.ForbidigoSettings) error {
options := []forbidigo.Option{
forbidigo.OptionExcludeGodocExamples(settings.ExcludeGodocExamples),
// disable "//permit" directives so only "//nolint" directives matters within golangci-lint
forbidigo.OptionIgnorePermitDirectives(true),
forbidigo.OptionAnalyzeTypes(settings.AnalyzeTypes),
}
// Convert patterns back to strings because that is what NewLinter accepts.
var patterns []string
for _, pattern := range settings.Forbid {
buffer, err := yaml.Marshal(pattern)
if err != nil {
return err
}
patterns = append(patterns, string(buffer))
}
forbid, err := forbidigo.NewLinter(patterns, options...)
if err != nil {
return fmt.Errorf("failed to create linter %q: %w", linterName, err)
}
for _, file := range pass.Files {
runConfig := forbidigo.RunConfig{
Fset: pass.Fset,
DebugLog: logutils.Debug(logutils.DebugKeyForbidigo),
}
if settings.AnalyzeTypes {
runConfig.TypesInfo = pass.TypesInfo
}
hints, err := forbid.RunWithConfig(runConfig, file)
if err != nil {
return fmt.Errorf("forbidigo linter failed on file %q: %w", file.Name.String(), err)
}
for _, hint := range hints {
pass.Report(analysis.Diagnostic{
Pos: hint.Pos(),
Message: hint.Details(),
})
}
}
return nil
}
================================================
FILE: pkg/golinters/forbidigo/forbidigo_integration_test.go
================================================
package forbidigo
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/forbidigo/testdata/forbidigo.yml
================================================
version: "2"
linters:
settings:
forbidigo:
forbid:
- pattern: fmt\.Print.*
- pattern: time.Sleep(# no sleeping!)?
================================================
FILE: pkg/golinters/forbidigo/testdata/forbidigo_cgo.go
================================================
//golangcitest:args -Eforbidigo
//golangcitest:config_path testdata/forbidigo.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
fmt2 "fmt"
"time"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func Forbidigo() {
fmt.Printf("too noisy!!!") // want "use of `fmt\\.Printf` forbidden by pattern `fmt\\\\.Print\\.\\*`"
fmt2.Printf("too noisy!!!") // Not detected because analyze-types is false by default for backward compatibility.
time.Sleep(time.Nanosecond) // want "no sleeping!"
}
================================================
FILE: pkg/golinters/forbidigo/testdata/forbidigo_example.go
================================================
//golangcitest:args -Eforbidigo
//golangcitest:config_path testdata/forbidigo.yml
package testdata
import (
"fmt"
fmt2 "fmt"
"time"
)
func Forbidigo() {
fmt.Printf("too noisy!!!") // want "use of `fmt\\.Printf` forbidden by pattern `fmt\\\\.Print\\.\\*`"
fmt2.Printf("too noisy!!!") // Not detected because analyze-types is false by default for backward compatibility.
time.Sleep(time.Nanosecond) // want "no sleeping!"
}
================================================
FILE: pkg/golinters/forbidigo/testdata/forbidigo_example_test.go
================================================
//golangcitest:args -Eforbidigo
//golangcitest:config_path testdata/forbidigo.yml
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
func ExampleForbidigo() {
fmt.Printf("too noisy!!!") // godoc examples are ignored (in *_test.go files only)
}
================================================
FILE: pkg/golinters/forbidigo/testdata/forbidigo_include_godoc_examples.yml
================================================
version: "2"
linters:
settings:
forbidigo:
exclude-godoc-examples: false
================================================
FILE: pkg/golinters/forbidigo/testdata/forbidigo_include_godoc_examples_test.go
================================================
//golangcitest:args -Eforbidigo
//golangcitest:config_path testdata/forbidigo_include_godoc_examples.yml
package testdata
import "fmt"
func ExampleForbidigoNoGodoc() {
fmt.Printf("too noisy!!!") // want "use of `fmt.Printf` forbidden by pattern.*"
}
================================================
FILE: pkg/golinters/forbidigo/testdata/forbidigo_struct.yml
================================================
version: "2"
linters:
settings:
forbidigo:
analyze-types: true
forbid:
- pattern: fmt\.Print.*
pkg: ^fmt$
- pattern: time.Sleep
msg: no sleeping!
================================================
FILE: pkg/golinters/forbidigo/testdata/forbidigo_struct_config.go
================================================
//golangcitest:args -Eforbidigo
//golangcitest:config_path testdata/forbidigo_struct.yml
package testdata
import (
fmt2 "fmt"
"time"
)
func Forbidigo() {
fmt2.Printf("too noisy!!!") // want "use of `fmt2\\.Printf` forbidden by pattern `fmt\\\\.Print\\.\\*`"
time.Sleep(time.Nanosecond) // want "no sleeping!"
}
================================================
FILE: pkg/golinters/forcetypeassert/forcetypeassert.go
================================================
package forcetypeassert
import (
"github.com/gostaticanalysis/forcetypeassert"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(forcetypeassert.Analyzer).
WithDesc("Find forced type assertions").
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/forcetypeassert/forcetypeassert_integration_test.go
================================================
package forcetypeassert
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/forcetypeassert/testdata/forcetypeassert.go
================================================
//golangcitest:args -Eforcetypeassert
package testdata
import "fmt"
func forcetypeassertInvalid() {
var a interface{}
_ = a.(int) // want "type assertion must be checked"
var b interface{}
bi := b.(int) // want "type assertion must be checked"
fmt.Println(bi)
}
func forcetypeassertValid() {
var a interface{}
if ai, ok := a.(int); ok {
fmt.Println(ai)
}
}
================================================
FILE: pkg/golinters/forcetypeassert/testdata/forcetypeassert_cgo.go
================================================
//golangcitest:args -Eforcetypeassert
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
var a interface{}
_ = a.(int) // want "type assertion must be checked"
var b interface{}
bi := b.(int) // want "type assertion must be checked"
fmt.Println(bi)
}
func _() {
var a interface{}
if ai, ok := a.(int); ok {
fmt.Println(ai)
}
}
================================================
FILE: pkg/golinters/funcorder/funcorder.go
================================================
package funcorder
import (
"github.com/manuelarte/funcorder/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.FuncOrderSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
analyzer.ConstructorCheckName: settings.Constructor,
analyzer.StructMethodCheckName: settings.StructMethod,
analyzer.AlphabeticalCheckName: settings.Alphabetical,
}
}
return goanalysis.
NewLinterFromAnalyzer(analyzer.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/funcorder/funcorder_integration_test.go
================================================
package funcorder
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/funcorder/testdata/funcorder.go
================================================
//golangcitest:args -Efuncorder
package testdata
import "time"
type MyStruct struct {
Name string
}
func (m MyStruct) lenName() int { // want `unexported method "lenName" for struct "MyStruct" should be placed after the exported method "SetName"`
return len(m.Name)
}
func (m MyStruct) GetName() string {
return m.Name
}
func (m *MyStruct) SetName(name string) {
m.Name = name
}
type MyStruct2 struct {
Name string
}
func (m MyStruct2) GetName() string {
return m.Name
}
func (m *MyStruct2) SetName(name string) {
m.Name = name
}
func NewMyStruct2() *MyStruct2 { // want `constructor "NewMyStruct2" for struct "MyStruct2" should be placed before struct method "GetName"`
return &MyStruct2{Name: "John"}
}
func NewTime() time.Time {
return time.Now()
}
================================================
FILE: pkg/golinters/funcorder/testdata/funcorder_disable_constructor.go
================================================
//golangcitest:args -Efuncorder
//golangcitest:config_path testdata/funcorder_disable_constructor.yml
package testdata
import "time"
type MyStruct struct {
Name string
}
func (m MyStruct) lenName() int { // want `unexported method "lenName" for struct "MyStruct" should be placed after the exported method "SetName"`
return len(m.Name)
}
func (m MyStruct) GetName() string {
return m.Name
}
func (m *MyStruct) SetName(name string) {
m.Name = name
}
type MyStruct2 struct {
Name string
}
func (m MyStruct2) GetName() string {
return m.Name
}
func (m *MyStruct2) SetName(name string) {
m.Name = name
}
func NewMyStruct2() *MyStruct2 {
return &MyStruct2{Name: "John"}
}
func NewTime() time.Time {
return time.Now()
}
================================================
FILE: pkg/golinters/funcorder/testdata/funcorder_disable_constructor.yml
================================================
version: "2"
linters:
settings:
funcorder:
constructor: false
================================================
FILE: pkg/golinters/funcorder/testdata/funcorder_struct_method.go
================================================
//golangcitest:args -Efuncorder
//golangcitest:config_path testdata/funcorder_struct_method.yml
package testdata
import "time"
type MyStruct struct {
Name string
}
func (m MyStruct) lenName() int {
return len(m.Name)
}
func (m MyStruct) GetName() string {
return m.Name
}
func (m *MyStruct) SetName(name string) {
m.Name = name
}
type MyStruct2 struct {
Name string
}
func (m MyStruct2) GetName() string {
return m.Name
}
func (m *MyStruct2) SetName(name string) {
m.Name = name
}
func NewMyStruct2() *MyStruct2 { // want `constructor "NewMyStruct2" for struct "MyStruct2" should be placed before struct method "GetName"`
return &MyStruct2{Name: "John"}
}
func NewTime() time.Time {
return time.Now()
}
================================================
FILE: pkg/golinters/funcorder/testdata/funcorder_struct_method.yml
================================================
version: "2"
linters:
settings:
funcorder:
struct-method: false
================================================
FILE: pkg/golinters/funlen/funlen.go
================================================
package funlen
import (
"github.com/ultraware/funlen"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
type Config struct {
lineLimit int
stmtLimit int
ignoreComments bool
}
func New(settings *config.FunlenSettings) *goanalysis.Linter {
cfg := Config{}
if settings != nil {
cfg.lineLimit = settings.Lines
cfg.stmtLimit = settings.Statements
cfg.ignoreComments = settings.IgnoreComments
}
return goanalysis.
NewLinterFromAnalyzer(funlen.NewAnalyzer(cfg.lineLimit, cfg.stmtLimit, cfg.ignoreComments)).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/funlen/funlen_integration_test.go
================================================
package funlen
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/funlen/testdata/funlen.go
================================================
//golangcitest:args -Efunlen
package testdata
func TooManyLines() { // want `Function 'TooManyLines' is too long \(70 > 60\)`
t := struct {
A0 string
A1 string
A2 string
A3 string
A4 string
A5 string
A6 string
A7 string
A8 string
A9 string
A10 string
A11 string
A12 string
A13 string
A14 string
A15 string
A16 string
A17 string
A18 string
A19 string
A20 string
A21 string
A22 string
A23 string
A24 string
A25 string
A26 string
A27 string
A28 string
A29 string
A30 string
A31 string
A32 string
}{
A0: "a",
A1: "a",
A2: "a",
A3: "a",
A4: "a",
A5: "a",
A6: "a",
A7: "a",
A8: "a",
A9: "a",
A10: "a",
A11: "a",
A12: "a",
A13: "a",
A14: "a",
A15: "a",
A16: "a",
A17: "a",
A18: "a",
A19: "a",
A20: "a",
A21: "a",
A22: "a",
A23: "a",
A24: "a",
A25: "a",
A26: "a",
A27: "a",
A28: "a",
A29: "a",
A30: "a",
A31: "a",
A32: "a",
}
_ = t
}
func TooManyStatements() { // want `Function 'TooManyStatements' has too many statements \(46 > 40\)`
a0 := 1
a1 := 1
a2 := 1
a3 := 1
a4 := 1
a5 := 1
a6 := 1
a7 := 1
a8 := 1
a9 := 1
a10 := 1
a11 := 1
a12 := 1
a13 := 1
a14 := 1
a15 := 1
a16 := 1
a17 := 1
a18 := 1
a19 := 1
a20 := 1
a21 := 1
a22 := 1
_ = a0
_ = a1
_ = a2
_ = a3
_ = a4
_ = a5
_ = a6
_ = a7
_ = a8
_ = a9
_ = a10
_ = a11
_ = a12
_ = a13
_ = a14
_ = a15
_ = a16
_ = a17
_ = a18
_ = a19
_ = a20
_ = a21
_ = a22
}
func withComments() {
// Comment 1
// Comment 2
// Comment 3
// Comment 4
// Comment 5
// Comment 6
// Comment 7
// Comment 8
// Comment 9
// Comment 10
// Comment 11
// Comment 12
// Comment 13
// Comment 14
// Comment 15
// Comment 16
// Comment 17
// Comment 18
// Comment 19
// Comment 20
// Comment 21
// Comment 22
// Comment 23
// Comment 24
// Comment 25
// Comment 26
// Comment 27
// Comment 28
// Comment 29
// Comment 30
// Comment 31
// Comment 32
// Comment 33
// Comment 34
// Comment 35
// Comment 36
// Comment 37
// Comment 38
// Comment 39
// Comment 40
// Comment 41
// Comment 42
// Comment 43
// Comment 44
// Comment 45
// Comment 46
// Comment 47
// Comment 48
// Comment 49
// Comment 50
// Comment 51
// Comment 52
// Comment 53
// Comment 54
// Comment 55
// Comment 56
// Comment 57
// Comment 58
// Comment 59
// Comment 60
print("Hello, world!")
}
================================================
FILE: pkg/golinters/funlen/testdata/funlen_cgo.go
================================================
//golangcitest:args -Efunlen
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func TooManyLines() { // want `Function 'TooManyLines' is too long \(70 > 60\)`
t := struct {
A0 string
A1 string
A2 string
A3 string
A4 string
A5 string
A6 string
A7 string
A8 string
A9 string
A10 string
A11 string
A12 string
A13 string
A14 string
A15 string
A16 string
A17 string
A18 string
A19 string
A20 string
A21 string
A22 string
A23 string
A24 string
A25 string
A26 string
A27 string
A28 string
A29 string
A30 string
A31 string
A32 string
}{
A0: "a",
A1: "a",
A2: "a",
A3: "a",
A4: "a",
A5: "a",
A6: "a",
A7: "a",
A8: "a",
A9: "a",
A10: "a",
A11: "a",
A12: "a",
A13: "a",
A14: "a",
A15: "a",
A16: "a",
A17: "a",
A18: "a",
A19: "a",
A20: "a",
A21: "a",
A22: "a",
A23: "a",
A24: "a",
A25: "a",
A26: "a",
A27: "a",
A28: "a",
A29: "a",
A30: "a",
A31: "a",
A32: "a",
}
_ = t
}
func TooManyStatements() { // want `Function 'TooManyStatements' has too many statements \(46 > 40\)`
a0 := 1
a1 := 1
a2 := 1
a3 := 1
a4 := 1
a5 := 1
a6 := 1
a7 := 1
a8 := 1
a9 := 1
a10 := 1
a11 := 1
a12 := 1
a13 := 1
a14 := 1
a15 := 1
a16 := 1
a17 := 1
a18 := 1
a19 := 1
a20 := 1
a21 := 1
a22 := 1
_ = a0
_ = a1
_ = a2
_ = a3
_ = a4
_ = a5
_ = a6
_ = a7
_ = a8
_ = a9
_ = a10
_ = a11
_ = a12
_ = a13
_ = a14
_ = a15
_ = a16
_ = a17
_ = a18
_ = a19
_ = a20
_ = a21
_ = a22
}
func withComments() {
// Comment 1
// Comment 2
// Comment 3
// Comment 4
// Comment 5
// Comment 6
// Comment 7
// Comment 8
// Comment 9
// Comment 10
// Comment 11
// Comment 12
// Comment 13
// Comment 14
// Comment 15
// Comment 16
// Comment 17
// Comment 18
// Comment 19
// Comment 20
// Comment 21
// Comment 22
// Comment 23
// Comment 24
// Comment 25
// Comment 26
// Comment 27
// Comment 28
// Comment 29
// Comment 30
// Comment 31
// Comment 32
// Comment 33
// Comment 34
// Comment 35
// Comment 36
// Comment 37
// Comment 38
// Comment 39
// Comment 40
// Comment 41
// Comment 42
// Comment 43
// Comment 44
// Comment 45
// Comment 46
// Comment 47
// Comment 48
// Comment 49
// Comment 50
// Comment 51
// Comment 52
// Comment 53
// Comment 54
// Comment 55
// Comment 56
// Comment 57
// Comment 58
// Comment 59
// Comment 60
print("Hello, world!")
}
================================================
FILE: pkg/golinters/funlen/testdata/funlen_custom.go
================================================
//golangcitest:args -Efunlen
//golangcitest:config_path testdata/funlen_custom.yml
package testdata
func TooManyLines() { // want `Function 'TooManyLines' is too long \(22 > 20\)`
t := struct {
A string
B string
C string
D string
E string
F string
G string
H string
I string
}{
`a`,
`b`,
`c`,
`d`,
`e`,
`f`,
`g`,
`h`,
`i`,
}
_ = t
}
func TooManyStatements() { // want `Function 'TooManyStatements' has too many statements \(11 > 10\)`
a := 1
b := a
c := b
d := c
e := d
f := e
g := f
h := g
i := h
j := i
_ = j
}
================================================
FILE: pkg/golinters/funlen/testdata/funlen_custom.yml
================================================
version: "2"
linters:
settings:
funlen:
lines: 20
statements: 10
================================================
FILE: pkg/golinters/funlen/testdata/funlen_ignore_comments.go
================================================
//golangcitest:args -Efunlen
//golangcitest:config_path testdata/funlen_ignore_comments.yml
package testdata
// want +1 "Function 'withComments' is too long"
func withComments() {
// Comment 1
// Comment 2
// Comment 3
// Comment 4
// Comment 5
// Comment 6
// Comment 7
// Comment 8
// Comment 9
// Comment 10
// Comment 11
// Comment 12
// Comment 13
// Comment 14
// Comment 15
// Comment 16
// Comment 17
// Comment 18
// Comment 19
// Comment 20
// Comment 21
// Comment 22
// Comment 23
// Comment 24
// Comment 25
// Comment 26
// Comment 27
// Comment 28
// Comment 29
// Comment 30
// Comment 31
// Comment 32
// Comment 33
// Comment 34
// Comment 35
// Comment 36
// Comment 37
// Comment 38
// Comment 39
// Comment 40
// Comment 41
// Comment 42
// Comment 43
// Comment 44
// Comment 45
// Comment 46
// Comment 47
// Comment 48
// Comment 49
// Comment 50
// Comment 51
// Comment 52
// Comment 53
// Comment 54
// Comment 55
// Comment 56
// Comment 57
// Comment 58
// Comment 59
// Comment 60
print("Hello, world!")
}
================================================
FILE: pkg/golinters/funlen/testdata/funlen_ignore_comments.yml
================================================
version: "2"
linters:
settings:
funlen:
ignore-comments: false
================================================
FILE: pkg/golinters/gci/gci.go
================================================
package gci
import (
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
gcibase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "gci"
func New(settings *config.GciSettings) *goanalysis.Linter {
formatter, err := gcibase.New(settings)
if err != nil {
internal.LinterLogger.Fatalf("%s: create analyzer: %v", linterName, err)
}
return goanalysis.
NewLinterFromAnalyzer(
goformatters.NewAnalyzer(
internal.LinterLogger.Child(linterName),
"Check if code and import statements are formatted, with additional rules.",
formatter,
),
).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/gci/gci_integration_test.go
================================================
package gci
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/gci/testdata/fix/in/gci.go
================================================
//golangcitest:config_path testdata/gci.yml
//golangcitest:expected_exitcode 0
package gci
import (
"github.com/golangci/golangci-lint/v2/pkg/config"
"golang.org/x/tools/go/analysis"
"fmt"
gcicfg "github.com/daixiang0/gci/pkg/config"
)
func GoimportsLocalTest() {
fmt.Print("x")
_ = config.Config{}
_ = analysis.Analyzer{}
_ = gcicfg.BoolConfig{}
}
================================================
FILE: pkg/golinters/gci/testdata/fix/out/gci.go
================================================
//golangcitest:config_path testdata/gci.yml
//golangcitest:expected_exitcode 0
package gci
import (
"fmt"
gcicfg "github.com/daixiang0/gci/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/config"
"golang.org/x/tools/go/analysis"
)
func GoimportsLocalTest() {
fmt.Print("x")
_ = config.Config{}
_ = analysis.Analyzer{}
_ = gcicfg.BoolConfig{}
}
================================================
FILE: pkg/golinters/gci/testdata/gci.go
================================================
//golangcitest:config_path testdata/gci.yml
package testdata
import (
"golang.org/x/tools/go/analysis" // want "File is not properly formatted"
"github.com/golangci/golangci-lint/v2/pkg/config"
"fmt"
"errors"
gcicfg "github.com/daixiang0/gci/pkg/config"
)
func GoimportsLocalTest() {
fmt.Print(errors.New("x"))
_ = config.Config{}
_ = analysis.Analyzer{}
_ = gcicfg.BoolConfig{}
}
================================================
FILE: pkg/golinters/gci/testdata/gci.yml
================================================
version: "2"
formatters:
enable:
- gci
settings:
gci:
sections:
- standard
- prefix(github.com/golangci/golangci-lint,github.com/daixiang0/gci)
- default
custom-order: true
================================================
FILE: pkg/golinters/gci/testdata/gci_cgo.go
================================================
//golangcitest:config_path testdata/gci.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"golang.org/x/tools/go/analysis" // want "File is not properly formatted"
"github.com/golangci/golangci-lint/v2/pkg/config"
"fmt"
"errors"
gcicfg "github.com/daixiang0/gci/pkg/config"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func GoimportsLocalTest() {
fmt.Print(errors.New("x"))
_ = config.Config{}
_ = analysis.Analyzer{}
_ = gcicfg.BoolConfig{}
}
================================================
FILE: pkg/golinters/gci/testdata/gci_go124.go
================================================
//go:build go1.24
//golangcitest:config_path testdata/gci_go124.yml
//golangcitest:expected_exitcode 0
package testdata
import (
"crypto/sha3"
"errors"
"fmt"
)
func _() {
fmt.Print(errors.New("x"))
sha3.New224()
}
================================================
FILE: pkg/golinters/gci/testdata/gci_go124.yml
================================================
version: "2"
formatters:
enable:
- gci
================================================
FILE: pkg/golinters/ginkgolinter/ginkgolinter.go
================================================
package ginkgolinter
import (
"github.com/nunnatsa/ginkgolinter"
glconfig "github.com/nunnatsa/ginkgolinter/config"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.GinkgoLinterSettings) *goanalysis.Linter {
cfg := &glconfig.Config{}
if settings != nil {
cfg = &glconfig.Config{
SuppressLen: settings.SuppressLenAssertion,
SuppressNil: settings.SuppressNilAssertion,
SuppressErr: settings.SuppressErrAssertion,
SuppressCompare: settings.SuppressCompareAssertion,
SuppressAsync: settings.SuppressAsyncAssertion,
ForbidFocus: settings.ForbidFocusContainer,
SuppressTypeCompare: settings.SuppressTypeCompareWarning,
AllowHaveLen0: settings.AllowHaveLenZero,
ForceExpectTo: settings.ForceExpectTo,
ValidateAsyncIntervals: settings.ValidateAsyncIntervals,
ForbidSpecPollution: settings.ForbidSpecPollution,
ForceSucceedForFuncs: settings.ForceSucceedForFuncs,
ForceAssertionDescription: settings.ForceAssertionDescription,
ForeToNot: settings.ForeToNot,
}
}
return goanalysis.
NewLinterFromAnalyzer(ginkgolinter.NewAnalyzerWithConfig(cfg)).
WithDesc("enforces standards of using ginkgo and gomega").
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/ginkgolinter/ginkgolinter_integration_test.go
================================================
package ginkgolinter
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter.go
================================================
//golangcitest:args -Eginkgolinter
package ginkgolinter
import (
"errors"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func LenUsecase() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(HaveLen\\(2\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0)) // // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.To\\(BeEmpty\\(\\)\\)"
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).Should(Equal(1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(HaveLen\\(1\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
}
func NilUsecase() {
y := 5
x := &y
Expect(x == nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(nil == x).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x != nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeTrue()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeFalse()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
}
func BooleanUsecase() {
x := true
Expect(x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeTrue\\(\\)\\)"
x = false
Expect(x).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeFalse\\(\\)\\)"
}
func ErrorUsecase() {
err := errors.New("fake error")
funcReturnsErr := func() error { return err }
Expect(err).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(Equal(true)) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(BeFalse()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(err != nil).To(BeTrue()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(funcReturnsErr()).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(funcReturnsErr\\(\\)\\)\\.To\\(Succeed\\(\\)\\)"
}
func HaveLen0Usecase() {
x := make([]string, 0)
Expect(x).To(HaveLen(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(x\\)\\.To\\(BeEmpty\\(\\)\\)"
}
func WrongComparisonUsecase() {
x := 8
Expect(x == 8).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(Equal\\(8\\)\\)"
Expect(x < 9).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(BeNumerically\\(\"<\", 9\\)\\)"
Expect(x < 7).To(Equal(false)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNumerically\\(\"<\", 7\\)\\)"
p1, p2 := &x, &x
Expect(p1 == p2).To(Equal(true)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(p1\\).To\\(BeIdenticalTo\\(p2\\)\\)"
}
func slowInt() int {
time.Sleep(time.Second)
return 42
}
func WrongEventuallyWithFunction() {
Eventually(slowInt).Should(Equal(42)) // valid
Eventually(slowInt()).Should(Equal(42)) // want "ginkgo-linter: use a function call in Eventually. This actually checks nothing, because Eventually receives the function returned value, instead of function itself, and this value is never changed. Consider using .Eventually\\(slowInt\\)\\.Should\\(Equal\\(42\\)\\)"
}
var _ = FDescribe("Should warn for focused containers", func() {
FContext("should not allow FContext", func() {
FWhen("should not allow FWhen", func() {
FIt("should not allow FIt", func() {})
})
})
})
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_allow_havelen0.yml
================================================
version: "2"
linters:
settings:
ginkgolinter:
allow-havelen-zero: true
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_cgo.go
================================================
//golangcitest:args -Eginkgolinter
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
. "github.com/onsi/gomega"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func LenUsecase() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(HaveLen\\(2\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0)) // // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.To\\(BeEmpty\\(\\)\\)"
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).Should(Equal(1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(HaveLen\\(1\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
}
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_default.yml
================================================
version: "2"
linters:
settings:
ginkgolinter: {}
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_havelen0.go
================================================
//golangcitest:config_path testdata/ginkgolinter_allow_havelen0.yml
//golangcitest:args -Eginkgolinter
package ginkgolinter
import (
"errors"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func LenUsecase_havelen0() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using `Expect\\(fakeVarUnderTest\\).Should\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(HaveLen\\(2\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0)) // // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.To\\(BeEmpty\\(\\)\\)"
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).Should(Equal(1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(HaveLen\\(1\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
}
func NilUsecase_havelen0() {
y := 5
x := &y
Expect(x == nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(nil == x).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x != nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeTrue()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeFalse()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
}
func BooleanUsecase_havelen0() {
x := true
Expect(x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeTrue\\(\\)\\)"
x = false
Expect(x).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeFalse\\(\\)\\)"
}
func ErrorUsecase_havelen0() {
err := errors.New("fake error")
funcReturnsErr := func() error { return err }
Expect(err).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(Equal(true)) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(BeFalse()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(err != nil).To(BeTrue()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(funcReturnsErr()).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(funcReturnsErr\\(\\)\\)\\.To\\(Succeed\\(\\)\\)"
}
func HaveLen0Usecase_havelen0() {
x := make([]string, 0)
Expect(x).To(HaveLen(0))
}
func WrongComparisonUsecase_havelen0() {
x := 8
Expect(x == 8).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(Equal\\(8\\)\\)"
Expect(x < 9).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(BeNumerically\\(\"<\", 9\\)\\)"
Expect(x < 7).To(Equal(false)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNumerically\\(\"<\", 7\\)\\)"
p1, p2 := &x, &x
Expect(p1 == p2).To(Equal(true)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(p1\\).To\\(BeIdenticalTo\\(p2\\)\\)"
}
func slowInt_havelen0() int {
time.Sleep(time.Second)
return 42
}
func WrongEventuallyWithFunction_havelen0() {
Eventually(slowInt_havelen0).Should(Equal(42)) // valid
Eventually(slowInt_havelen0()).Should(Equal(42)) // want "ginkgo-linter: use a function call in Eventually. This actually checks nothing, because Eventually receives the function returned value, instead of function itself, and this value is never changed. Consider using .Eventually\\(slowInt_havelen0\\)\\.Should\\(Equal\\(42\\)\\)"
}
var _ = FDescribe("Should warn for focused containers", func() {
FContext("should not allow FContext", func() {
FWhen("should not allow FWhen", func() {
FIt("should not allow FIt", func() {})
})
})
})
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_async.go
================================================
//golangcitest:config_path testdata/ginkgolinter_suppress_async.yml
//golangcitest:args -Eginkgolinter
package ginkgolinter
import (
"errors"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func LenUsecase_async() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(BeEmpty\\(\\)\\). instead"
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(HaveLen\\(2\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0)) // // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.To\\(BeEmpty\\(\\)\\)"
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).Should(Equal(1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(HaveLen\\(1\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
}
func NilUsecase_async() {
y := 5
x := &y
Expect(x == nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(nil == x).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x != nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeTrue()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeFalse()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
}
func BooleanUsecase_async() {
x := true
Expect(x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeTrue\\(\\)\\)"
x = false
Expect(x).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeFalse\\(\\)\\)"
}
func ErrorUsecase_async() {
err := errors.New("fake error")
funcReturnsErr := func() error { return err }
Expect(err).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(Equal(true)) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(BeFalse()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(err != nil).To(BeTrue()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(funcReturnsErr()).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(funcReturnsErr\\(\\)\\)\\.To\\(Succeed\\(\\)\\)"
}
func HaveLen0Usecase_async() {
x := make([]string, 0)
Expect(x).To(HaveLen(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(x\\)\\.To\\(BeEmpty\\(\\)\\)"
}
func WrongComparisonUsecase_async() {
x := 8
Expect(x == 8).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(Equal\\(8\\)\\)"
Expect(x < 9).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(BeNumerically\\(\"<\", 9\\)\\)"
Expect(x < 7).To(Equal(false)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNumerically\\(\"<\", 7\\)\\)"
p1, p2 := &x, &x
Expect(p1 == p2).To(Equal(true)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(p1\\).To\\(BeIdenticalTo\\(p2\\)\\)"
}
func slowInt_async() int {
time.Sleep(time.Second)
return 42
}
// WrongEventuallyWithFunction_async Should trigger no warning
func WrongEventuallyWithFunction_async() {
Eventually(slowInt_async).Should(Equal(42)) // valid
Eventually(slowInt_async()).Should(Equal(42)) // suppressed
}
var _ = FDescribe("Should warn for focused containers", func() {
FContext("should not allow FContext", func() {
FWhen("should not allow FWhen", func() {
FIt("should not allow FIt", func() {})
})
})
})
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_async.yml
================================================
version: "2"
linters:
settings:
ginkgolinter:
suppress-async-assertion: true
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_compare.go
================================================
//golangcitest:config_path testdata/ginkgolinter_suppress_compare.yml
//golangcitest:args -Eginkgolinter
package ginkgolinter
import (
"errors"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func LenUsecase_compare() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(HaveLen\\(2\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0)) // // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.To\\(BeEmpty\\(\\)\\)"
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).Should(Equal(1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(HaveLen\\(1\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
}
func NilUsecase_compare() {
y := 5
x := &y
Expect(x == nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(nil == x).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x != nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeTrue()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeFalse()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
}
func BooleanUsecase_compare() {
x := true
Expect(x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeTrue\\(\\)\\)"
x = false
Expect(x).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeFalse\\(\\)\\)"
}
func ErrorUsecase_compare() {
err := errors.New("fake error")
funcReturnsErr := func() error { return err }
Expect(err).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(Equal(true)) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(BeFalse()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(err != nil).To(BeTrue()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(funcReturnsErr()).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(funcReturnsErr\\(\\)\\)\\.To\\(Succeed\\(\\)\\)"
}
func HaveLen0Usecase_compare() {
x := make([]string, 0)
Expect(x).To(HaveLen(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(x\\)\\.To\\(BeEmpty\\(\\)\\)"
}
// WrongComparisonUsecase_compare should not trigger any warning
func WrongComparisonUsecase_compare() {
x := 8
Expect(x == 8).To(BeTrue())
Expect(x < 9).To(BeTrue())
Expect(x < 7).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using `Expect\\(x < 7\\)\\.To\\(BeFalse\\(\\)\\)`"
p1, p2 := &x, &x
Expect(p1 == p2).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using `Expect\\(p1 == p2\\)\\.To\\(BeTrue\\(\\)\\)`"
}
func slowInt_compare() int {
time.Sleep(time.Second)
return 42
}
func WrongEventuallyWithFunction_compare() {
Eventually(slowInt_compare).Should(Equal(42)) // valid
Eventually(slowInt_compare()).Should(Equal(42)) // want "ginkgo-linter: use a function call in Eventually. This actually checks nothing, because Eventually receives the function returned value, instead of function itself, and this value is never changed. Consider using .Eventually\\(slowInt_compare\\)\\.Should\\(Equal\\(42\\)\\)"
}
var _ = FDescribe("Should warn for focused containers", func() {
FContext("should not allow FContext", func() {
FWhen("should not allow FWhen", func() {
FIt("should not allow FIt", func() {})
})
})
})
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_compare.yml
================================================
version: "2"
linters:
settings:
ginkgolinter:
suppress-compare-assertion: true
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_err.go
================================================
//golangcitest:config_path testdata/ginkgolinter_suppress_err.yml
//golangcitest:args -Eginkgolinter
package ginkgolinter
import (
"errors"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func LenUsecase_err() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(HaveLen\\(2\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0)) // // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.To\\(BeEmpty\\(\\)\\)"
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).Should(Equal(1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(HaveLen\\(1\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
}
func NilUsecase_err() {
y := 5
x := &y
Expect(x == nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(nil == x).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x != nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeTrue()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeFalse()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
}
func BooleanUsecase_err() {
x := true
Expect(x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeTrue\\(\\)\\)"
x = false
Expect(x).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeFalse\\(\\)\\)"
}
// ErrorUsecase_err should not trigger any warning
func ErrorUsecase_err() {
err := errors.New("fake error")
funcReturnsErr := func() error { return err }
Expect(err).To(BeNil())
Expect(err == nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using `Expect\\(err\\).To\\(BeNil\\(\\)\\)`"
Expect(err == nil).To(BeFalse()) // want "ginkgo-linter: wrong nil assertion. Consider using `Expect\\(err\\).ToNot\\(BeNil\\(\\)\\)`"
Expect(err != nil).To(BeTrue()) // want "ginkgo-linter: wrong nil assertion. Consider using `Expect\\(err\\).ToNot\\(BeNil\\(\\)\\)`"
Expect(funcReturnsErr()).To(BeNil())
}
func HaveLen0Usecase_err() {
x := make([]string, 0)
Expect(x).To(HaveLen(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(x\\)\\.To\\(BeEmpty\\(\\)\\)"
}
func WrongComparisonUsecase_err() {
x := 8
Expect(x == 8).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(Equal\\(8\\)\\)"
Expect(x < 9).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(BeNumerically\\(\"<\", 9\\)\\)"
Expect(x < 7).To(Equal(false)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNumerically\\(\"<\", 7\\)\\)"
p1, p2 := &x, &x
Expect(p1 == p2).To(Equal(true)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(p1\\).To\\(BeIdenticalTo\\(p2\\)\\)"
}
func slowInt_err() int {
time.Sleep(time.Second)
return 42
}
func WrongEventuallyWithFunction_err() {
Eventually(slowInt_err).Should(Equal(42)) // valid
Eventually(slowInt_err()).Should(Equal(42)) // want "ginkgo-linter: use a function call in Eventually. This actually checks nothing, because Eventually receives the function returned value, instead of function itself, and this value is never changed. Consider using .Eventually\\(slowInt_err\\)\\.Should\\(Equal\\(42\\)\\)"
}
var _ = FDescribe("Should warn for focused containers", func() {
FContext("should not allow FContext", func() {
FWhen("should not allow FWhen", func() {
FIt("should not allow FIt", func() {})
})
})
})
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_err.yml
================================================
version: "2"
linters:
settings:
ginkgolinter:
suppress-err-assertion: true
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_focused_containers.go
================================================
//golangcitest:args -Eginkgolinter
//golangcitest:config_path testdata/ginkgolinter_suppress_focused_containers.yml
package ginkgolinter
import (
"errors"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func LenUsecase_focus() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(HaveLen\\(2\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0)) // // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.To\\(BeEmpty\\(\\)\\)"
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).Should(Equal(1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(HaveLen\\(1\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
}
func NilUsecase_focus() {
y := 5
x := &y
Expect(x == nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(nil == x).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x != nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeTrue()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeFalse()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
}
func BooleanUsecase_focus() {
x := true
Expect(x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeTrue\\(\\)\\)"
x = false
Expect(x).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeFalse\\(\\)\\)"
}
func ErrorUsecase_focus() {
err := errors.New("fake error")
funcReturnsErr := func() error { return err }
Expect(err).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(Equal(true)) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(BeFalse()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(err != nil).To(BeTrue()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(funcReturnsErr()).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(funcReturnsErr\\(\\)\\)\\.To\\(Succeed\\(\\)\\)"
}
func HaveLen0Usecase_focus() {
x := make([]string, 0)
Expect(x).To(HaveLen(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(x\\)\\.To\\(BeEmpty\\(\\)\\)"
}
func WrongComparisonUsecase_focus() {
x := 8
Expect(x == 8).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(Equal\\(8\\)\\)"
Expect(x < 9).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(BeNumerically\\(\"<\", 9\\)\\)"
Expect(x < 7).To(Equal(false)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNumerically\\(\"<\", 7\\)\\)"
p1, p2 := &x, &x
Expect(p1 == p2).To(Equal(true)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(p1\\).To\\(BeIdenticalTo\\(p2\\)\\)"
}
func slowInt_focus() int {
time.Sleep(time.Second)
return 42
}
func WrongEventuallyWithFunction_focus() {
Eventually(slowInt_focus).Should(Equal(42)) // valid
Eventually(slowInt_focus()).Should(Equal(42)) // want "ginkgo-linter: use a function call in Eventually. This actually checks nothing, because Eventually receives the function returned value, instead of function itself, and this value is never changed. Consider using .Eventually\\(slowInt_focus\\)\\.Should\\(Equal\\(42\\)\\)"
}
var _ = Describe("Should warn for focused containers", func() {
FContext("should not allow FContext", func() { // want "ginkgo-linter: Focus container found. This is used only for local debug and should not be part of the actual source code. Consider to replace with \"Context\""
FWhen("should not allow FWhen", func() { // want "ginkgo-linter: Focus container found. This is used only for local debug and should not be part of the actual source code. Consider to replace with \"When\""
FIt("should not allow FIt", func() { // want "ginkgo-linter: Focus container found. This is used only for local debug and should not be part of the actual source code. Consider to replace with \"It\""
})
})
})
})
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_focused_containers.yml
================================================
version: "2"
linters:
settings:
ginkgolinter:
forbid-focus-container: true
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_len.go
================================================
//golangcitest:config_path testdata/ginkgolinter_suppress_len.yml
//golangcitest:args -Eginkgolinter
package ginkgolinter
import (
"errors"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
// LenUsecase_len should not trigger any warning
func LenUsecase_len() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0))
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2))
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0))
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0))
Expect(len(fakeVarUnderTest)).Should(Equal(1))
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0))
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1))
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0))
}
func NilUsecase_len() {
y := 5
x := &y
Expect(x == nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(nil == x).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x != nil).To(Equal(true)) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeTrue()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.To\\(BeNil\\(\\)\\)"
Expect(x == nil).To(BeFalse()) // want "ginkgo-linter: wrong nil assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNil\\(\\)\\)"
}
func BooleanUsecase_len() {
x := true
Expect(x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeTrue\\(\\)\\)"
x = false
Expect(x).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeFalse\\(\\)\\)"
}
func ErrorUsecase_len() {
err := errors.New("fake error")
funcReturnsErr := func() error { return err }
Expect(err).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(Equal(true)) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(BeFalse()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(err != nil).To(BeTrue()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(funcReturnsErr()).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(funcReturnsErr\\(\\)\\)\\.To\\(Succeed\\(\\)\\)"
}
func HaveLen0Usecase_len() {
x := make([]string, 0)
Expect(x).To(HaveLen(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(x\\)\\.To\\(BeEmpty\\(\\)\\)"
}
func WrongComparisonUsecase_len() {
x := 8
Expect(x == 8).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(Equal\\(8\\)\\)"
Expect(x < 9).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(BeNumerically\\(\"<\", 9\\)\\)"
Expect(x < 7).To(Equal(false)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNumerically\\(\"<\", 7\\)\\)"
p1, p2 := &x, &x
Expect(p1 == p2).To(Equal(true)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(p1\\).To\\(BeIdenticalTo\\(p2\\)\\)"
}
func slowInt_len() int {
time.Sleep(time.Second)
return 42
}
func WrongEventuallyWithFunction_len() {
Eventually(slowInt_len).Should(Equal(42)) // valid
Eventually(slowInt_len()).Should(Equal(42)) // want "ginkgo-linter: use a function call in Eventually. This actually checks nothing, because Eventually receives the function returned value, instead of function itself, and this value is never changed. Consider using .Eventually\\(slowInt_len\\)\\.Should\\(Equal\\(42\\)\\)"
}
var _ = FDescribe("Should warn for focused containers", func() {
FContext("should not allow FContext", func() {
FWhen("should not allow FWhen", func() {
FIt("should not allow FIt", func() {})
})
})
})
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_len.yml
================================================
version: "2"
linters:
settings:
ginkgolinter:
suppress-len-assertion: true
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_nil.go
================================================
//golangcitest:args -Eginkgolinter
//golangcitest:config_path testdata/ginkgolinter_suppress_nil.yml
package ginkgolinter
import (
"errors"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func LenUsecase_nil() {
var fakeVarUnderTest []int
Expect(fakeVarUnderTest).Should(BeEmpty()) // valid
Expect(fakeVarUnderTest).ShouldNot(HaveLen(5)) // valid
Expect(len(fakeVarUnderTest)).Should(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(2)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(HaveLen\\(2\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("==", 0)) // // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.To\\(BeEmpty\\(\\)\\)"
fakeVarUnderTest = append(fakeVarUnderTest, 3)
Expect(len(fakeVarUnderTest)).ShouldNot(Equal(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ShouldNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).Should(Equal(1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.Should\\(HaveLen\\(1\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically(">=", 1)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
Expect(len(fakeVarUnderTest)).To(BeNumerically("!=", 0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(fakeVarUnderTest\\)\\.ToNot\\(BeEmpty\\(\\)\\)"
}
// NilUsecase_nil should not trigger any warning
func NilUsecase_nil() {
y := 5
x := &y
Expect(x == nil).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using `Expect\\(x == nil\\).To\\(BeTrue\\(\\)\\)`"
Expect(nil == x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using `Expect\\(nil == x\\).To\\(BeTrue\\(\\)\\)`"
Expect(x != nil).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using `Expect\\(x != nil\\).To\\(BeTrue\\(\\)\\)`"
Expect(x == nil).To(BeTrue())
Expect(x == nil).To(BeFalse())
}
func BooleanUsecase_nil() {
x := true
Expect(x).To(Equal(true)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeTrue\\(\\)\\)"
x = false
Expect(x).To(Equal(false)) // want "ginkgo-linter: wrong boolean assertion. Consider using .Expect\\(x\\)\\.To\\(BeFalse\\(\\)\\)"
}
func ErrorUsecase_nil() {
err := errors.New("fake error")
funcReturnsErr := func() error { return err }
Expect(err).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(Equal(true)) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.ToNot\\(HaveOccurred\\(\\)\\)"
Expect(err == nil).To(BeFalse()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(err != nil).To(BeTrue()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(err\\)\\.To\\(HaveOccurred\\(\\)\\)"
Expect(funcReturnsErr()).To(BeNil()) // want "ginkgo-linter: wrong error assertion. Consider using .Expect\\(funcReturnsErr\\(\\)\\)\\.To\\(Succeed\\(\\)\\)"
}
func HaveLen0Usecase_nil() {
x := make([]string, 0)
Expect(x).To(HaveLen(0)) // want "ginkgo-linter: wrong length assertion. Consider using .Expect\\(x\\)\\.To\\(BeEmpty\\(\\)\\)"
}
func WrongComparisonUsecase_nil() {
x := 8
Expect(x == 8).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(Equal\\(8\\)\\)"
Expect(x < 9).To(BeTrue()) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.To\\(BeNumerically\\(\"<\", 9\\)\\)"
Expect(x < 7).To(Equal(false)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(x\\)\\.ToNot\\(BeNumerically\\(\"<\", 7\\)\\)"
p1, p2 := &x, &x
Expect(p1 == p2).To(Equal(true)) // want "ginkgo-linter: wrong comparison assertion. Consider using .Expect\\(p1\\).To\\(BeIdenticalTo\\(p2\\)\\)"
}
func slowInt_nil() int {
time.Sleep(time.Second)
return 42
}
func WrongEventuallyWithFunction_nil() {
Eventually(slowInt_nil).Should(Equal(42)) // valid
Eventually(slowInt_nil()).Should(Equal(42)) // want "ginkgo-linter: use a function call in Eventually. This actually checks nothing, because Eventually receives the function returned value, instead of function itself, and this value is never changed. Consider using .Eventually\\(slowInt_nil\\)\\.Should\\(Equal\\(42\\)\\)"
}
var _ = FDescribe("Should warn for focused containers", func() {
FContext("should not allow FContext", func() {
FWhen("should not allow FWhen", func() {
FIt("should not allow FIt", func() {})
})
})
})
================================================
FILE: pkg/golinters/ginkgolinter/testdata/ginkgolinter_suppress_nil.yml
================================================
version: "2"
linters:
settings:
ginkgolinter:
suppress-nil-assertion: true
================================================
FILE: pkg/golinters/ginkgolinter/testdata/go.mod
================================================
module ginkgolinter
go 1.25.0
require (
github.com/onsi/ginkgo/v2 v2.28.1
github.com/onsi/gomega v1.39.1
)
require (
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/mod v0.32.0 // indirect
golang.org/x/net v0.49.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
golang.org/x/tools v0.41.0 // indirect
)
================================================
FILE: pkg/golinters/ginkgolinter/testdata/go.sum
================================================
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=
github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=
github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI=
github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
================================================
FILE: pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go
================================================
package gocheckcompilerdirectives
import (
"4d63.com/gocheckcompilerdirectives/checkcompilerdirectives"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(checkcompilerdirectives.Analyzer()).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives_integration_test.go
================================================
package gocheckcompilerdirectives
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gocheckcompilerdirectives/testdata/gocheckcompilerdirectives.go
================================================
//golangcitest:args -Egocheckcompilerdirectives
package testdata
import _ "embed"
// Okay cases:
//go:generate echo hello world
//go:embed
var Value string
//go:
// Problematic cases:
// go:embed // want "compiler directive contains space: // go:embed"
// go:embed // want "compiler directive contains space: // go:embed"
//go:genrate // want "compiler directive unrecognized: //go:genrate"
================================================
FILE: pkg/golinters/gocheckcompilerdirectives/testdata/gocheckcompilerdirectives_cgo.go
================================================
//golangcitest:args -Egocheckcompilerdirectives
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
_ "embed"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
// Okay cases:
//go:generate echo hello world
//go:embed
var Value string
//go:
// Problematic cases:
// go:embed // want "compiler directive contains space: // go:embed"
// go:embed // want "compiler directive contains space: // go:embed"
//go:genrate // want "compiler directive unrecognized: //go:genrate"
================================================
FILE: pkg/golinters/gochecknoglobals/gochecknoglobals.go
================================================
package gochecknoglobals
import (
"4d63.com/gochecknoglobals/checknoglobals"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(checknoglobals.Analyzer()).
WithDesc("Check that no global variables exist.").
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/gochecknoglobals/gochecknoglobals_integration_test.go
================================================
package gochecknoglobals
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gochecknoglobals/testdata/gochecknoglobals.go
================================================
//golangcitest:args -Egochecknoglobals
package testdata
import (
"errors"
"fmt"
"regexp"
)
var noGlobalsVar int // want "noGlobalsVar is a global variable"
var ErrSomeType = errors.New("test that global errors aren't warned")
var (
OnlyDigits = regexp.MustCompile(`^\d+$`)
BadNamedErr = errors.New("this is bad") // want "BadNamedErr is a global variable"
)
func NoGlobals() {
fmt.Print(noGlobalsVar)
}
================================================
FILE: pkg/golinters/gochecknoglobals/testdata/gochecknoglobals_cgo.go
================================================
//golangcitest:args -Egochecknoglobals
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"errors"
"fmt"
"regexp"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
var noGlobalsVar int // want "noGlobalsVar is a global variable"
var ErrSomeType = errors.New("test that global errors aren't warned")
var (
OnlyDigits = regexp.MustCompile(`^\d+$`)
BadNamedErr = errors.New("this is bad") // want "BadNamedErr is a global variable"
)
func NoGlobals() {
fmt.Print(noGlobalsVar)
}
================================================
FILE: pkg/golinters/gochecknoinits/gochecknoinits.go
================================================
package gochecknoinits
import (
"go/ast"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: "gochecknoinits",
Doc: "Checks that no init functions are present in Go code",
Run: run,
Requires: []*analysis.Analyzer{inspect.Analyzer},
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func run(pass *analysis.Pass) (any, error) {
insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
if !ok {
return nil, nil
}
for node := range insp.PreorderSeq((*ast.FuncDecl)(nil)) {
funcDecl, ok := node.(*ast.FuncDecl)
if !ok {
continue
}
fnName := funcDecl.Name.Name
if fnName == "init" && funcDecl.Recv.NumFields() == 0 {
pass.Reportf(funcDecl.Pos(), "don't use %s function", internal.FormatCode(fnName))
}
}
return nil, nil
}
================================================
FILE: pkg/golinters/gochecknoinits/gochecknoinits_integration_test.go
================================================
package gochecknoinits
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gochecknoinits/testdata/gochecknoinits.go
================================================
//golangcitest:args -Egochecknoinits
package testdata
import "fmt"
func init() { // want "don't use `init` function"
fmt.Println()
}
func Init() {}
================================================
FILE: pkg/golinters/gochecknoinits/testdata/gochecknoinits_cgo.go
================================================
//golangcitest:args -Egochecknoinits
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func init() { // want "don't use `init` function"
fmt.Println()
}
func Init() {}
================================================
FILE: pkg/golinters/gochecksumtype/gochecksumtype.go
================================================
package gochecksumtype
import (
"strings"
"sync"
gochecksumtype "github.com/alecthomas/go-check-sumtype"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gochecksumtype"
func New(settings *config.GoChecksumTypeSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []*goanalysis.Issue
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: `Run exhaustiveness checks on Go "sum types"`,
Run: func(pass *analysis.Pass) (any, error) {
issues, err := runGoCheckSumType(pass, settings)
if err != nil {
return nil, err
}
if len(issues) == 0 {
return nil, nil
}
mu.Lock()
resIssues = append(resIssues, issues...)
mu.Unlock()
return nil, nil
},
}).
WithIssuesReporter(func(_ *linter.Context) []*goanalysis.Issue {
return resIssues
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func runGoCheckSumType(pass *analysis.Pass, settings *config.GoChecksumTypeSettings) ([]*goanalysis.Issue, error) {
var resIssues []*goanalysis.Issue
pkg := &packages.Package{
Fset: pass.Fset,
Syntax: pass.Files,
Types: pass.Pkg,
TypesInfo: pass.TypesInfo,
}
cfg := gochecksumtype.Config{
DefaultSignifiesExhaustive: settings.DefaultSignifiesExhaustive,
IncludeSharedInterfaces: settings.IncludeSharedInterfaces,
}
var unknownError error
errors := gochecksumtype.Run([]*packages.Package{pkg}, cfg)
for _, err := range errors {
err, ok := err.(gochecksumtype.Error)
if !ok {
unknownError = err
continue
}
resIssues = append(resIssues, goanalysis.NewIssue(&result.Issue{
FromLinter: linterName,
Text: strings.TrimPrefix(err.Error(), err.Pos().String()+": "),
Pos: err.Pos(),
}, pass))
}
return resIssues, unknownError
}
================================================
FILE: pkg/golinters/gochecksumtype/gochecksumtype_integration_test.go
================================================
package gochecksumtype
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gochecksumtype/testdata/gochecksumtype.go
================================================
//golangcitest:args -Egochecksumtype
package testdata
import (
"log"
)
//sumtype:decl
type SumType interface{ isSumType() }
//sumtype:decl
type One struct{} // want "type 'One' is not an interface"
func (One) isSumType() {}
type Two struct{}
func (Two) isSumType() {}
func sumTypeTest() {
var sum SumType = One{}
switch sum.(type) { // want "exhaustiveness check failed for sum type.*SumType.*missing cases for Two"
case One:
}
switch sum.(type) { // want "exhaustiveness check failed for sum type.*SumType.*missing cases for Two"
case One:
default:
panic("??")
}
switch sum.(type) {
case *One:
default:
log.Println("legit catch all goes here")
}
log.Println("??")
switch sum.(type) {
case One:
case Two:
}
}
================================================
FILE: pkg/golinters/gochecksumtype/testdata/gochecksumtype_cgo.go
================================================
//golangcitest:args -Egochecksumtype
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"log"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
//sumtype:decl
type SumType interface{ isSumType() }
//sumtype:decl
type One struct{} // want "type 'One' is not an interface"
func (One) isSumType() {}
type Two struct{}
func (Two) isSumType() {}
func sumTypeTest() {
var sum SumType = One{}
switch sum.(type) { // want "exhaustiveness check failed for sum type.*SumType.*missing cases for Two"
case One:
}
switch sum.(type) { // want "exhaustiveness check failed for sum type.*SumType.*missing cases for Two"
case One:
default:
panic("??")
}
switch sum.(type) {
case *One:
default:
log.Println("legit catch all goes here")
}
log.Println("??")
switch sum.(type) {
case One:
case Two:
}
}
================================================
FILE: pkg/golinters/gochecksumtype/testdata/gochecksumtype_custom.go
================================================
//golangcitest:args -Egochecksumtype
//golangcitest:config_path testdata/gochecksumtype_custom.yml
package testdata
import (
"log"
)
//sumtype:decl
type SumType interface{ isSumType() }
//sumtype:decl
type One struct{} // want "type 'One' is not an interface"
func (One) isSumType() {}
type Two struct{}
func (Two) isSumType() {}
func sumTypeTest() {
var sum SumType = One{}
switch sum.(type) { // want "exhaustiveness check failed for sum type.*SumType.*missing cases for Two"
case One:
}
switch sum.(type) { // want "exhaustiveness check failed for sum type.*SumType.*missing cases for Two"
case One:
default:
panic("??")
}
switch sum.(type) { // want "exhaustiveness check failed for sum type.*SumType.*missing cases for Two"
case *One:
default:
log.Println("legit catch all goes here")
}
log.Println("??")
switch sum.(type) {
case One:
case Two:
}
}
================================================
FILE: pkg/golinters/gochecksumtype/testdata/gochecksumtype_custom.yml
================================================
version: "2"
linters:
settings:
gochecksumtype:
default-signifies-exhaustive: false
================================================
FILE: pkg/golinters/gocognit/gocognit.go
================================================
package gocognit
import (
"fmt"
"sort"
"sync"
"github.com/uudashr/gocognit"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gocognit"
func New(settings *config.GocognitSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []*goanalysis.Issue
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: "Computes and checks the cognitive complexity of functions",
Run: func(pass *analysis.Pass) (any, error) {
issues := runGocognit(pass, settings)
if len(issues) == 0 {
return nil, nil
}
mu.Lock()
resIssues = append(resIssues, issues...)
mu.Unlock()
return nil, nil
},
}).
WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
return resIssues
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func runGocognit(pass *analysis.Pass, settings *config.GocognitSettings) []*goanalysis.Issue {
var stats []gocognit.Stat
for _, f := range pass.Files {
stats = gocognit.ComplexityStats(f, pass.Fset, stats)
}
if len(stats) == 0 {
return nil
}
sort.SliceStable(stats, func(i, j int) bool {
return stats[i].Complexity > stats[j].Complexity
})
issues := make([]*goanalysis.Issue, 0, len(stats))
for _, s := range stats {
if s.Complexity <= settings.MinComplexity {
break // Break as the stats is already sorted from greatest to least
}
issues = append(issues, goanalysis.NewIssue(&result.Issue{
Pos: s.Pos,
Text: fmt.Sprintf("cognitive complexity %d of func %s is high (> %d)",
s.Complexity, internal.FormatCode(s.FuncName), settings.MinComplexity),
FromLinter: linterName,
}, pass))
}
return issues
}
================================================
FILE: pkg/golinters/gocognit/gocognit_integration_test.go
================================================
package gocognit
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gocognit/testdata/gocognit.go
================================================
//golangcitest:args -Egocognit
//golangcitest:config_path testdata/gocognit.yml
package testdata
func GoCognit_CC4_GetWords(number int) string { // want "cognitive complexity 4 of func .* is high .*"
if number == 1 { // +1
return "one"
} else if number == 2 { // +1
return "a couple"
} else if number == 3 { // +1
return "a few"
} else { // +1
return "lots"
}
} // total complexity = 4
func GoCognit_CC1_GetWords(number int) string {
switch number { // +1
case 1:
return "one"
case 2:
return "a couple"
case 3:
return "a few"
default:
return "lots"
}
} // Cognitive complexity = 1
func GoCognit_CC3_Fact(n int) int { // want "cognitive complexity 3 of func .* is high .*"
if n <= 1 { // +1
return 1
} else { // +1
return n + GoCognit_CC3_Fact(n-1) // +1
}
} // total complexity = 3
func GoCognit_CC7_SumOfPrimes(max int) int { // want "cognitive complexity 7 of func .* is high .*"
var total int
OUT:
for i := 1; i < max; i++ { // +1
for j := 2; j < i; j++ { // +2 (nesting = 1)
if i%j == 0 { // +3 (nesting = 2)
continue OUT // +1
}
}
total += i
}
return total
} // Cognitive complexity = 7
================================================
FILE: pkg/golinters/gocognit/testdata/gocognit.yml
================================================
version: "2"
linters:
settings:
gocognit:
min-complexity: 2
================================================
FILE: pkg/golinters/gocognit/testdata/gocognit_cgo.go
================================================
//golangcitest:args -Egocognit
//golangcitest:config_path testdata/gocognit.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _(number int) string { // want "cognitive complexity 4 of func .* is high .*"
if number == 1 { // +1
return "one"
} else if number == 2 { // +1
return "a couple"
} else if number == 3 { // +1
return "a few"
} else { // +1
return "lots"
}
} // total complexity = 4
================================================
FILE: pkg/golinters/goconst/goconst.go
================================================
package goconst
import (
"fmt"
"sync"
goconstAPI "github.com/jgautheron/goconst"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "goconst"
func New(settings *config.GoConstSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []*goanalysis.Issue
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: "Finds repeated strings that could be replaced by a constant",
Run: func(pass *analysis.Pass) (any, error) {
issues, err := runGoconst(pass, settings)
if err != nil {
return nil, err
}
if len(issues) == 0 {
return nil, nil
}
mu.Lock()
resIssues = append(resIssues, issues...)
mu.Unlock()
return nil, nil
},
}).
WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
return resIssues
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func runGoconst(pass *analysis.Pass, settings *config.GoConstSettings) ([]*goanalysis.Issue, error) {
cfg := goconstAPI.Config{
IgnoreStrings: settings.IgnoreStringValues,
MatchWithConstants: settings.MatchWithConstants,
MinStringLength: settings.MinStringLen,
MinOccurrences: settings.MinOccurrencesCount,
ParseNumbers: settings.ParseNumbers,
NumberMin: settings.NumberMin,
NumberMax: settings.NumberMax,
ExcludeTypes: map[goconstAPI.Type]bool{},
FindDuplicates: settings.FindDuplicates,
EvalConstExpressions: settings.EvalConstExpressions,
// Should be managed with `linters.exclusions.rules`.
IgnoreTests: false,
}
if settings.IgnoreCalls {
cfg.ExcludeTypes[goconstAPI.Call] = true
}
lintIssues, err := goconstAPI.Run(pass.Files, pass.Fset, pass.TypesInfo, &cfg)
if err != nil {
return nil, err
}
if len(lintIssues) == 0 {
return nil, nil
}
res := make([]*goanalysis.Issue, 0, len(lintIssues))
for i := range lintIssues {
issue := &lintIssues[i]
var text string
switch {
case issue.OccurrencesCount > 0:
text = fmt.Sprintf("string %s has %d occurrences", internal.FormatCode(issue.Str), issue.OccurrencesCount)
if issue.MatchingConst == "" {
text += ", make it a constant"
} else {
text += fmt.Sprintf(", but such constant %s already exists", internal.FormatCode(issue.MatchingConst))
}
case issue.DuplicateConst != "":
text = fmt.Sprintf("This constant is a duplicate of %s at %s",
internal.FormatCode(issue.DuplicateConst),
issue.DuplicatePos.String())
default:
continue
}
res = append(res, goanalysis.NewIssue(&result.Issue{
Pos: issue.Pos,
Text: text,
FromLinter: linterName,
}, pass))
}
return res, nil
}
================================================
FILE: pkg/golinters/goconst/goconst_integration_test.go
================================================
package goconst
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/goconst/testdata/goconst.go
================================================
//golangcitest:args -Egoconst
package testdata
import "fmt"
func GoconstA() {
a := "needconst" // want "string `needconst` has 5 occurrences, make it a constant"
fmt.Print(a)
b := "needconst"
fmt.Print(b)
c := "needconst"
fmt.Print(c)
}
func GoconstB() {
a := "needconst"
fmt.Print(a)
b := "needconst"
fmt.Print(b)
}
const AlreadyHasConst = "alreadyhasconst"
func GoconstC() {
a := "alreadyhasconst" // want "string `alreadyhasconst` has 3 occurrences, but such constant `AlreadyHasConst` already exists"
fmt.Print(a)
b := "alreadyhasconst"
fmt.Print(b)
c := "alreadyhasconst"
fmt.Print(c)
fmt.Print("alreadyhasconst")
}
================================================
FILE: pkg/golinters/goconst/testdata/goconst_calls_enabled.go
================================================
//golangcitest:args -Egoconst
//golangcitest:config_path testdata/goconst_calls_enabled.yml
package testdata
import "fmt"
const FooBar = "foobar"
func Baz() {
a := "foobar" // want "string `foobar` has 4 occurrences, but such constant `FooBar` already exists"
fmt.Print(a)
b := "foobar"
fmt.Print(b)
c := "foobar"
fmt.Print(c)
fmt.Print("foobar")
}
================================================
FILE: pkg/golinters/goconst/testdata/goconst_calls_enabled.yml
================================================
version: "2"
linters:
settings:
goconst:
ignore-calls: false
================================================
FILE: pkg/golinters/goconst/testdata/goconst_cgo.go
================================================
//golangcitest:args -Egoconst
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
a := "needconst" // want "string `needconst` has 5 occurrences, make it a constant"
fmt.Print(a)
b := "needconst"
fmt.Print(b)
c := "needconst"
fmt.Print(c)
}
func _() {
a := "needconst"
fmt.Print(a)
b := "needconst"
fmt.Print(b)
}
================================================
FILE: pkg/golinters/goconst/testdata/goconst_dont_ignore_test.go
================================================
//golangcitest:args -Egoconst
package testdata
import (
"fmt"
"testing"
)
func TestGoConstA(t *testing.T) {
a := "needconst" // want "string `needconst` has 5 occurrences, make it a constant"
fmt.Print(a)
b := "needconst"
fmt.Print(b)
c := "needconst"
fmt.Print(c)
}
func TestGoConstB(t *testing.T) {
a := "needconst"
fmt.Print(a)
b := "needconst"
fmt.Print(b)
}
const AlreadyHasConst = "alreadyhasconst"
func TestGoConstC(t *testing.T) {
a := "alreadyhasconst" // want "string `alreadyhasconst` has 3 occurrences, but such constant `AlreadyHasConst` already exists"
fmt.Print(a)
b := "alreadyhasconst"
fmt.Print(b)
c := "alreadyhasconst"
fmt.Print(c)
fmt.Print("alreadyhasconst")
}
================================================
FILE: pkg/golinters/goconst/testdata/goconst_eval_and_find_duplicates.go
================================================
//golangcitest:args -Egoconst
//golangcitest:config_path testdata/goconst_eval_and_find_duplicates.yml
package testdata
import "fmt"
const (
envPrefix = "FOO_"
EnvUser = envPrefix + "USER"
EnvPassword = envPrefix + "PASSWORD"
)
const EnvUserFull = "FOO_USER" // want "This constant is a duplicate of `EnvUser` at .*goconst_eval_and_find_duplicates.go:9:16"
const KiB = 1 << 10
func _() {
fmt.Println(envPrefix, EnvUser, EnvPassword, EnvUserFull)
const kilobytes = 1024 // want "This constant is a duplicate of `KiB` at .*goconst_eval_and_find_duplicates.go:15:13"
fmt.Println(kilobytes)
kib := 1024
fmt.Println(kib)
}
================================================
FILE: pkg/golinters/goconst/testdata/goconst_eval_and_find_duplicates.yml
================================================
version: "2"
linters:
settings:
goconst:
find-duplicates: true
eval-const-expressions: true
numbers: true
================================================
FILE: pkg/golinters/goconst/testdata/goconst_eval_const_expressions.go
================================================
//golangcitest:args -Egoconst
//golangcitest:config_path testdata/goconst_eval_const_expressions.yml
package testdata
const (
prefix = "example.com/"
API = prefix + "api"
Web = prefix + "web"
)
const Full = "example.com/api"
func _() {
a0 := "example.com/api" // want "string `example.com/api` has 3 occurrences, but such constant `API` already exists"
a1 := "example.com/api"
a2 := "example.com/api"
_ = a0
_ = a1
_ = a2
b0 := "example.com/web" // want "string `example.com/web` has 3 occurrences, but such constant `Web` already exists"
b1 := "example.com/web"
b2 := "example.com/web"
_ = b0
_ = b1
_ = b2
}
================================================
FILE: pkg/golinters/goconst/testdata/goconst_eval_const_expressions.yml
================================================
version: "2"
linters:
settings:
goconst:
eval-const-expressions: true
================================================
FILE: pkg/golinters/goconst/testdata/goconst_find_duplicates.go
================================================
//golangcitest:args -Egoconst
//golangcitest:config_path testdata/goconst_find_duplicates.yml
package testdata
const SingleConst = "single constant"
const (
GroupedConst1 = "grouped constant"
GroupedConst2 = "another grouped"
)
const (
GroupedDuplicateConst1 = "grouped duplicate value"
GroupedDuplicateConst2 = "grouped duplicate value" // want "This constant is a duplicate of `GroupedDuplicateConst1` at .*goconst_find_duplicates.go:13:2"
)
const DuplicateConst1 = "duplicate value"
const DuplicateConst2 = "duplicate value" // want "This constant is a duplicate of `DuplicateConst1` at .*goconst_find_duplicates.go:17:7"
const (
SpecialDuplicateConst1 = "special\nvalue\twith\rchars"
SpecialDuplicateConst2 = "special\nvalue\twith\rchars" // want "This constant is a duplicate of `SpecialDuplicateConst1` at .*goconst_find_duplicates.go:22:2"
)
func _() {
const DuplicateScopedConst1 = "duplicate scoped value"
const DuplicateScopedConst2 = "duplicate scoped value" // want "This constant is a duplicate of `DuplicateScopedConst1` at .*goconst_find_duplicates.go:27:8"
}
================================================
FILE: pkg/golinters/goconst/testdata/goconst_find_duplicates.yml
================================================
version: "2"
linters:
settings:
goconst:
find-duplicates: true
================================================
FILE: pkg/golinters/gocritic/gocritic.go
================================================
package gocritic
import (
"errors"
"fmt"
"go/ast"
"go/types"
"runtime"
"slices"
"strings"
"sync"
"github.com/go-critic/go-critic/checkers"
gocriticlinter "github.com/go-critic/go-critic/linter"
_ "github.com/quasilyte/go-ruleguard/dsl"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const linterName = "gocritic"
var (
debugf = logutils.Debug(logutils.DebugKeyGoCritic)
isDebug = logutils.HaveDebugTag(logutils.DebugKeyGoCritic)
)
func New(settings *config.GoCriticSettings, replacer *strings.Replacer) *goanalysis.Linter {
wrapper := &goCriticWrapper{
sizes: types.SizesFor("gc", runtime.GOARCH),
}
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: `Provides diagnostics that check for bugs, performance and style issues.
Extensible without recompilation through dynamic rules.
Dynamic rules are written declaratively with AST patterns, filters, report message and optional suggestion.`,
Run: func(pass *analysis.Pass) (any, error) {
err := wrapper.run(pass)
if err != nil {
return nil, err
}
return nil, nil
},
}).
WithContextSetter(func(context *linter.Context) {
wrapper.init(context.Log, settings, replacer)
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
type goCriticWrapper struct {
settingsWrapper *settingsWrapper
sizes types.Sizes
once sync.Once
}
func (w *goCriticWrapper) init(logger logutils.Log, settings *config.GoCriticSettings, replacer *strings.Replacer) {
if settings == nil {
return
}
w.once.Do(func() {
err := checkers.InitEmbeddedRules()
if err != nil {
logger.Fatalf("%s: %v: setting an explicit GOROOT can fix this problem", linterName, err)
}
})
settingsWrapper := newSettingsWrapper(logger, settings, replacer)
if err := settingsWrapper.Load(); err != nil {
logger.Fatalf("%s: invalid settings: %s", linterName, err)
}
w.settingsWrapper = settingsWrapper
}
func (w *goCriticWrapper) run(pass *analysis.Pass) error {
if w.settingsWrapper == nil {
return errors.New("the settings wrapper is nil")
}
linterCtx := gocriticlinter.NewContext(pass.Fset, w.sizes)
linterCtx.SetGoVersion(w.settingsWrapper.Go)
enabledCheckers, err := w.buildEnabledCheckers(linterCtx)
if err != nil {
return err
}
linterCtx.SetPackageInfo(pass.TypesInfo, pass.Pkg)
needFileInfo := slices.ContainsFunc(enabledCheckers, func(c *gocriticlinter.Checker) bool {
// Related to https://github.com/go-critic/go-critic/blob/440ff466685b41e67d231a1c4a8f5e093374ee93/checkers/importShadow_checker.go#L23
return strings.EqualFold(c.Info.Name, "importShadow")
})
for _, f := range pass.Files {
if needFileInfo {
// Related to https://github.com/go-critic/go-critic/blob/440ff466685b41e67d231a1c4a8f5e093374ee93/checkers/importShadow_checker.go#L23
linterCtx.SetFileInfo(f.Name.Name, f)
}
runOnFile(pass, f, enabledCheckers)
}
return nil
}
func (w *goCriticWrapper) buildEnabledCheckers(linterCtx *gocriticlinter.Context) ([]*gocriticlinter.Checker, error) {
allLowerCasedParams := w.settingsWrapper.GetLowerCasedParams()
var enabledCheckers []*gocriticlinter.Checker
for _, info := range gocriticlinter.GetCheckersInfo() {
if !w.settingsWrapper.IsCheckEnabled(info.Name) {
continue
}
err := w.settingsWrapper.setCheckerParams(info, allLowerCasedParams)
if err != nil {
return nil, err
}
c, err := gocriticlinter.NewChecker(linterCtx, info)
if err != nil {
return nil, err
}
enabledCheckers = append(enabledCheckers, c)
}
return enabledCheckers, nil
}
func runOnFile(pass *analysis.Pass, f *ast.File, checks []*gocriticlinter.Checker) {
for _, c := range checks {
// All checkers are expected to use *lint.Context
// as read-only structure, so no copying is required.
for _, warn := range c.Check(f) {
diag := analysis.Diagnostic{
Pos: warn.Pos,
Category: c.Info.Name,
Message: fmt.Sprintf("%s: %s", c.Info.Name, warn.Text),
}
if warn.HasQuickFix() {
diag.SuggestedFixes = []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: warn.Suggestion.From,
End: warn.Suggestion.To,
NewText: warn.Suggestion.Replacement,
}},
}}
}
pass.Report(diag)
}
}
}
================================================
FILE: pkg/golinters/gocritic/gocritic_integration_test.go
================================================
package gocritic
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/gocritic/gocritic_settings.go
================================================
package gocritic
import (
"errors"
"fmt"
"maps"
"reflect"
"slices"
"strings"
gocriticlinter "github.com/go-critic/go-critic/linter"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type settingsWrapper struct {
*config.GoCriticSettings
replacer *strings.Replacer
logger logutils.Log
allCheckers []*gocriticlinter.CheckerInfo
allChecks goCriticChecks[struct{}]
allChecksByTag goCriticChecks[[]string]
allTagsSorted []string
inferredEnabledChecks goCriticChecks[struct{}]
// *LowerCased fields are used for GoCriticSettings.SettingsPerCheck validation only.
allChecksLowerCased goCriticChecks[struct{}]
inferredEnabledChecksLowerCased goCriticChecks[struct{}]
}
func newSettingsWrapper(logger logutils.Log, settings *config.GoCriticSettings, replacer *strings.Replacer) *settingsWrapper {
allCheckers := gocriticlinter.GetCheckersInfo()
allChecks := make(goCriticChecks[struct{}], len(allCheckers))
allChecksLowerCased := make(goCriticChecks[struct{}], len(allCheckers))
allChecksByTag := make(goCriticChecks[[]string])
for _, checker := range allCheckers {
allChecks[checker.Name] = struct{}{}
allChecksLowerCased[strings.ToLower(checker.Name)] = struct{}{}
for _, tag := range checker.Tags {
allChecksByTag[tag] = append(allChecksByTag[tag], checker.Name)
}
}
return &settingsWrapper{
GoCriticSettings: settings,
replacer: replacer,
logger: logger,
allCheckers: allCheckers,
allChecks: allChecks,
allChecksByTag: allChecksByTag,
allTagsSorted: slices.Sorted(maps.Keys(allChecksByTag)),
inferredEnabledChecks: make(goCriticChecks[struct{}]),
allChecksLowerCased: allChecksLowerCased,
inferredEnabledChecksLowerCased: make(goCriticChecks[struct{}]),
}
}
func (s *settingsWrapper) IsCheckEnabled(name string) bool {
return s.inferredEnabledChecks.has(name)
}
func (s *settingsWrapper) GetLowerCasedParams() map[string]config.GoCriticCheckSettings {
return normalizeMap(s.SettingsPerCheck)
}
func (s *settingsWrapper) Load() error {
s.inferEnabledChecks()
// validate must be after inferEnabledChecks, not before.
// Because it uses gathered information about tags set and finally enabled checks.
return s.validate()
}
func (s *settingsWrapper) inferEnabledChecks() {
s.debugChecksInitialState()
enabledByDefaultChecks, disabledByDefaultChecks := s.buildEnabledAndDisabledByDefaultChecks()
debugChecksListf(enabledByDefaultChecks, "Enabled by default")
debugChecksListf(disabledByDefaultChecks, "Disabled by default")
var enabledChecks goCriticChecks[struct{}]
switch {
case s.DisableAll:
// disable-all revokes the default settings.
enabledChecks = make(goCriticChecks[struct{}])
case s.EnableAll:
// enable-all revokes the default settings.
enabledChecks = make(goCriticChecks[struct{}], len(s.allCheckers))
for _, info := range s.allCheckers {
enabledChecks[info.Name] = struct{}{}
}
default:
enabledChecks = make(goCriticChecks[struct{}], len(enabledByDefaultChecks))
for _, check := range enabledByDefaultChecks {
enabledChecks[check] = struct{}{}
}
}
if len(s.EnabledTags) > 0 {
enabledFromTags := s.expandTagsToChecks(s.EnabledTags)
debugChecksListf(enabledFromTags, "Enabled by config tags %s", s.EnabledTags)
for _, check := range enabledFromTags {
enabledChecks[check] = struct{}{}
}
}
if len(s.EnabledChecks) > 0 {
debugChecksListf(s.EnabledChecks, "Enabled by config")
for _, check := range s.EnabledChecks {
if enabledChecks.has(check) {
s.logger.Warnf("%s: no need to enable check %q: it's already enabled", linterName, check)
continue
}
enabledChecks[check] = struct{}{}
}
}
if len(s.DisabledTags) > 0 {
disabledFromTags := s.expandTagsToChecks(s.DisabledTags)
debugChecksListf(disabledFromTags, "Disabled by config tags %s", s.DisabledTags)
for _, check := range disabledFromTags {
delete(enabledChecks, check)
}
}
if len(s.DisabledChecks) > 0 {
debugChecksListf(s.DisabledChecks, "Disabled by config")
for _, check := range s.DisabledChecks {
if !enabledChecks.has(check) {
s.logger.Warnf("%s: no need to disable check %q: it's already disabled", linterName, check)
continue
}
delete(enabledChecks, check)
}
}
s.inferredEnabledChecks = enabledChecks
s.inferredEnabledChecksLowerCased = normalizeMap(s.inferredEnabledChecks)
s.debugChecksFinalState()
}
func (s *settingsWrapper) buildEnabledAndDisabledByDefaultChecks() (enabled, disabled []string) {
for _, info := range s.allCheckers {
if isEnabledByDefaultGoCriticChecker(info) {
enabled = append(enabled, info.Name)
} else {
disabled = append(disabled, info.Name)
}
}
return enabled, disabled
}
func (s *settingsWrapper) expandTagsToChecks(tags []string) []string {
var checks []string
for _, tag := range tags {
checks = append(checks, s.allChecksByTag[tag]...)
}
return checks
}
func (s *settingsWrapper) setCheckerParams(
info *gocriticlinter.CheckerInfo,
allLowerCasedParams map[string]config.GoCriticCheckSettings,
) error {
params := allLowerCasedParams[strings.ToLower(info.Name)]
if params == nil { // no config for this checker
return nil
}
// To lowercase info param keys here because golangci-lint's config parser lowercases all strings.
infoParams := normalizeMap(info.Params)
for k, p := range params {
v, ok := infoParams[k]
if ok {
v.Value = s.normalizeCheckerParamsValue(p)
continue
}
// param `k` isn't supported
if len(info.Params) == 0 {
return fmt.Errorf("checker %s config param %s doesn't exist: checker doesn't have params",
info.Name, k)
}
return fmt.Errorf("checker %s config param %s doesn't exist, all existing: %s",
info.Name, k, slices.Sorted(maps.Keys(info.Params)))
}
return nil
}
func (s *settingsWrapper) debugChecksInitialState() {
if !isDebug {
return
}
debugf("All gocritic existing tags and checks:")
for _, tag := range s.allTagsSorted {
debugChecksListf(s.allChecksByTag[tag], " tag %q", tag)
}
}
func (s *settingsWrapper) debugChecksFinalState() {
if !isDebug {
return
}
var enabledChecks []string
var disabledChecks []string
for _, checker := range s.allCheckers {
if s.IsCheckEnabled(checker.Name) {
enabledChecks = append(enabledChecks, checker.Name)
} else {
disabledChecks = append(disabledChecks, checker.Name)
}
}
debugChecksListf(enabledChecks, "Final used")
if len(disabledChecks) == 0 {
debugf("All checks are enabled")
} else {
debugChecksListf(disabledChecks, "Final not used")
}
}
// normalizeCheckerParamsValue normalizes value types.
// go-critic asserts that CheckerParam.Value has some specific types,
// but the file parsers (TOML, YAML, JSON) don't create the same representation for raw type.
// then we have to convert value types into the expected value types.
// Maybe in the future, this kind of conversion will be done in go-critic itself.
func (s *settingsWrapper) normalizeCheckerParamsValue(p any) any {
rv := reflect.ValueOf(p)
switch rv.Type().Kind() {
case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
return int(rv.Int())
case reflect.Bool:
return rv.Bool()
case reflect.String:
// Perform variable substitution.
return s.replacer.Replace(rv.String())
default:
return p
}
}
// validate tries to be consistent with (lintersdb.Validator).validateEnabledDisabledLintersConfig.
func (s *settingsWrapper) validate() error {
for _, v := range []func() error{
s.validateOptionsCombinations,
s.validateCheckerTags,
s.validateCheckerNames,
s.validateDisabledAndEnabledAtOneMoment,
s.validateAtLeastOneCheckerEnabled,
} {
if err := v(); err != nil {
return err
}
}
return nil
}
func (s *settingsWrapper) validateOptionsCombinations() error {
if s.EnableAll && s.DisableAll {
return errors.New("enable-all and disable-all options must not be combined")
}
switch {
case s.EnableAll:
if len(s.EnabledTags) > 0 {
return errors.New("enable-all and enabled-tags options must not be combined")
}
if len(s.EnabledChecks) > 0 {
return errors.New("enable-all and enabled-checks options must not be combined")
}
case s.DisableAll:
if len(s.DisabledTags) > 0 {
return errors.New("disable-all and disabled-tags options must not be combined")
}
if len(s.DisabledChecks) > 0 {
return errors.New("disable-all and disabled-checks options must not be combined")
}
if len(s.EnabledTags) == 0 && len(s.EnabledChecks) == 0 {
return errors.New("all checks were disabled, but no one check was enabled: at least one must be enabled")
}
}
return nil
}
func (s *settingsWrapper) validateCheckerTags() error {
for _, tag := range s.EnabledTags {
if !s.allChecksByTag.has(tag) {
return fmt.Errorf("enabled tag %q doesn't exist, see %s's documentation", tag, linterName)
}
}
for _, tag := range s.DisabledTags {
if !s.allChecksByTag.has(tag) {
return fmt.Errorf("disabled tag %q doesn't exist, see %s's documentation", tag, linterName)
}
}
return nil
}
func (s *settingsWrapper) validateCheckerNames() error {
for _, check := range s.EnabledChecks {
if !s.allChecks.has(check) {
return fmt.Errorf("enabled check %q doesn't exist, see %s's documentation", check, linterName)
}
}
for _, check := range s.DisabledChecks {
if !s.allChecks.has(check) {
return fmt.Errorf("disabled check %q doesn't exist, see %s documentation", check, linterName)
}
}
for check := range s.SettingsPerCheck {
lcName := strings.ToLower(check)
if !s.allChecksLowerCased.has(lcName) {
return fmt.Errorf("invalid check settings: check %q doesn't exist, see %s documentation", check, linterName)
}
if !s.inferredEnabledChecksLowerCased.has(lcName) {
s.logger.Warnf("%s: settings were provided for disabled check %q", check, linterName)
}
}
return nil
}
func (s *settingsWrapper) validateDisabledAndEnabledAtOneMoment() error {
for _, tag := range s.DisabledTags {
if slices.Contains(s.EnabledTags, tag) {
return fmt.Errorf("tag %q disabled and enabled at one moment", tag)
}
}
for _, check := range s.DisabledChecks {
if slices.Contains(s.EnabledChecks, check) {
return fmt.Errorf("check %q disabled and enabled at one moment", check)
}
}
return nil
}
func (s *settingsWrapper) validateAtLeastOneCheckerEnabled() error {
if len(s.inferredEnabledChecks) == 0 {
return errors.New("eventually all checks were disabled: at least one must be enabled")
}
return nil
}
type goCriticChecks[T any] map[string]T
func (m goCriticChecks[T]) has(name string) bool {
_, ok := m[name]
return ok
}
func debugChecksListf(checks []string, format string, args ...any) {
if !isDebug {
return
}
v := slices.Sorted(slices.Values(checks))
debugf("%s checks (%d): %s", fmt.Sprintf(format, args...), len(checks), strings.Join(v, ", "))
}
func normalizeMap[ValueT any](in map[string]ValueT) map[string]ValueT {
ret := make(map[string]ValueT, len(in))
for k, v := range in {
ret[strings.ToLower(k)] = v
}
return ret
}
func isEnabledByDefaultGoCriticChecker(info *gocriticlinter.CheckerInfo) bool {
// https://github.com/go-critic/go-critic/blob/5b67cfd487ae9fe058b4b19321901b3131810f65/cmd/gocritic/check.go#L342-L345
return !info.HasTag(gocriticlinter.ExperimentalTag) &&
!info.HasTag(gocriticlinter.OpinionatedTag) &&
!info.HasTag(gocriticlinter.PerformanceTag) &&
!info.HasTag(gocriticlinter.SecurityTag)
}
================================================
FILE: pkg/golinters/gocritic/gocritic_settings_test.go
================================================
package gocritic
import (
"maps"
"slices"
"strings"
"testing"
"github.com/go-critic/go-critic/checkers"
gocriticlinter "github.com/go-critic/go-critic/linter"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
// https://go-critic.com/overview.html
func Test_settingsWrapper_inferEnabledChecks(t *testing.T) {
err := checkers.InitEmbeddedRules()
require.NoError(t, err)
allCheckersInfo := gocriticlinter.GetCheckersInfo()
allChecksByTag := make(map[string]Slicer)
allChecks := make(Slicer, 0, len(allCheckersInfo))
for _, checker := range allCheckersInfo {
allChecks = append(allChecks, checker.Name)
for _, tag := range checker.Tags {
allChecksByTag[tag] = append(allChecksByTag[tag], checker.Name)
}
}
enabledByDefaultChecks := make(Slicer, 0, len(allCheckersInfo))
for _, info := range allCheckersInfo {
if isEnabledByDefaultGoCriticChecker(info) {
enabledByDefaultChecks = append(enabledByDefaultChecks, info.Name)
}
}
t.Logf("enabled by default checks:\n%s", strings.Join(enabledByDefaultChecks, "\n"))
testCases := []struct {
name string
settings *config.GoCriticSettings
expectedEnabledChecks []string
}{
{
name: "no configuration",
settings: &config.GoCriticSettings{},
expectedEnabledChecks: enabledByDefaultChecks,
},
{
name: "enable checks",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"assignOp", "badCall", "emptyDecl"},
},
expectedEnabledChecks: enabledByDefaultChecks.add("emptyDecl"),
},
{
name: "disable checks",
settings: &config.GoCriticSettings{
DisabledChecks: []string{"assignOp", "emptyDecl"},
},
expectedEnabledChecks: enabledByDefaultChecks.remove("assignOp"),
},
{
name: "enable tags",
settings: &config.GoCriticSettings{
EnabledTags: []string{"style", "experimental"},
},
expectedEnabledChecks: enabledByDefaultChecks.
add(allChecksByTag["style"]...).
add(allChecksByTag["experimental"]...).
uniq(),
},
{
name: "disable tags",
settings: &config.GoCriticSettings{
DisabledTags: []string{"diagnostic"},
},
expectedEnabledChecks: enabledByDefaultChecks.remove(allChecksByTag["diagnostic"]...),
},
{
name: "enable checks disable checks",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"badCall", "badLock"},
DisabledChecks: []string{"assignOp", "badSorting"},
},
expectedEnabledChecks: enabledByDefaultChecks.
remove("assignOp").
add("badLock"),
},
{
name: "enable checks enable tags",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"badCall", "badLock", "hugeParam"},
EnabledTags: []string{"diagnostic"},
},
expectedEnabledChecks: enabledByDefaultChecks.
add(allChecksByTag["diagnostic"]...).
add("hugeParam").
uniq(),
},
{
name: "enable checks disable tags",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"badCall", "badLock", "boolExprSimplify", "hugeParam"},
DisabledTags: []string{"style", "diagnostic"},
},
expectedEnabledChecks: enabledByDefaultChecks.
remove(allChecksByTag["style"]...).
remove(allChecksByTag["diagnostic"]...).
add("hugeParam"),
},
{
name: "enable all checks via tags",
settings: &config.GoCriticSettings{
EnabledTags: []string{"diagnostic", "experimental", "opinionated", "performance", "style"},
},
expectedEnabledChecks: allChecks,
},
{
name: "disable checks enable tags",
settings: &config.GoCriticSettings{
DisabledChecks: []string{"assignOp", "badCall", "badLock", "hugeParam"},
EnabledTags: []string{"style", "diagnostic"},
},
expectedEnabledChecks: enabledByDefaultChecks.
add(allChecksByTag["style"]...).
add(allChecksByTag["diagnostic"]...).
uniq().
remove("assignOp", "badCall", "badLock"),
},
{
name: "disable checks disable tags",
settings: &config.GoCriticSettings{
DisabledChecks: []string{"badCall", "badLock", "codegenComment", "hugeParam"},
DisabledTags: []string{"style"},
},
expectedEnabledChecks: enabledByDefaultChecks.
remove(allChecksByTag["style"]...).
remove("badCall", "codegenComment"),
},
{
name: "enable tags disable tags",
settings: &config.GoCriticSettings{
EnabledTags: []string{"experimental"},
DisabledTags: []string{"style"},
},
expectedEnabledChecks: enabledByDefaultChecks.
add(allChecksByTag["experimental"]...).
uniq().
remove(allChecksByTag["style"]...),
},
{
name: "enable checks disable checks enable tags",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"badCall", "badLock", "boolExprSimplify", "indexAlloc", "hugeParam"},
DisabledChecks: []string{"deprecatedComment", "typeSwitchVar"},
EnabledTags: []string{"experimental"},
},
expectedEnabledChecks: enabledByDefaultChecks.
add(allChecksByTag["experimental"]...).
add("indexAlloc", "hugeParam").
uniq().
remove("deprecatedComment", "typeSwitchVar"),
},
{
name: "enable checks disable checks enable tags disable tags",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"badCall", "badCond", "badLock", "indexAlloc", "hugeParam"},
DisabledChecks: []string{"deprecatedComment", "typeSwitchVar"},
EnabledTags: []string{"experimental"},
DisabledTags: []string{"performance"},
},
expectedEnabledChecks: enabledByDefaultChecks.
add(allChecksByTag["experimental"]...).
add("badCond").
uniq().
remove(allChecksByTag["performance"]...).
remove("deprecatedComment", "typeSwitchVar"),
},
{
name: "enable single tag only",
settings: &config.GoCriticSettings{
DisableAll: true,
EnabledTags: []string{"experimental"},
},
expectedEnabledChecks: allChecksByTag["experimental"],
},
{
name: "enable two tags only",
settings: &config.GoCriticSettings{
DisableAll: true,
EnabledTags: []string{"experimental", "performance"},
},
expectedEnabledChecks: allChecksByTag["experimental"].
add(allChecksByTag["performance"]...).
uniq(),
},
{
name: "disable single tag only",
settings: &config.GoCriticSettings{
EnableAll: true,
DisabledTags: []string{"style"},
},
expectedEnabledChecks: allChecks.remove(allChecksByTag["style"]...),
},
{
name: "disable two tags only",
settings: &config.GoCriticSettings{
EnableAll: true,
DisabledTags: []string{"style", "diagnostic"},
},
expectedEnabledChecks: allChecks.
remove(allChecksByTag["style"]...).
remove(allChecksByTag["diagnostic"]...),
},
{
name: "enable some checks only",
settings: &config.GoCriticSettings{
DisableAll: true,
EnabledChecks: []string{"deferInLoop", "dupImport", "ifElseChain", "mapKey"},
},
expectedEnabledChecks: []string{"deferInLoop", "dupImport", "ifElseChain", "mapKey"},
},
{
name: "disable some checks only",
settings: &config.GoCriticSettings{
EnableAll: true,
DisabledChecks: []string{"deferInLoop", "dupImport", "ifElseChain", "mapKey"},
},
expectedEnabledChecks: allChecks.
remove("deferInLoop", "dupImport", "ifElseChain", "mapKey"),
},
{
name: "enable single tag and some checks from another tag only",
settings: &config.GoCriticSettings{
DisableAll: true,
EnabledTags: []string{"experimental"},
EnabledChecks: []string{"importShadow"},
},
expectedEnabledChecks: allChecksByTag["experimental"].add("importShadow"),
},
{
name: "disable single tag and some checks from another tag only",
settings: &config.GoCriticSettings{
EnableAll: true,
DisabledTags: []string{"experimental"},
DisabledChecks: []string{"importShadow"},
},
expectedEnabledChecks: allChecks.
remove(allChecksByTag["experimental"]...).
remove("importShadow"),
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
lg := logutils.NewStderrLog(t.Name())
wr := newSettingsWrapper(lg, test.settings, nil)
wr.inferEnabledChecks()
assert.ElementsMatch(t, test.expectedEnabledChecks, slices.Collect(maps.Keys(wr.inferredEnabledChecks)))
assert.NoError(t, wr.validate())
})
}
}
func Test_settingsWrapper_Load(t *testing.T) {
testCases := []struct {
name string
settings *config.GoCriticSettings
expectedErr bool
}{
{
name: "combine enable-all and disable-all",
settings: &config.GoCriticSettings{
EnableAll: true,
DisableAll: true,
},
expectedErr: true,
},
{
name: "combine enable-all and enabled-tags",
settings: &config.GoCriticSettings{
EnableAll: true,
EnabledTags: []string{"experimental"},
},
expectedErr: true,
},
{
name: "combine enable-all and enabled-checks",
settings: &config.GoCriticSettings{
EnableAll: true,
EnabledChecks: []string{"dupImport"},
},
expectedErr: true,
},
{
name: "combine disable-all and disabled-tags",
settings: &config.GoCriticSettings{
DisableAll: true,
DisabledTags: []string{"style"},
},
expectedErr: true,
},
{
name: "combine disable-all and disable-checks",
settings: &config.GoCriticSettings{
DisableAll: true,
DisabledChecks: []string{"appendAssign"},
},
expectedErr: true,
},
{
name: "disable-all and no one check enabled",
settings: &config.GoCriticSettings{
DisableAll: true,
},
expectedErr: true,
},
{
name: "unknown enabled tag",
settings: &config.GoCriticSettings{
EnabledTags: []string{"diagnostic", "go-proverbs"},
},
expectedErr: true,
},
{
name: "unknown disabled tag",
settings: &config.GoCriticSettings{
DisabledTags: []string{"style", "go-proverbs"},
},
expectedErr: true,
},
{
name: "unknown enabled check",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"appendAssign", "noExitAfterDefer", "underef"},
},
expectedErr: true,
},
{
name: "unknown disabled check",
settings: &config.GoCriticSettings{
DisabledChecks: []string{"dupSubExpr", "noExitAfterDefer", "returnAfterHttpError"},
},
expectedErr: true,
},
{
name: "settings for unknown check",
settings: &config.GoCriticSettings{
SettingsPerCheck: map[string]config.GoCriticCheckSettings{
"captLocall": {"paramsOnly": false},
"unnamedResult": {"checkExported": true},
},
},
expectedErr: true,
},
{
name: "settings for disabled check",
settings: &config.GoCriticSettings{
DisabledChecks: []string{"elseif"},
SettingsPerCheck: map[string]config.GoCriticCheckSettings{
"elseif": {"skipBalanced": true},
},
},
expectedErr: false, // Just logging.
},
{
name: "settings by lower-cased checker name",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"tooManyResultsChecker"},
SettingsPerCheck: map[string]config.GoCriticCheckSettings{
"toomanyresultschecker": {"maxResults": 3},
"unnamedResult": {"checkExported": true},
},
},
expectedErr: false,
},
{
name: "enabled and disabled at one moment check",
settings: &config.GoCriticSettings{
EnabledChecks: []string{"appendAssign", "codegenComment", "underef"},
DisabledChecks: []string{"elseif", "underef"},
},
expectedErr: true,
},
{
name: "enabled and disabled at one moment tag",
settings: &config.GoCriticSettings{
EnabledTags: []string{"performance", "style"},
DisabledTags: []string{"style", "diagnostic"},
},
expectedErr: true,
},
{
name: "disable all checks via tags",
settings: &config.GoCriticSettings{
DisabledTags: []string{"diagnostic", "experimental", "opinionated", "performance", "style"},
},
expectedErr: true,
},
{
name: "enable-all and disable all checks via tags",
settings: &config.GoCriticSettings{
EnableAll: true,
DisabledTags: []string{"diagnostic", "experimental", "opinionated", "performance", "style"},
},
expectedErr: true,
},
{
name: "valid configuration",
settings: &config.GoCriticSettings{
EnabledTags: []string{"performance"},
DisabledChecks: []string{"dupImport", "ifElseChain", "octalLiteral", "whyNoLint"},
SettingsPerCheck: map[string]config.GoCriticCheckSettings{
"hugeParam": {"sizeThreshold": 100},
"rangeValCopy": {"skipTestFuncs": true},
},
},
expectedErr: false,
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
lg := logutils.NewStderrLog(t.Name())
wr := newSettingsWrapper(lg, test.settings, nil)
err := wr.Load()
if test.expectedErr {
if assert.Error(t, err) {
t.Log(err)
}
} else {
assert.NoError(t, err)
}
})
}
}
type Slicer []string
func (s Slicer) add(toAdd ...string) Slicer {
return slices.Concat(s, toAdd)
}
func (s Slicer) remove(toRemove ...string) Slicer {
result := slices.Clone(s)
for _, v := range toRemove {
if i := slices.Index(result, v); i != -1 {
result = slices.Delete(result, i, i+1)
}
}
return result
}
func (s Slicer) uniq() Slicer {
return slices.Compact(slices.Sorted(slices.Values(s)))
}
================================================
FILE: pkg/golinters/gocritic/testdata/fix/in/gocritic.go
================================================
//golangcitest:args -Egocritic
//golangcitest:config_path testdata/gocritic-fix.yml
//golangcitest:expected_exitcode 0
package p
import (
"strings"
)
func gocritic() {
var xs [2048]byte
// xs -> &xs
for _, x := range xs {
print(x)
}
// strings.Count("foo", "bar") == 0 -> !strings.Contains("foo", "bar")
if strings.Count("foo", "bar") == 0 {
print("qu")
}
}
================================================
FILE: pkg/golinters/gocritic/testdata/fix/out/gocritic.go
================================================
//golangcitest:args -Egocritic
//golangcitest:config_path testdata/gocritic-fix.yml
//golangcitest:expected_exitcode 0
package p
import (
"strings"
)
func gocritic() {
var xs [2048]byte
// xs -> &xs
for _, x := range &xs {
print(x)
}
// strings.Count("foo", "bar") == 0 -> !strings.Contains("foo", "bar")
if !strings.Contains("foo", "bar") {
print("qu")
}
}
================================================
FILE: pkg/golinters/gocritic/testdata/gocritic-fix.yml
================================================
version: "2"
linters:
settings:
gocritic:
enabled-checks:
- ruleguard
settings:
ruleguard:
failOn: dsl,import
rules: '${base-path}/ruleguard/rangeExprCopy.go,${base-path}/ruleguard/stringsSimplify.go'
run:
relative-path-mode: cfg
================================================
FILE: pkg/golinters/gocritic/testdata/gocritic.go
================================================
//golangcitest:args -Egocritic
//golangcitest:config_path testdata/gocritic.yml
package testdata
import (
"flag"
"io"
"log"
"strings"
)
var _ = *flag.Bool("global1", false, "") // want `flagDeref: immediate deref in \*flag.Bool\(.global1., false, ..\) is most likely an error; consider using flag\.BoolVar`
type size1 struct {
a [12]bool
}
type size2 struct {
size1
b [12]bool
}
func gocriticAppendAssign() {
var positives, negatives []int
positives = append(negatives, 1)
negatives = append(negatives, -1)
log.Print(positives, negatives)
}
func gocriticDupSubExpr(x bool) {
if x && x { // want "dupSubExpr: suspicious identical LHS and RHS.*"
log.Print("x is true")
}
}
func gocriticHugeParamSize1(ss size1) {
log.Print(ss)
}
func gocriticHugeParamSize2(ss size2) { // want "hugeParam: ss is heavy \\(24 bytes\\); consider passing it by pointer"
log.Print(ss)
}
func gocriticHugeParamSize2Ptr(ss *size2) {
log.Print(*ss)
}
func gocriticSwitchTrue() {
switch true {
case false:
log.Print("false")
default:
log.Print("default")
}
}
func goCriticPreferStringWriter(w interface {
io.Writer
io.StringWriter
}) {
w.Write([]byte("test")) // want "ruleguard: w\\.WriteString\\(\"test\"\\) should be preferred.*"
}
func gocriticStringSimplify() {
s := "Most of the time, travellers worry about their luggage."
s = strings.Replace(s, ",", "", -1) // want "ruleguard: this Replace call can be simplified.*"
log.Print(s)
}
func gocriticRuleWrapperFunc() {
strings.Replace("abcabc", "a", "d", -1) // want "ruleguard: this Replace call can be simplified.*"
}
================================================
FILE: pkg/golinters/gocritic/testdata/gocritic.yml
================================================
version: "2"
linters:
settings:
gocritic:
disabled-checks:
- appendAssign
- switchTrue
enabled-checks:
- hugeParam
- ruleguard
settings:
hugeParam:
sizeThreshold: 24
ruleguard:
failOn: dsl,import
rules: '${base-path}/ruleguard/preferWriteString.go,${config-path}/ruleguard/stringsSimplify.go'
run:
relative-path-mode: cfg
================================================
FILE: pkg/golinters/gocritic/testdata/gocritic_cgo.go
================================================
//golangcitest:args -Egocritic
//golangcitest:config_path testdata/gocritic.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"flag"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
var _ = *flag.Bool("global1", false, "") // want `flagDeref: immediate deref in \*flag.Bool\(.global1., false, ..\) is most likely an error; consider using flag\.BoolVar`
================================================
FILE: pkg/golinters/gocritic/testdata/gocritic_importShadow.go
================================================
//golangcitest:args -Egocritic
//golangcitest:config_path testdata/gocritic_inportShadow.yml
package testdata
import (
"fmt"
"path/filepath"
)
func Bar() {
filepath.Join("a", "b")
}
func foo() {
filepath := "foo.txt" // want "importShadow: shadow of imported package 'filepath'"
fmt.Printf("File path: %s\n", filepath)
}
================================================
FILE: pkg/golinters/gocritic/testdata/gocritic_inportShadow.yml
================================================
version: "2"
linters:
settings:
gocritic:
disable-all: true
enabled-checks:
- importShadow
================================================
FILE: pkg/golinters/gocritic/testdata/ruleguard/README.md
================================================
This directory contains ruleguard files that are used in functional tests.
Helpful:
- https://go-critic.com/overview.html
- https://github.com/go-critic/go-critic/blob/HEAD/checkers/rules/rules.go
================================================
FILE: pkg/golinters/gocritic/testdata/ruleguard/preferWriteString.go
================================================
//go:build ruleguard
package ruleguard
import "github.com/quasilyte/go-ruleguard/dsl"
func preferWriteString(m dsl.Matcher) {
m.Match(`$w.Write([]byte($s))`).
Where(m["w"].Type.Implements("io.StringWriter")).
Suggest("$w.WriteString($s)").
Report(`$w.WriteString($s) should be preferred to the $$`)
}
================================================
FILE: pkg/golinters/gocritic/testdata/ruleguard/rangeExprCopy.go
================================================
//go:build ruleguard
package ruleguard
import (
"github.com/quasilyte/go-ruleguard/dsl"
)
func rangeExprCopy(m dsl.Matcher) {
m.Match(`for _, $_ := range $x { $*_ }`, `for _, $_ = range $x { $*_ }`).
Where(m["x"].Addressable && m["x"].Type.Size >= 512).
Report(`$x copy can be avoided with &$x`).
At(m["x"]).
Suggest(`&$x`)
}
================================================
FILE: pkg/golinters/gocritic/testdata/ruleguard/stringsSimplify.go
================================================
//go:build ruleguard
package ruleguard
import "github.com/quasilyte/go-ruleguard/dsl"
func stringsSimplify(m dsl.Matcher) {
// Some issues have simple fixes that can be expressed as
// a replacement pattern. Rules can use Suggest() function
// to add a quickfix action for such issues.
m.Match(`strings.Replace($s, $old, $new, -1)`).
Report(`this Replace call can be simplified`).
Suggest(`strings.ReplaceAll($s, $old, $new)`)
// Suggest() can be used without Report().
// It'll print the suggested template to the user.
m.Match(`strings.Count($s1, $s2) == 0`).
Suggest(`!strings.Contains($s1, $s2)`)
}
================================================
FILE: pkg/golinters/gocyclo/gocyclo.go
================================================
package gocyclo
import (
"fmt"
"sync"
"github.com/fzipp/gocyclo"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gocyclo"
func New(settings *config.GoCycloSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []*goanalysis.Issue
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: "Computes and checks the cyclomatic complexity of functions",
Run: func(pass *analysis.Pass) (any, error) {
issues := runGoCyclo(pass, settings)
if len(issues) == 0 {
return nil, nil
}
mu.Lock()
resIssues = append(resIssues, issues...)
mu.Unlock()
return nil, nil
},
}).
WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
return resIssues
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func runGoCyclo(pass *analysis.Pass, settings *config.GoCycloSettings) []*goanalysis.Issue {
var stats gocyclo.Stats
for _, f := range pass.Files {
stats = gocyclo.AnalyzeASTFile(f, pass.Fset, stats)
}
if len(stats) == 0 {
return nil
}
stats = stats.SortAndFilter(-1, settings.MinComplexity)
issues := make([]*goanalysis.Issue, 0, len(stats))
for _, s := range stats {
text := fmt.Sprintf("cyclomatic complexity %d of func %s is high (> %d)",
s.Complexity, internal.FormatCode(s.FuncName), settings.MinComplexity)
issues = append(issues, goanalysis.NewIssue(&result.Issue{
Pos: s.Pos,
Text: text,
FromLinter: linterName,
}, pass))
}
return issues
}
================================================
FILE: pkg/golinters/gocyclo/gocyclo_integration_test.go
================================================
package gocyclo
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gocyclo/testdata/gocyclo.go
================================================
//golangcitest:args -Egocyclo
//golangcitest:config_path testdata/gocyclo.yml
package testdata
import "net/http"
func GocycloBigComplexity(s string) { // want "cyclomatic complexity .* of func .* is high .*"
if s == http.MethodGet || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
}
================================================
FILE: pkg/golinters/gocyclo/testdata/gocyclo.yml
================================================
version: "2"
linters:
settings:
gocyclo:
min-complexity: 20
================================================
FILE: pkg/golinters/gocyclo/testdata/gocyclo_cgo.go
================================================
//golangcitest:args -Egocyclo
//golangcitest:config_path testdata/gocyclo.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"net/http"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _(s string) { // want "cyclomatic complexity .* of func .* is high .*"
if s == http.MethodGet || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
if s == "1" || s == "2" || s == "3" || s == "4" || s == "5" || s == "6" || s == "7" {
return
}
}
================================================
FILE: pkg/golinters/godoclint/godoclint.go
================================================
package godoclint
import (
"errors"
"fmt"
"slices"
glcompose "github.com/godoc-lint/godoc-lint/pkg/compose"
glconfig "github.com/godoc-lint/godoc-lint/pkg/config"
"github.com/godoc-lint/godoc-lint/pkg/model"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.GodoclintSettings) *goanalysis.Linter {
var pcfg glconfig.PlainConfig
if settings != nil {
err := checkSettings(settings)
if err != nil {
internal.LinterLogger.Fatalf("godoclint: %v", err)
}
// The following options are explicitly ignored: they must be handled globally with exclusions or nolint directives.
// - Include
// - Exclude
// The following options are explicitly ignored: these options cannot work as expected because the global configuration about tests.
// - Options.MaxLenIncludeTests
// - Options.PkgDocIncludeTests
// - Options.SinglePkgDocIncludeTests
// - Options.RequirePkgDocIncludeTests
// - Options.RequireDocIncludeTests
// - Options.StartWithNameIncludeTests
// - Options.NoUnusedLinkIncludeTests
// - Options.RequireStdlibDoclinkIncludeTests
// Also, Options.MaxLenIgnorePatterns is ignored because the Golangci-lint's idiomatic way to ignore such issues
// is exclusion by source text patterns.
pcfg = glconfig.PlainConfig{
Default: settings.Default,
Enable: settings.Enable,
Disable: settings.Disable,
Options: &glconfig.PlainRuleOptions{
MaxLenLength: settings.Options.MaxLen.Length,
MaxLenIncludeTests: pointer(true),
MaxLenIgnorePatterns: []string{`^\+kubebuilder:`},
PkgDocIncludeTests: pointer(false),
SinglePkgDocIncludeTests: pointer(true),
RequirePkgDocIncludeTests: pointer(false),
RequireDocIncludeTests: pointer(true),
RequireDocIgnoreExported: settings.Options.RequireDoc.IgnoreExported,
RequireDocIgnoreUnexported: settings.Options.RequireDoc.IgnoreUnexported,
StartWithNameIncludeTests: pointer(false),
StartWithNameIncludeUnexported: settings.Options.StartWithName.IncludeUnexported,
RequireStdlibDoclinkIncludeTests: pointer(true),
NoUnusedLinkIncludeTests: pointer(true),
},
}
if err := pcfg.Validate(); err != nil {
internal.LinterLogger.Fatalf("godoclint: %v", err)
}
}
composition := glcompose.Compose(glcompose.CompositionConfig{
BaseDirPlainConfig: &pcfg,
ExitFunc: func(_ int, err error) {
internal.LinterLogger.Errorf("godoclint: %v", err)
},
})
return goanalysis.
NewLinterFromAnalyzer(composition.Analyzer.GetAnalyzer()).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func checkSettings(settings *config.GodoclintSettings) error {
switch deref(settings.Default) {
case string(model.DefaultSetAll):
if len(settings.Enable) > 0 {
return errors.New("cannot use 'enable' with 'default=all'")
}
case string(model.DefaultSetNone):
if len(settings.Disable) > 0 {
return errors.New("cannot use 'disable' with 'default=none'")
}
default:
for _, rule := range settings.Enable {
if slices.Contains(settings.Disable, rule) {
return fmt.Errorf("a rule cannot be enabled and disabled at the same time: '%s'", rule)
}
}
for _, rule := range settings.Disable {
if slices.Contains(settings.Enable, rule) {
return fmt.Errorf("a rule cannot be enabled and disabled at the same time: '%s'", rule)
}
}
}
return nil
}
func pointer[T any](v T) *T { return &v }
func deref[T any](v *T) T {
if v == nil {
var zero T
return zero
}
return *v
}
================================================
FILE: pkg/golinters/godoclint/godoclint_integration_test.go
================================================
package godoclint
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/godoclint/testdata/godoclint.yml
================================================
version: "2"
linters:
settings:
godoclint:
default: none
enable:
- pkg-doc
- require-pkg-doc
- start-with-name
- require-doc
- deprecated
- max-len
- no-unused-link
- require-stdlib-doclink
options:
start-with-name:
include-unexported: true
require-doc:
ignore-exported: false
ignore-unexported: false
max-len:
length: 127
================================================
FILE: pkg/golinters/godoclint/testdata/godoclint_default_fail.go
================================================
//golangcitest:args -Egodoclint
// bad godoc // want `package godoc should start with "Package testdata "`
package testdata
// This is a special stdlib import because the package itself has issues that
// godoclint can, but must not, detect.
import "go/ast"
// bad godoc // want `godoc should start with symbol name \("FooType"\)`
type FooType struct{}
// bad godoc // want `godoc should start with symbol name \("FooAlias"\)`
type FooAlias = ast.Comment
// bad godoc // want `godoc should start with symbol name \("FooConst"\)`
const FooConst = 1
// bad godoc // want `godoc should start with symbol name \("FooVar"\)`
var FooVar = 1
// bad godoc // want `godoc should start with symbol name \("FooFunc"\)`
func FooFunc() {}
// bad godoc // want `godoc should start with symbol name \("FooFunc"\)`
func (FooType) FooFunc() {}
// DeprecatedConstA is... // want `deprecation note should be formatted as "Deprecated: "`
//
// DEPRECATED: do not use
const DeprecatedConstA = 1
// DeprecatedConstB is... // want `deprecation note should be formatted as "Deprecated: "`
//
// DEPRECATED:do not use
const DeprecatedConstB = 1
// DeprecatedConstC is... // want `deprecation note should be formatted as "Deprecated: "`
//
// deprecated:do not use
const DeprecatedConstC = 1
================================================
FILE: pkg/golinters/godoclint/testdata/godoclint_default_pass.go
================================================
//golangcitest:args -Egodoclint
//golangcitest:expected_exitcode 0
// Package testdata has good godoc.
package testdata
// This is a special stdlib import because the package itself has issues that
// godoclint can, but must not, detect.
import "go/ast"
// FooType is a type.
type FooType struct{}
// FooAlias is an alias.
type FooAlias = ast.Comment
// FooConst is a constant.
const FooConst = 1
// FooVar is a variable.
var FooVar = 1
// FooFunc is a function.
func FooFunc() {}
// FooFunc is a method.
func (FooType) FooFunc() {}
// bad godoc on unexported symbol
type fooType struct{}
// bad godoc on unexported symbol
type fooAlias = ast.Comment
// bad godoc on unexported symbol
const fooConst = 1
// bad godoc on unexported symbol
var fooVar = 1
// bad godoc on unexported symbol
func fooFunc() {}
// bad godoc on unexported symbol
func (FooType) fooFunc() {}
// DeprecatedConstA is...
//
// Deprecated: do not use
const DeprecatedConstA = 1
// Deprecated: do not use
const DeprecatedConstB = 1
// deprecatedConstC is...
//
// DEPRECATED: invalid deprecation note but okay since the symbol is not exported
const deprecatedConstC = 1
// constWithStdlibDoclink has a potential doc link to encoding/json.Encoder but
// should be ignored since the rule is not enabled by default.
const constWithStdlibDoclink = 1
================================================
FILE: pkg/golinters/godoclint/testdata/godoclint_full_fail.go
================================================
//golangcitest:args -Egodoclint
//golangcitest:config_path testdata/godoclint.yml
// Asserting rule "pkg-doc"
// bad godoc // want `package godoc should start with "Package testdata "`
package testdata
// This is a special stdlib import because the package itself has issues that
// godoclint can, but must not, detect.
import "go/ast"
// Asserting rule "start-with-name"
// bad godoc // want `godoc should start with symbol name \("FooType"\)`
type FooType struct{}
// bad godoc // want `godoc should start with symbol name \("FooAlias"\)`
type FooAlias = ast.Comment
// bad godoc // want `godoc should start with symbol name \("FooConst"\)`
const FooConst = 1
// bad godoc // want `godoc should start with symbol name \("FooVar"\)`
var FooVar = 1
// bad godoc // want `godoc should start with symbol name \("FooFunc"\)`
func FooFunc() {}
// bad godoc // want `godoc should start with symbol name \("FooFunc"\)`
func (FooType) FooFunc() {}
// bad godoc // want `godoc should start with symbol name \("fooType"\)`
type fooType struct{}
// bad godoc // want `godoc should start with symbol name \("fooAlias"\)`
type fooAlias = ast.Comment
// bad godoc // want `godoc should start with symbol name \("fooConst"\)`
const fooConst = 1
// bad godoc // want `godoc should start with symbol name \("fooVar"\)`
var fooVar = 1
// bad godoc // want `godoc should start with symbol name \("fooFunc"\)`
func fooFunc() {}
// bad godoc // want `godoc should start with symbol name \("fooFunc"\)`
func (FooType) fooFunc() {}
// Asserting rule "require-doc"
// The //foo:bar directives mark the trailing comment as a directive so they're
// not parsed as a normal trailing comment group.
type BarType struct{} //foo:bar // want `symbol should have a godoc \("BarType"\)`
type BarAlias = ast.Comment //foo:bar // want `symbol should have a godoc \("BarAlias"\)`
const BarConst = 1 //foo:bar // want `symbol should have a godoc \("BarConst"\)`
var BarVar = 1 //foo:bar // want `symbol should have a godoc \("BarVar"\)`
func BarFunc() {} //foo:bar // want `symbol should have a godoc \("BarFunc"\)`
func (BarType) BarFunc() {} //foo:bar // want `symbol should have a godoc \("BarFunc"\)`
type barType struct{} //foo:bar // want `symbol should have a godoc \("barType"\)`
type barAlias = ast.Comment //foo:bar // want `symbol should have a godoc \("barAlias"\)`
const barConst = 1 //foo:bar // want `symbol should have a godoc \("barConst"\)`
var barVar = 1 //foo:bar // want `symbol should have a godoc \("barVar"\)`
func barFunc() {} //foo:bar // want `symbol should have a godoc \("barFunc"\)`
func (BarType) barFunc() {} //foo:bar // want `symbol should have a godoc \("barFunc"\)`
// Asserting rule "no-unused-link"
// constWithUnusedLink point to [used] and unused links. // want `godoc has unused link \("unused"\)`
//
// [used]: https://example.com
//
// [unused]: https://example.com
const constWithUnusedLink = 1
// Asserting rule "max-len"
// constWithTooLongGodoc has a very long godoc that exceeds the maximum allowed length for godoc comments in this test setup. // want `godoc line is too long \(169 > 127\)`
const constWithTooLongGodoc = 1
// DeprecatedConstA is... // want `deprecation note should be formatted as "Deprecated: "`
//
// DEPRECATED: do not use
const DeprecatedConstA = 1
// DeprecatedConstB is... // want `deprecation note should be formatted as "Deprecated: "`
//
// DEPRECATED:do not use
const DeprecatedConstB = 1
// DeprecatedConstC is... // want `deprecation note should be formatted as "Deprecated: "`
//
// deprecated:do not use
const DeprecatedConstC = 1
// constWithStdlibDoclink has a potential doc link to encoding/json.Encoder. // want `text "encoding/json\.Encoder" should be replaced with "\[encoding/json\.Encoder\]" to link to stdlib type`
//
//godoclint:disable max-len
const constWithStdlibDoclink = 1
================================================
FILE: pkg/golinters/godoclint/testdata/godoclint_full_pass.go
================================================
//golangcitest:args -Egodoclint
//golangcitest:config_path testdata/godoclint.yml
//golangcitest:expected_exitcode 0
// Asserting rule "pkg-doc" and "require-pkg-doc" since the package has a godoc.
// Package testdata
package testdata
// This is a special stdlib import because the package itself has issues that
// godoclint can, but must not, detect.
import "go/ast"
// Asserting rule "start-with-name" and "require-doc" (since all have godocs)
// FooType is...
type FooType struct{}
// FooAlias is...
type FooAlias = ast.Comment
// FooConst is...
const FooConst = 1
// FooVar is...
var FooVar = 1
// FooFunc is...
func FooFunc() {}
// FooFunc is...
func (FooType) FooFunc() {}
// fooType is...
type fooType struct{}
// fooAlias is...
type fooAlias = ast.Comment
// fooConst is...
const fooConst = 1
// fooVar is...
var fooVar = 1
// fooFunc is...
func fooFunc() {}
// fooFunc is...
func (FooType) fooFunc() {}
// Asserting rule "no-unused-link"
// constWithUnusedLink point to a [used] link and has no unused one.
//
// [used]: https://example.com
const constWithUnusedLink = 1
// Asserting rule "max-len"
// constWithTooLongGodoc has a very long godoc that does not exceed the maximum allowed length for godoc comments.
const constWithTooLongGodoc = 1
// DeprecatedConstA is...
//
// Deprecated: do not use
const DeprecatedConstA = 1
// Deprecated: do not use
const DeprecatedConstB = 1
// deprecatedConstC is...
//
// DEPRECATED: invalid deprecation note but okay since the symbol is not exported
const deprecatedConstC = 1
// constWithStdlibDoclink has a doc link to [encoding/json.Encoder].
const constWithStdlibDoclink = 1
================================================
FILE: pkg/golinters/godoclint/testdata/godoclint_full_pass_test.go
================================================
//golangcitest:args -Egodoclint
//golangcitest:config_path testdata/godoclint.yml
//golangcitest:expected_exitcode 0
// Asserting rule "pkg-doc" and "require-pkg-doc" since the package has a godoc.
// Package testdata
package testdata
// This is a special stdlib import because the package itself has issues that
// godoclint can, but must not, detect.
import "go/ast"
// Asserting rule "start-with-name" and "require-doc" (since all have godocs)
// FooType is...
type FooType struct{}
// FooAlias is...
type FooAlias = ast.Comment
// FooConst is...
const FooConst = 1
// FooVar is...
var FooVar = 1
// FooFunc is...
func FooFunc() {}
// FooFunc is...
func (FooType) FooFunc() {}
// fooType is...
type fooType struct{}
// fooAlias is...
type fooAlias = ast.Comment
// fooConst is...
const fooConst = 1
// fooVar is...
var fooVar = 1
// fooFunc is...
func fooFunc() {}
// fooFunc is...
func (FooType) fooFunc() {}
// Asserting rule "no-unused-link"
// constWithUnusedLink point to a [used] link and has no unused one.
//
// [used]: https://example.com
const constWithUnusedLink = 1
// Asserting rule "max-len"
// constWithTooLongGodoc has a very long godoc that does not exceed the maximum allowed length for godoc comments.
const constWithTooLongGodoc = 1
// DeprecatedConstA is...
//
// Deprecated: do not use
const DeprecatedConstA = 1
// Deprecated: do not use
const DeprecatedConstB = 1
// constWithStdlibDoclink has a doc link to [encoding/json.Encoder].
const constWithStdlibDoclink = 1
================================================
FILE: pkg/golinters/godot/godot.go
================================================
package godot
import (
"cmp"
"github.com/tetafro/godot"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.GodotSettings) *goanalysis.Linter {
var dotSettings godot.Settings
if settings != nil {
dotSettings = godot.Settings{
Scope: godot.Scope(settings.Scope),
Exclude: settings.Exclude,
Period: settings.Period,
Capital: settings.Capital,
}
}
dotSettings.Scope = cmp.Or(dotSettings.Scope, godot.DeclScope)
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: "godot",
Doc: "Check if comments end in a period",
Run: func(pass *analysis.Pass) (any, error) {
err := runGodot(pass, dotSettings)
if err != nil {
return nil, err
}
return nil, nil
},
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func runGodot(pass *analysis.Pass, settings godot.Settings) error {
for _, file := range pass.Files {
iss, err := godot.Run(file, pass.Fset, settings)
if err != nil {
return err
}
if len(iss) == 0 {
continue
}
f := pass.Fset.File(file.Pos())
for _, i := range iss {
start := f.Pos(i.Pos.Offset)
end := goanalysis.EndOfLinePos(f, i.Pos.Line)
pass.Report(analysis.Diagnostic{
Pos: start,
End: end,
Message: i.Message,
SuggestedFixes: []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: start,
End: end,
NewText: []byte(i.Replacement),
}},
}},
})
}
}
return nil
}
================================================
FILE: pkg/golinters/godot/godot_integration_test.go
================================================
package godot
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/godot/testdata/fix/in/godot.go
================================================
//golangcitest:args -Egodot
//golangcitest:expected_exitcode 0
package p
/*
This comment won't be checked in default mode
*/
// This comment will be fixed
func godot(a, b int) int {
// Nothing to do here
return a + b
}
// Foo Lorem ipsum dolor sit amet, consectetur adipiscing elit.
// Aenean rhoncus odio enim, et pulvinar libero ultrices quis.
// Nulla at erat tellus. Maecenas id dapibus velit, ut porttitor ipsum
func Foo() {
// nothing to do here
}
================================================
FILE: pkg/golinters/godot/testdata/fix/out/godot.go
================================================
//golangcitest:args -Egodot
//golangcitest:expected_exitcode 0
package p
/*
This comment won't be checked in default mode
*/
// This comment will be fixed.
func godot(a, b int) int {
// Nothing to do here
return a + b
}
// Foo Lorem ipsum dolor sit amet, consectetur adipiscing elit.
// Aenean rhoncus odio enim, et pulvinar libero ultrices quis.
// Nulla at erat tellus. Maecenas id dapibus velit, ut porttitor ipsum.
func Foo() {
// nothing to do here
}
================================================
FILE: pkg/golinters/godot/testdata/godot.go
================================================
//golangcitest:args -Egodot
package testdata
// want +2 "Comment should end in a period"
// Godot checks top-level comments
func Godot() {
// nothing to do here
}
// want +4 "Comment should end in a period"
// Foo Lorem ipsum dolor sit amet, consectetur adipiscing elit.
// Aenean rhoncus odio enim, et pulvinar libero ultrices quis.
// Nulla at erat tellus. Maecenas id dapibus velit, ut porttitor ipsum
func Foo() {
// nothing to do here
}
================================================
FILE: pkg/golinters/godot/testdata/godot_cgo.go
================================================
//golangcitest:args -Egodot
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
// want +2 "Comment should end in a period"
// Godot checks top-level comments
func Godot() {
// nothing to do here
}
================================================
FILE: pkg/golinters/godox/godox.go
================================================
package godox
import (
"go/token"
"strings"
"github.com/matoous/godox"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.GodoxSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: "godox",
Doc: "Detects usage of FIXME, TODO and other keywords inside comments",
Run: func(pass *analysis.Pass) (any, error) {
return run(pass, settings), nil
},
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func run(pass *analysis.Pass, settings *config.GodoxSettings) error {
for _, file := range pass.Files {
position, isGoFile := goanalysis.GetGoFilePosition(pass, file)
if !isGoFile {
continue
}
messages, err := godox.Run(file, pass.Fset, settings.Keywords...)
if err != nil {
return err
}
if len(messages) == 0 {
continue
}
nonAdjPosition := pass.Fset.PositionFor(file.Pos(), false)
ft := pass.Fset.File(file.Pos())
for _, i := range messages {
msg := strings.TrimRight(i.Message, "\n")
// https://github.com/matoous/godox/blob/1d6ac9d899726279072e1c4d2b10f1eb52f22878/godox.go#L56
index := strings.Index(msg, "Line contains")
pass.Report(analysis.Diagnostic{
Pos: ft.LineStart(goanalysis.AdjustPos(i.Pos.Line, nonAdjPosition.Line, position.Line)) + token.Pos(i.Pos.Column),
Message: msg[index:],
})
}
}
return nil
}
================================================
FILE: pkg/golinters/godox/godox_integration_test.go
================================================
package godox
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/godox/testdata/godox.go
================================================
//golangcitest:args -Egodox
//golangcitest:config_path testdata/godox.yml
package testdata
func todoLeftInCode() {
// TODO implement me // want `Line contains FIXME/TODO: "TODO implement me`
//TODO no space // want `Line contains FIXME/TODO: "TODO no space`
// TODO(author): 123 // want `Line contains FIXME/TODO: "TODO\(author\): 123`
//TODO(author): 123 // want `Line contains FIXME/TODO: "TODO\(author\): 123`
//TODO(author) 456 // want `Line contains FIXME/TODO: "TODO\(author\) 456`
// TODO: qwerty // want `Line contains FIXME/TODO: "TODO: qwerty`
// todo 789 // want `Line contains FIXME/TODO: "todo 789`
}
================================================
FILE: pkg/golinters/godox/testdata/godox.yml
================================================
version: "2"
linters:
settings:
godox:
keywords:
- FIXME
- TODO
================================================
FILE: pkg/golinters/godox/testdata/godox_cgo.go
================================================
//golangcitest:args -Egodox
//golangcitest:config_path testdata/godox.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func todoLeftInCode() {
// TODO implement me // want `Line contains FIXME/TODO: "TODO implement me`
//TODO no space // want `Line contains FIXME/TODO: "TODO no space`
// TODO(author): 123 // want `Line contains FIXME/TODO: "TODO\(author\): 123`
//TODO(author): 123 // want `Line contains FIXME/TODO: "TODO\(author\): 123`
//TODO(author) 456 // want `Line contains FIXME/TODO: "TODO\(author\) 456`
// TODO: qwerty // want `Line contains FIXME/TODO: "TODO: qwerty`
// todo 789 // want `Line contains FIXME/TODO: "todo 789`
}
================================================
FILE: pkg/golinters/gofmt/gofmt.go
================================================
package gofmt
import (
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
gofmtbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.GoFmtSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(
goformatters.NewAnalyzer(
internal.LinterLogger.Child(gofmtbase.Name),
"Check if the code is formatted according to 'gofmt' command.",
gofmtbase.New(settings),
),
).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/gofmt/gofmt_integration_test.go
================================================
package gofmt
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/gofmt/testdata/fix/in/gofmt.go
================================================
//golangcitest:config_path testdata/gofmt.yml
//golangcitest:expected_exitcode 0
package p
func gofmt(a, b int) int {
if a != b {
return 1
}
return 2
}
================================================
FILE: pkg/golinters/gofmt/testdata/fix/in/gofmt_rewrite_rules.go
================================================
//golangcitest:config_path testdata/gofmt_rewrite_rules.yml
//golangcitest:expected_exitcode 0
package p
import "fmt"
func GofmtRewriteRule() {
values := make([]int, 0)
values = append(values, 1)
values = append(values, 2)
values = append(values, 3)
slice := values[1:len(values)]
fmt.Println(slice)
}
func GofmtRewriteRule2() {
var to interface{}
fmt.Println(to)
}
================================================
FILE: pkg/golinters/gofmt/testdata/fix/out/gofmt.go
================================================
//golangcitest:config_path testdata/gofmt.yml
//golangcitest:expected_exitcode 0
package p
func gofmt(a, b int) int {
if a != b {
return 1
}
return 2
}
================================================
FILE: pkg/golinters/gofmt/testdata/fix/out/gofmt_rewrite_rules.go
================================================
//golangcitest:config_path testdata/gofmt_rewrite_rules.yml
//golangcitest:expected_exitcode 0
package p
import "fmt"
func GofmtRewriteRule() {
values := make([]int, 0)
values = append(values, 1)
values = append(values, 2)
values = append(values, 3)
slice := values[1:]
fmt.Println(slice)
}
func GofmtRewriteRule2() {
var to any
fmt.Println(to)
}
================================================
FILE: pkg/golinters/gofmt/testdata/gofmt.go
================================================
//golangcitest:config_path testdata/gofmt.yml
package testdata
import "fmt"
func GofmtNotSimplified() {
var x []string
fmt.Print(x[1:len(x)]) // want "File is not properly formatted"
}
================================================
FILE: pkg/golinters/gofmt/testdata/gofmt.yml
================================================
version: "2"
formatters:
enable:
- gofmt
================================================
FILE: pkg/golinters/gofmt/testdata/gofmt_cgo.go
================================================
//golangcitest:config_path testdata/gofmt.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func GofmtNotSimplified() {
var x []string
fmt.Print(x[1:len(x)]) // want "File is not properly formatted"
}
================================================
FILE: pkg/golinters/gofmt/testdata/gofmt_no_simplify.go
================================================
//golangcitest:config_path testdata/gofmt_no_simplify.yml
package testdata
import "fmt"
func GofmtNotSimplifiedOk() {
var x []string
fmt.Print(x[1:len(x)])
}
func GofmtBadFormat(){ // want "File is not properly formatted"
}
================================================
FILE: pkg/golinters/gofmt/testdata/gofmt_no_simplify.yml
================================================
version: "2"
formatters:
enable:
- gofmt
settings:
gofmt:
simplify: false
================================================
FILE: pkg/golinters/gofmt/testdata/gofmt_rewrite_rules.go
================================================
//golangcitest:config_path testdata/gofmt_rewrite_rules.yml
package testdata
import "fmt"
func GofmtRewriteRule() {
vals := make([]int, 0)
vals = append(vals, 1)
vals = append(vals, 2)
vals = append(vals, 3)
slice := vals[1:len(vals)] // want "File is not properly formatted"
fmt.Println(slice)
}
================================================
FILE: pkg/golinters/gofmt/testdata/gofmt_rewrite_rules.yml
================================================
version: "2"
formatters:
enable:
- gofmt
settings:
gofmt:
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
- pattern: 'a[b:len(a)]'
replacement: 'a[b:]'
================================================
FILE: pkg/golinters/gofmt/testdata/gofmt_too_many_empty_lines.go
================================================
//golangcitest:config_path testdata/gofmt.yml
package testdata
import "fmt"
// want +4 "File is not properly formatted"
func _() {
fmt.Println("foo")
}
================================================
FILE: pkg/golinters/gofumpt/gofumpt.go
================================================
package gofumpt
import (
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
gofumptbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.GoFumptSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(
goformatters.NewAnalyzer(
internal.LinterLogger.Child(gofumptbase.Name),
"Check if code and import statements are formatted, with additional rules.",
gofumptbase.New(settings, settings.LangVersion),
),
).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/gofumpt/gofumpt_integration_test.go
================================================
package gofumpt
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/gofumpt/testdata/fix/in/gofumpt.go
================================================
//golangcitest:config_path testdata/gofumpt-fix.yml
//golangcitest:expected_exitcode 0
package p
import "fmt"
func GofmtNotExtra(bar string, baz string) {
fmt.Print(bar, baz)
}
================================================
FILE: pkg/golinters/gofumpt/testdata/fix/in/gofumpt_cgo.go
================================================
//golangcitest:config_path testdata/gofumpt-fix.yml
//golangcitest:expected_exitcode 0
package p
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import "fmt"
func GofmtNotExtra(bar string, baz string) {
fmt.Print(bar, baz)
}
================================================
FILE: pkg/golinters/gofumpt/testdata/fix/out/gofumpt.go
================================================
//golangcitest:config_path testdata/gofumpt-fix.yml
//golangcitest:expected_exitcode 0
package p
import "fmt"
func GofmtNotExtra(bar, baz string) {
fmt.Print(bar, baz)
}
================================================
FILE: pkg/golinters/gofumpt/testdata/fix/out/gofumpt_cgo.go
================================================
//golangcitest:config_path testdata/gofumpt-fix.yml
//golangcitest:expected_exitcode 0
package p
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import "fmt"
func GofmtNotExtra(bar, baz string) {
fmt.Print(bar, baz)
}
================================================
FILE: pkg/golinters/gofumpt/testdata/gofumpt-fix.yml
================================================
version: "2"
formatters:
enable:
- gofumpt
settings:
gofumpt:
extra-rules: true
================================================
FILE: pkg/golinters/gofumpt/testdata/gofumpt.go
================================================
//golangcitest:config_path testdata/gofumpt.yml
package testdata
import "fmt"
func GofumptNewLine() {
fmt.Println( "foo" ) // want "File is not properly formatted"
}
================================================
FILE: pkg/golinters/gofumpt/testdata/gofumpt.yml
================================================
version: "2"
formatters:
enable:
- gofumpt
================================================
FILE: pkg/golinters/gofumpt/testdata/gofumpt_cgo.go
================================================
//golangcitest:config_path testdata/gofumpt.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func GofumptNewLine() {
fmt.Println( "foo" ) // want "File is not properly formatted"
}
================================================
FILE: pkg/golinters/gofumpt/testdata/gofumpt_too_many_empty_lines.go
================================================
//golangcitest:config_path testdata/gofumpt.yml
package testdata
import "fmt"
// want +4 "File is not properly formatted"
func _() {
fmt.Println("foo")
}
================================================
FILE: pkg/golinters/gofumpt/testdata/gofumpt_with_extra.go
================================================
//golangcitest:config_path testdata/gofumpt_with_extra.yml
package testdata
import "fmt"
func GofmtNotExtra(bar string, baz string) { // want "File is not properly formatted"
fmt.Print("foo")
}
================================================
FILE: pkg/golinters/gofumpt/testdata/gofumpt_with_extra.yml
================================================
version: "2"
formatters:
enable:
- gofumpt
settings:
gofumpt:
extra-rules: true
================================================
FILE: pkg/golinters/goheader/goheader.go
================================================
package goheader
import (
"go/token"
"strings"
goheader "github.com/denis-tingaikin/go-header"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "goheader"
func New(settings *config.GoHeaderSettings, replacer *strings.Replacer) *goanalysis.Linter {
conf := &goheader.Configuration{}
if settings != nil {
conf = &goheader.Configuration{
Values: settings.Values,
Template: settings.Template,
TemplatePath: replacer.Replace(settings.TemplatePath),
}
}
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: "Check if file header matches to pattern",
Run: func(pass *analysis.Pass) (any, error) {
err := runGoHeader(pass, conf)
if err != nil {
return nil, err
}
return nil, nil
},
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func runGoHeader(pass *analysis.Pass, conf *goheader.Configuration) error {
if conf.TemplatePath == "" && conf.Template == "" {
// User did not pass template, so then do not run go-header linter
return nil
}
template, err := conf.GetTemplate()
if err != nil {
return err
}
values, err := conf.GetValues()
if err != nil {
return err
}
a := goheader.New(goheader.WithTemplate(template), goheader.WithValues(values))
for _, file := range pass.Files {
position, isGoFile := goanalysis.GetGoFilePosition(pass, file)
if !isGoFile {
continue
}
issue := a.Analyze(&goheader.Target{File: file, Path: position.Filename})
if issue == nil {
continue
}
f := pass.Fset.File(file.Pos())
commentLine := 1
var offset int
// Inspired by https://github.com/denis-tingaikin/go-header/blob/4c75a6a2332f025705325d6c71fff4616aedf48f/analyzer.go#L85-L92
if len(file.Comments) > 0 && file.Comments[0].Pos() < file.Package {
if !strings.HasPrefix(file.Comments[0].List[0].Text, "/*") {
// When the comment is "//" there is a one character offset.
offset = 1
}
commentLine = goanalysis.GetFilePositionFor(pass.Fset, file.Comments[0].Pos()).Line
}
// Skip issues related to build directives.
// https://github.com/denis-tingaikin/go-header/issues/18
if issue.Location().Position-offset < 0 {
continue
}
diag := analysis.Diagnostic{
Pos: f.LineStart(issue.Location().Line+1) + token.Pos(issue.Location().Position-offset), // The position of the first divergence.
Message: issue.Message(),
}
if fix := issue.Fix(); fix != nil {
current := len(fix.Actual)
for _, s := range fix.Actual {
current += len(s)
}
start := f.LineStart(commentLine)
end := start + token.Pos(current)
header := strings.Join(fix.Expected, "\n") + "\n"
// Adds an extra line between the package and the header.
if end == file.Package {
header += "\n"
}
diag.SuggestedFixes = []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: start,
End: end,
NewText: []byte(header),
}},
}}
}
pass.Report(diag)
}
return nil
}
================================================
FILE: pkg/golinters/goheader/goheader_integration_test.go
================================================
package goheader
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/goheader/testdata/fix/in/goheader_1.go
================================================
// Copyright 1999 The Awesome Project Authors
//golangcitest:args -Egoheader
//golangcitest:expected_exitcode 0
//golangcitest:config_path testdata/goheader-fix.yml
package p
================================================
FILE: pkg/golinters/goheader/testdata/fix/in/goheader_2.go
================================================
/* Copyright 1999 The Awesome Project Authors
Use of this source code is governed */
//golangcitest:args -Egoheader
//golangcitest:expected_exitcode 0
//golangcitest:config_path testdata/goheader-fix.yml
package p
================================================
FILE: pkg/golinters/goheader/testdata/fix/in/goheader_3.go
================================================
/*
Copyright 1999 The Awesome
Use of this source code is governed by LICENSE
*/
//golangcitest:args -Egoheader
//golangcitest:expected_exitcode 0
//golangcitest:config_path testdata/goheader-fix.yml
package p
================================================
FILE: pkg/golinters/goheader/testdata/fix/in/goheader_4.go
================================================
/*
Copyright 2024 The Awesome Project Authors
Use of this source code is governed by LICENSE.md
*/
//golangcitest:args -Egoheader
//golangcitest:expected_exitcode 0
//golangcitest:config_path testdata/goheader-fix.yml
package p
================================================
FILE: pkg/golinters/goheader/testdata/fix/out/goheader_1.go
================================================
// Copyright 2024 The Awesome Project Authors
//
// Use of this source code is governed by LICENSE
//golangcitest:args -Egoheader
//golangcitest:expected_exitcode 0
//golangcitest:config_path testdata/goheader-fix.yml
package p
================================================
FILE: pkg/golinters/goheader/testdata/fix/out/goheader_2.go
================================================
/* Copyright 2024 The Awesome Project Authors
Use of this source code is governed by LICENSE */
//golangcitest:args -Egoheader
//golangcitest:expected_exitcode 0
//golangcitest:config_path testdata/goheader-fix.yml
package p
================================================
FILE: pkg/golinters/goheader/testdata/fix/out/goheader_3.go
================================================
/*
Copyright 2024 The Awesome Project Authors
Use of this source code is governed by LICENSE
*/
//golangcitest:args -Egoheader
//golangcitest:expected_exitcode 0
//golangcitest:config_path testdata/goheader-fix.yml
package p
================================================
FILE: pkg/golinters/goheader/testdata/fix/out/goheader_4.go
================================================
/*
Copyright 2024 The Awesome Project Authors
Use of this source code is governed by LICENSE
*/
//golangcitest:args -Egoheader
//golangcitest:expected_exitcode 0
//golangcitest:config_path testdata/goheader-fix.yml
package p
================================================
FILE: pkg/golinters/goheader/testdata/goheader-fix.yml
================================================
version: "2"
linters:
settings:
goheader:
values:
const:
AUTHOR: The Awesome Project Authors
template: |-
Copyright 2024 {{ AUTHOR }}
Use of this source code is governed by LICENSE
================================================
FILE: pkg/golinters/goheader/testdata/goheader.yml
================================================
version: "2"
linters:
settings:
goheader:
template: MY {{title}}
values:
const:
title: TITLE.
================================================
FILE: pkg/golinters/goheader/testdata/goheader_bad.go
================================================
/*MY TITLE!*/ // want `Expected:TITLE\., Actual: TITLE!`
//golangcitest:args -Egoheader
//golangcitest:config_path testdata/goheader.yml
package testdata
================================================
FILE: pkg/golinters/goheader/testdata/goheader_cgo.go
================================================
//go:build ignore
// TODO(ldez) the linter doesn't support cgo.
/*MY TITLE!*/ // want `Expected:TITLE\., Actual: TITLE!`
//golangcitest:args -Egoheader
//golangcitest:config_path testdata/goheader.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
================================================
FILE: pkg/golinters/goheader/testdata/goheader_good.go
================================================
/*MY TITLE.*/
//golangcitest:args -Egoheader
//golangcitest:config_path testdata/goheader.yml
//golangcitest:expected_exitcode 0
package testdata
================================================
FILE: pkg/golinters/goimports/goimports.go
================================================
package goimports
import (
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
goimportsbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.GoImportsSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(
goformatters.NewAnalyzer(
internal.LinterLogger.Child(goimportsbase.Name),
"Checks if the code and import statements are formatted according to the 'goimports' command.",
goimportsbase.New(settings),
),
).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/goimports/goimports_integration_test.go
================================================
package goimports
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/goimports/testdata/fix/in/goimports.go
================================================
//golangcitest:config_path testdata/goimports.yml
//golangcitest:expected_exitcode 0
package p
import (
"os"
"fmt"
)
func goimports(a, b int) int {
if a != b {
return 1
}
return 2
}
================================================
FILE: pkg/golinters/goimports/testdata/fix/in/goimports_cgo.go
================================================
//golangcitest:config_path testdata/goimports.yml
//golangcitest:expected_exitcode 0
package p
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"os"
"fmt"
)
func goimports(a, b int) int {
if a != b {
return 1
}
return 2
}
================================================
FILE: pkg/golinters/goimports/testdata/fix/out/goimports.go
================================================
//golangcitest:config_path testdata/goimports.yml
//golangcitest:expected_exitcode 0
package p
func goimports(a, b int) int {
if a != b {
return 1
}
return 2
}
================================================
FILE: pkg/golinters/goimports/testdata/fix/out/goimports_cgo.go
================================================
//golangcitest:config_path testdata/goimports.yml
//golangcitest:expected_exitcode 0
package p
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
func goimports(a, b int) int {
if a != b {
return 1
}
return 2
}
================================================
FILE: pkg/golinters/goimports/testdata/goimports.go
================================================
//golangcitest:config_path testdata/goimports.yml
package testdata
import (
"fmt" // want "File is not properly formatted"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
func Bar() {
fmt.Print("x")
_ = config.Config{}
}
================================================
FILE: pkg/golinters/goimports/testdata/goimports.yml
================================================
version: "2"
formatters:
enable:
- goimports
================================================
FILE: pkg/golinters/goimports/testdata/goimports_cgo.go
================================================
//golangcitest:config_path testdata/goimports.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe" // want "File is not properly formatted"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func Bar() {
fmt.Print("x")
_ = config.Config{}
}
================================================
FILE: pkg/golinters/goimports/testdata/goimports_local.go
================================================
//golangcitest:config_path testdata/goimports_local.yml
package testdata
import (
"fmt"
"github.com/golangci/golangci-lint/v2/pkg/config" // want "File is not properly formatted"
"golang.org/x/tools/go/analysis"
)
func GoimportsLocalPrefixTest() {
fmt.Print("x")
_ = config.Config{}
_ = analysis.Analyzer{}
}
================================================
FILE: pkg/golinters/goimports/testdata/goimports_local.yml
================================================
version: "2"
formatters:
enable:
- goimports
settings:
goimports:
local-prefixes:
- github.com/golangci/golangci-lint
================================================
FILE: pkg/golinters/golines/golines.go
================================================
package golines
import (
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
golinesbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.GoLinesSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(
goformatters.NewAnalyzer(
internal.LinterLogger.Child(golinesbase.Name),
"Checks if code is formatted, and fixes long lines",
golinesbase.New(settings),
),
).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/golines/golines_integration_test.go
================================================
package golines
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/golines/testdata/fix/in/golines-custom.go
================================================
//golangcitest:config_path testdata/golines-custom.yml
//golangcitest:expected_exitcode 0
package testdata
// the struct tags should not be reformatted here
type Foo struct {
Bar `a:"b=\"c\"" d:"e"`
Baz `a:"f" d:"g"`
}
var (
// this ends at 80 columns with tab size 2, and would only be a little wider
// with tab size 8, not failing the default line-len, so it checks both
// settings are applied properly
abc = []string{"a string that is only wrapped at narrow widths and wide tabs"}
)
================================================
FILE: pkg/golinters/golines/testdata/fix/in/golines.go
================================================
//golangcitest:config_path testdata/golines.yml
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
var (
abc = []string{"a really long string", "another really long string", "a third really long string", "a fourth really long string", fmt.Sprintf("%s %s %s %s >>>>> %s %s", "first argument", "second argument", "third argument", "fourth argument", "fifth argument", "sixth argument")}
)
type MyStruct struct {
aLongProperty int `help:"This is a really long string for this property"`
anotherLongProperty int `help:"This is a really long string for this property, part 2"`
athirdLongProperty int `help:"This is a really long string for this property, part 3...."`
}
type MyInterface interface {
aReallyLongFunctionName(argument1 string, argument2 string, argument3 string, argument4 string, argument5 string, argument6 string) (string, error)
}
// Something here
// Another comment
// A third comment
// This is a really really long comment that needs to be split up into multiple lines. I don't know how easy it will be to do, but I think we can do it!
func longLine(aReallyLongName string, anotherLongName string, aThirdLongName string) (string, error) {
argument1 := "argument1"
argument2 := "argument2"
argument3 := "argument3"
argument4 := "argument4"
fmt.Printf("This is a really long string with a bunch of arguments: %s %s %s %s >>>>>>>>>>>>>>>>>>>>>>", argument1, argument2, argument3, argument4)
fmt.Printf("This is a short statement: %d %d %d", 1, 2, 3)
z := argument1 + argument2 + fmt.Sprintf("This is a really long statement that should be broken up %s %s %s", argument1, argument2, argument3)
fmt.Printf("This is a really long line that can be broken up twice %s %s", fmt.Sprintf("This is a really long sub-line that should be broken up more because %s %s", argument1, argument2), fmt.Sprintf("A short one %d", 3))
fmt.Print("This is a function with a really long single argument. We want to see if it's properly split")
fmt.Println(z)
// This is a really long comment on an indented line. Do you think we can split it up or should we just leave it as is?
if argument4 == "5" {
return "", fmt.Errorf("a very long query with ID %d failed. Check Query History in AWS UI", 12341251)
}
go func() {
fmt.Printf("This is a really long line inside of a go routine call. It should be split if at all possible.")
}()
if "hello this is a big string" == "this is a small string" && "this is another big string" == "this is an even bigger string >>>" {
fmt.Print("inside if statement")
}
fmt.Println(map[string]string{"key1": "a very long value", "key2": "a very long value", "key3": "another very long value"})
return "", nil
}
func shortFunc(a int, b int) error {
c := make(chan int)
for {
select {
case <-c:
switch a {
case 1:
return fmt.Errorf("This is a really long line that can be broken up twice %s %s", fmt.Sprintf("This is a really long sub-line that should be broken up more because %s %s", "xxxx", "yyyy"), fmt.Sprintf("A short one %d", 3))
case 2:
}
}
break
}
if a > 5 {
panic(fmt.Sprintf(">>>>>>>>>>>>>>>>>>> %s %s %s %s", "really long argument", "another really long argument", "a third really long arguement", abc[1:2]))
}
return nil
// This is an end decoration
}
================================================
FILE: pkg/golinters/golines/testdata/fix/out/golines-custom.go
================================================
//golangcitest:config_path testdata/golines-custom.yml
//golangcitest:expected_exitcode 0
package testdata
// the struct tags should not be reformatted here
type Foo struct {
Bar `a:"b=\"c\"" d:"e"`
Baz `a:"f" d:"g"`
}
var (
// this ends at 80 columns with tab size 2, and would only be a little wider
// with tab size 8, not failing the default line-len, so it checks both
// settings are applied properly
abc = []string{
"a string that is only wrapped at narrow widths and wide tabs",
}
)
================================================
FILE: pkg/golinters/golines/testdata/fix/out/golines.go
================================================
//golangcitest:config_path testdata/golines.yml
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
var (
abc = []string{
"a really long string",
"another really long string",
"a third really long string",
"a fourth really long string",
fmt.Sprintf(
"%s %s %s %s >>>>> %s %s",
"first argument",
"second argument",
"third argument",
"fourth argument",
"fifth argument",
"sixth argument",
),
}
)
type MyStruct struct {
aLongProperty int `help:"This is a really long string for this property"`
anotherLongProperty int `help:"This is a really long string for this property, part 2"`
athirdLongProperty int `help:"This is a really long string for this property, part 3...."`
}
type MyInterface interface {
aReallyLongFunctionName(
argument1 string,
argument2 string,
argument3 string,
argument4 string,
argument5 string,
argument6 string,
) (string, error)
}
// Something here
// Another comment
// A third comment
// This is a really really long comment that needs to be split up into multiple lines. I don't know how easy it will be to do, but I think we can do it!
func longLine(
aReallyLongName string,
anotherLongName string,
aThirdLongName string,
) (string, error) {
argument1 := "argument1"
argument2 := "argument2"
argument3 := "argument3"
argument4 := "argument4"
fmt.Printf(
"This is a really long string with a bunch of arguments: %s %s %s %s >>>>>>>>>>>>>>>>>>>>>>",
argument1,
argument2,
argument3,
argument4,
)
fmt.Printf("This is a short statement: %d %d %d", 1, 2, 3)
z := argument1 + argument2 + fmt.Sprintf(
"This is a really long statement that should be broken up %s %s %s",
argument1,
argument2,
argument3,
)
fmt.Printf(
"This is a really long line that can be broken up twice %s %s",
fmt.Sprintf(
"This is a really long sub-line that should be broken up more because %s %s",
argument1,
argument2,
),
fmt.Sprintf("A short one %d", 3),
)
fmt.Print(
"This is a function with a really long single argument. We want to see if it's properly split",
)
fmt.Println(z)
// This is a really long comment on an indented line. Do you think we can split it up or should we just leave it as is?
if argument4 == "5" {
return "", fmt.Errorf(
"a very long query with ID %d failed. Check Query History in AWS UI",
12341251,
)
}
go func() {
fmt.Printf(
"This is a really long line inside of a go routine call. It should be split if at all possible.",
)
}()
if "hello this is a big string" == "this is a small string" &&
"this is another big string" == "this is an even bigger string >>>" {
fmt.Print("inside if statement")
}
fmt.Println(
map[string]string{
"key1": "a very long value",
"key2": "a very long value",
"key3": "another very long value",
},
)
return "", nil
}
func shortFunc(a int, b int) error {
c := make(chan int)
for {
select {
case <-c:
switch a {
case 1:
return fmt.Errorf(
"This is a really long line that can be broken up twice %s %s",
fmt.Sprintf(
"This is a really long sub-line that should be broken up more because %s %s",
"xxxx",
"yyyy",
),
fmt.Sprintf("A short one %d", 3),
)
case 2:
}
}
break
}
if a > 5 {
panic(
fmt.Sprintf(
">>>>>>>>>>>>>>>>>>> %s %s %s %s",
"really long argument",
"another really long argument",
"a third really long arguement",
abc[1:2],
),
)
}
return nil
// This is an end decoration
}
================================================
FILE: pkg/golinters/golines/testdata/golines-custom.yml
================================================
version: "2"
formatters:
enable:
- golines
settings:
golines:
# override many settings
max-len: 80
tab-len: 8
reformat-tags: false
================================================
FILE: pkg/golinters/golines/testdata/golines.go
================================================
//golangcitest:config_path testdata/golines.yml
package testdata
import "fmt"
var (
// want +1 "File is not properly formatted"
abc = []string{"a really long string", "another really long string", "a third really long string", "a fourth really long string", fmt.Sprintf("%s %s %s %s >>>>> %s %s", "first argument", "second argument", "third argument", "fourth argument", "fifth argument", "sixth argument")}
)
type MyStruct struct {
aLongProperty int `help:"This is a really long string for this property"`
anotherLongProperty int `help:"This is a really long string for this property, part 2"`
athirdLongProperty int `help:"This is a really long string for this property, part 3...."`
}
type MyInterface interface {
aReallyLongFunctionName(argument1 string, argument2 string, argument3 string, argument4 string, argument5 string, argument6 string) (string, error)
}
// Something here
// Another comment
// A third comment
// This is a really really long comment that needs to be split up into multiple lines. I don't know how easy it will be to do, but I think we can do it!
func longLine(aReallyLongName string, anotherLongName string, aThirdLongName string) (string, error) {
argument1 := "argument1"
argument2 := "argument2"
argument3 := "argument3"
argument4 := "argument4"
fmt.Printf("This is a really long string with a bunch of arguments: %s %s %s %s >>>>>>>>>>>>>>>>>>>>>>", argument1, argument2, argument3, argument4)
fmt.Printf("This is a short statement: %d %d %d", 1, 2, 3)
z := argument1 + argument2 + fmt.Sprintf("This is a really long statement that should be broken up %s %s %s", argument1, argument2, argument3)
fmt.Printf("This is a really long line that can be broken up twice %s %s", fmt.Sprintf("This is a really long sub-line that should be broken up more because %s %s", argument1, argument2), fmt.Sprintf("A short one %d", 3))
fmt.Print("This is a function with a really long single argument. We want to see if it's properly split")
fmt.Println(z)
// This is a really long comment on an indented line. Do you think we can split it up or should we just leave it as is?
if argument4 == "5" {
return "", fmt.Errorf("a very long query with ID %d failed. Check Query History in AWS UI", 12341251)
}
go func() {
fmt.Printf("This is a really long line inside of a go routine call. It should be split if at all possible.")
}()
if "hello this is a big string" == "this is a small string" && "this is another big string" == "this is an even bigger string >>>" {
fmt.Print("inside if statement")
}
fmt.Println(map[string]string{"key1": "a very long value", "key2": "a very long value", "key3": "another very long value"})
return "", nil
}
func shortFunc(a int, b int) error {
c := make(chan int)
for {
select {
case <-c:
switch a {
case 1:
return fmt.Errorf("This is a really long line that can be broken up twice %s %s", fmt.Sprintf("This is a really long sub-line that should be broken up more because %s %s", "xxxx", "yyyy"), fmt.Sprintf("A short one %d", 3))
case 2:
}
}
break
}
if a > 5 {
panic(fmt.Sprintf(">>>>>>>>>>>>>>>>>>> %s %s %s %s", "really long argument", "another really long argument", "a third really long arguement", abc[1:2]))
}
return nil
// This is an end decoration
}
================================================
FILE: pkg/golinters/golines/testdata/golines.yml
================================================
version: "2"
formatters:
enable:
- golines
================================================
FILE: pkg/golinters/gomoddirectives/gomoddirectives.go
================================================
package gomoddirectives
import (
"regexp"
"sync"
"github.com/ldez/gomoddirectives"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gomoddirectives"
func New(settings *config.GoModDirectivesSettings) *goanalysis.Linter {
var issues []*goanalysis.Issue
var once sync.Once
var opts gomoddirectives.Options
if settings != nil {
opts.ReplaceAllowLocal = settings.ReplaceLocal
opts.ReplaceAllowList = settings.ReplaceAllowList
opts.RetractAllowNoExplanation = settings.RetractAllowNoExplanation
opts.ExcludeForbidden = settings.ExcludeForbidden
opts.ToolchainForbidden = settings.ToolchainForbidden
opts.ToolForbidden = settings.ToolForbidden
opts.GoDebugForbidden = settings.GoDebugForbidden
opts.CheckModulePath = settings.CheckModulePath
if settings.ToolchainPattern != "" {
exp, err := regexp.Compile(settings.ToolchainPattern)
if err != nil {
internal.LinterLogger.Fatalf("%s: invalid toolchain pattern: %v", linterName, err)
} else {
opts.ToolchainPattern = exp
}
}
if settings.GoVersionPattern != "" {
exp, err := regexp.Compile(settings.GoVersionPattern)
if err != nil {
internal.LinterLogger.Fatalf("%s: invalid Go version pattern: %v", linterName, err)
} else {
opts.GoVersionPattern = exp
}
}
}
analyzer := &analysis.Analyzer{
Name: linterName,
Doc: "Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.",
Run: goanalysis.DummyRun,
}
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithContextSetter(func(lintCtx *linter.Context) {
analyzer.Run = func(pass *analysis.Pass) (any, error) {
once.Do(func() {
results, err := gomoddirectives.AnalyzePass(pass, opts)
if err != nil {
lintCtx.Log.Warnf("running %s failed: %s: "+
"if you are not using go modules it is suggested to disable this linter", linterName, err)
return
}
for _, p := range results {
issues = append(issues, goanalysis.NewIssue(&result.Issue{
FromLinter: linterName,
Pos: p.Start,
Text: p.Reason,
}, pass))
}
})
return nil, nil
}
}).
WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
return issues
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/gomodguard/gomodguard.go
================================================
package gomodguard
import (
"sync"
"github.com/ryancurrah/gomodguard"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gomodguard"
func New(settings *config.GoModGuardSettings) *goanalysis.Linter {
var issues []*goanalysis.Issue
var mu sync.Mutex
processorCfg := &gomodguard.Configuration{}
if settings != nil {
processorCfg.Allowed.Modules = settings.Allowed.Modules
processorCfg.Allowed.Domains = settings.Allowed.Domains
processorCfg.Blocked.LocalReplaceDirectives = settings.Blocked.LocalReplaceDirectives
for n := range settings.Blocked.Modules {
for k, v := range settings.Blocked.Modules[n] {
m := map[string]gomodguard.BlockedModule{k: {
Recommendations: v.Recommendations,
Reason: v.Reason,
}}
processorCfg.Blocked.Modules = append(processorCfg.Blocked.Modules, m)
break
}
}
for n := range settings.Blocked.Versions {
for k, v := range settings.Blocked.Versions[n] {
m := map[string]gomodguard.BlockedVersion{k: {
Version: v.Version,
Reason: v.Reason,
}}
processorCfg.Blocked.Versions = append(processorCfg.Blocked.Versions, m)
break
}
}
}
analyzer := &analysis.Analyzer{
Name: linterName,
Doc: "Allow and blocklist linter for direct Go module dependencies. " +
"This is different from depguard where there are different block " +
"types for example version constraints and module recommendations.",
Run: goanalysis.DummyRun,
}
return goanalysis.NewLinterFromAnalyzer(analyzer).
WithContextSetter(func(lintCtx *linter.Context) {
processor, err := gomodguard.NewProcessor(processorCfg)
if err != nil {
lintCtx.Log.Warnf("running gomodguard failed: %s: if you are not using go modules "+
"it is suggested to disable this linter", err)
return
}
analyzer.Run = func(pass *analysis.Pass) (any, error) {
gomodguardIssues := processor.ProcessFiles(internal.GetGoFileNames(pass))
mu.Lock()
defer mu.Unlock()
for _, gomodguardIssue := range gomodguardIssues {
issues = append(issues, goanalysis.NewIssue(&result.Issue{
FromLinter: linterName,
Pos: gomodguardIssue.Position,
Text: gomodguardIssue.Reason,
}, pass))
}
return nil, nil
}
}).
WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
return issues
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/gomodguard/gomodguard_integration_test.go
================================================
package gomodguard
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gomodguard/testdata/go.mod
================================================
module gomodguard
go 1.25.0
require (
golang.org/x/mod v0.24.0
gopkg.in/yaml.v3 v3.0.1
)
================================================
FILE: pkg/golinters/gomodguard/testdata/go.sum
================================================
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
================================================
FILE: pkg/golinters/gomodguard/testdata/gomodguard.go
================================================
//golangcitest:args -Egomodguard
//golangcitest:config_path testdata/gomodguard.yml
package testdata
import (
"log"
"golang.org/x/mod/modfile"
"gopkg.in/yaml.v3" // want "import of package `gopkg.in/yaml.v3` is blocked because the module is in the blocked modules list. `github.com/kylelemons/go-gypsy` is a recommended module. This is an example of recommendations."
)
// Something just some struct
type Something struct{}
func aAllowedImport() { //nolint:unused
mfile, _ := modfile.Parse("go.mod", []byte{}, nil)
log.Println(mfile)
}
func aBlockedImport() { //nolint:unused
data := []byte{}
something := Something{}
_ = yaml.Unmarshal(data, &something)
log.Println(data)
}
================================================
FILE: pkg/golinters/gomodguard/testdata/gomodguard.yml
================================================
version: "2"
linters:
settings:
gomodguard:
allowed:
modules: # List of allowed modules
- golang.org/x/mod
blocked:
modules: # List of blocked modules
- gopkg.in/yaml.v3: # Blocked module
recommendations: # Recommended modules that should be used instead (Optional)
- github.com/kylelemons/go-gypsy
reason: "This is an example of recommendations." # Reason why the recommended module should be used (Optional)
================================================
FILE: pkg/golinters/gomodguard/testdata/gomodguard_cgo.go
================================================
//golangcitest:args -Egomodguard
//golangcitest:config_path testdata/gomodguard.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"log"
"unsafe"
"golang.org/x/mod/modfile"
"gopkg.in/yaml.v3" // want "import of package `gopkg.in/yaml.v3` is blocked because the module is in the blocked modules list. `github.com/kylelemons/go-gypsy` is a recommended module. This is an example of recommendations."
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
// Something just some struct
type Something struct{}
func aAllowedImport() { //nolint:unused
mfile, _ := modfile.Parse("go.mod", []byte{}, nil)
log.Println(mfile)
}
func aBlockedImport() { //nolint:unused
data := []byte{}
something := Something{}
_ = yaml.Unmarshal(data, &something)
log.Println(data)
}
================================================
FILE: pkg/golinters/goprintffuncname/goprintffuncname.go
================================================
package goprintffuncname
import (
"github.com/golangci/go-printf-func-name/pkg/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(analyzer.Analyzer).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/goprintffuncname/goprintffuncname_integration_test.go
================================================
package goprintffuncname
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/goprintffuncname/testdata/goprintffuncname.go
================================================
//golangcitest:args -Egoprintffuncname
package testdata
func PrintfLikeFuncWithBadName(format string, args ...interface{}) { // want "printf-like formatting function 'PrintfLikeFuncWithBadName' should be named 'PrintfLikeFuncWithBadNamef'"
}
================================================
FILE: pkg/golinters/goprintffuncname/testdata/goprintffuncname_cgo.go
================================================
//golangcitest:args -Egoprintffuncname
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func PrintfLikeFuncWithBadName(format string, args ...interface{}) { // want "printf-like formatting function 'PrintfLikeFuncWithBadName' should be named 'PrintfLikeFuncWithBadNamef'"
}
================================================
FILE: pkg/golinters/gosec/gosec.go
================================================
package gosec
import (
"fmt"
"go/token"
"io"
"log"
"strconv"
"strings"
"sync"
"github.com/securego/gosec/v2"
"github.com/securego/gosec/v2/analyzers"
"github.com/securego/gosec/v2/issue"
"github.com/securego/gosec/v2/rules"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gosec"
func New(settings *config.GoSecSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []*goanalysis.Issue
conf := gosec.NewConfig()
var ruleFilters []rules.RuleFilter
var analyzerFilters []analyzers.AnalyzerFilter
if settings != nil {
// TODO(ldez) to remove when the problem will be fixed by gosec.
// https://github.com/securego/gosec/issues/1211
// https://github.com/securego/gosec/issues/1209
settings.Excludes = append(settings.Excludes, "G407")
ruleFilters = createRuleFilters(settings.Includes, settings.Excludes)
analyzerFilters = createAnalyzerFilters(settings.Includes, settings.Excludes)
conf = toGosecConfig(settings)
}
logger := log.New(io.Discard, "", 0)
ruleDefinitions := rules.Generate(false, ruleFilters...)
analyzerDefinitions := analyzers.Generate(false, analyzerFilters...)
analyzer := &analysis.Analyzer{
Name: linterName,
Doc: "Inspects source code for security problems",
Run: goanalysis.DummyRun,
}
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithContextSetter(func(lintCtx *linter.Context) {
analyzer.Run = func(pass *analysis.Pass) (any, error) {
// The `gosecAnalyzer` is here because of concurrency issue.
gosecAnalyzer := gosec.NewAnalyzer(conf, true, false, false, settings.Concurrency, logger)
gosecAnalyzer.LoadRules(ruleDefinitions.RulesInfo())
gosecAnalyzer.LoadAnalyzers(analyzerDefinitions.AnalyzersInfo())
issues := runGoSec(lintCtx, pass, settings, gosecAnalyzer)
mu.Lock()
resIssues = append(resIssues, issues...)
mu.Unlock()
return nil, nil
}
}).
WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
return resIssues
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func runGoSec(lintCtx *linter.Context, pass *analysis.Pass, settings *config.GoSecSettings, analyzer *gosec.Analyzer) []*goanalysis.Issue {
pkg := &packages.Package{
Fset: pass.Fset,
Syntax: pass.Files,
Types: pass.Pkg,
TypesInfo: pass.TypesInfo,
}
analyzer.CheckRules(pkg)
analyzer.CheckAnalyzers(pkg)
secIssues, _, _ := analyzer.Report()
if len(secIssues) == 0 {
return nil
}
severity, err := convertToScore(settings.Severity)
if err != nil {
lintCtx.Log.Warnf("The provided severity %v", err)
}
confidence, err := convertToScore(settings.Confidence)
if err != nil {
lintCtx.Log.Warnf("The provided confidence %v", err)
}
secIssues = filterIssues(secIssues, severity, confidence)
issues := make([]*goanalysis.Issue, 0, len(secIssues))
for _, i := range secIssues {
text := fmt.Sprintf("%s: %s", i.RuleID, i.What)
var r *result.Range
line, err := strconv.Atoi(i.Line)
if err != nil {
r = &result.Range{}
if n, rerr := fmt.Sscanf(i.Line, "%d-%d", &r.From, &r.To); rerr != nil || n != 2 {
lintCtx.Log.Warnf("Can't convert gosec line number %q of %v to int: %s", i.Line, i, err)
continue
}
line = r.From
}
column, err := strconv.Atoi(i.Col)
if err != nil {
lintCtx.Log.Warnf("Can't convert gosec column number %q of %v to int: %s", i.Col, i, err)
continue
}
issues = append(issues, goanalysis.NewIssue(&result.Issue{
Severity: convertScoreToString(i.Severity),
Pos: token.Position{
Filename: i.File,
Line: line,
Column: column,
},
Text: text,
LineRange: r,
FromLinter: linterName,
}, pass))
}
return issues
}
func toGosecConfig(settings *config.GoSecSettings) gosec.Config {
conf := gosec.NewConfig()
for k, v := range settings.Config {
if k == gosec.Globals {
convertGosecGlobals(v, conf)
continue
}
// Uses ToUpper because the parsing of the map's key change the key to lowercase.
// The value is not impacted by that: the case is respected.
conf.Set(strings.ToUpper(k), v)
}
return conf
}
func convertScoreToString(score issue.Score) string {
switch score {
case issue.Low:
return "low"
case issue.Medium:
return "medium"
case issue.High:
return "high"
default:
return ""
}
}
// based on https://github.com/securego/gosec/blob/47bfd4eb6fc7395940933388550b547538b4c946/config.go#L52-L62
func convertGosecGlobals(globalOptionFromConfig any, conf gosec.Config) {
globalOptionMap, ok := globalOptionFromConfig.(map[string]any)
if !ok {
return
}
for k, v := range globalOptionMap {
option := gosec.GlobalOption(k)
// Set nosec global option only if the value is true
// https://github.com/securego/gosec/blob/v2.21.4/analyzer.go#L572
if option == gosec.Nosec && v == false {
continue
}
conf.SetGlobal(option, fmt.Sprintf("%v", v))
}
}
// based on https://github.com/securego/gosec/blob/81cda2f91fbe1bf4735feb55febcae03e697a92b/cmd/gosec/main.go#L258-L275
func createAnalyzerFilters(includes, excludes []string) []analyzers.AnalyzerFilter {
var filters []analyzers.AnalyzerFilter
if len(includes) > 0 {
filters = append(filters, analyzers.NewAnalyzerFilter(false, includes...))
}
if len(excludes) > 0 {
filters = append(filters, analyzers.NewAnalyzerFilter(true, excludes...))
}
return filters
}
// based on https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/cmd/gosec/main.go#L170-L188
func createRuleFilters(includes, excludes []string) []rules.RuleFilter {
var filters []rules.RuleFilter
if len(includes) > 0 {
filters = append(filters, rules.NewRuleFilter(false, includes...))
}
if len(excludes) > 0 {
filters = append(filters, rules.NewRuleFilter(true, excludes...))
}
return filters
}
// code borrowed from https://github.com/securego/gosec/blob/69213955dacfd560562e780f723486ef1ca6d486/cmd/gosec/main.go#L250-L262
func convertToScore(str string) (issue.Score, error) {
str = strings.ToLower(str)
switch str {
case "", "low":
return issue.Low, nil
case "medium":
return issue.Medium, nil
case "high":
return issue.High, nil
default:
return issue.Low, fmt.Errorf("'%s' is invalid, use low instead. Valid options: low, medium, high", str)
}
}
// code borrowed from https://github.com/securego/gosec/blob/69213955dacfd560562e780f723486ef1ca6d486/cmd/gosec/main.go#L264-L276
func filterIssues(issues []*issue.Issue, severity, confidence issue.Score) []*issue.Issue {
res := make([]*issue.Issue, 0)
for _, i := range issues {
if i.Severity >= severity && i.Confidence >= confidence {
res = append(res, i)
}
}
return res
}
================================================
FILE: pkg/golinters/gosec/gosec_integration_test.go
================================================
package gosec
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gosec/gosec_test.go
================================================
package gosec
import (
"testing"
"github.com/securego/gosec/v2"
"github.com/stretchr/testify/assert"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
func Test_toGosecConfig(t *testing.T) {
testCases := []struct {
desc string
settings *config.GoSecSettings
expected gosec.Config
}{
{
desc: "empty config map",
settings: &config.GoSecSettings{},
expected: gosec.Config{
"global": map[gosec.GlobalOption]string{},
},
},
{
desc: "with global settings",
settings: &config.GoSecSettings{
Config: map[string]any{
gosec.Globals: map[string]any{
string(gosec.Nosec): true,
string(gosec.Audit): "true",
},
},
},
expected: gosec.Config{
"global": map[gosec.GlobalOption]string{
"audit": "true",
"nosec": "true",
},
},
},
{
desc: "with global settings nosec enabled",
settings: &config.GoSecSettings{
Config: map[string]any{
gosec.Globals: map[string]any{
string(gosec.Nosec): false,
string(gosec.Audit): "true",
},
},
},
expected: gosec.Config{
"global": map[gosec.GlobalOption]string{
"audit": "true",
},
},
},
{
desc: "rule specified setting",
settings: &config.GoSecSettings{
Config: map[string]any{
"g101": map[string]any{
"pattern": "(?i)example",
},
"G301": "0750",
},
},
expected: gosec.Config{
"G101": map[string]any{"pattern": "(?i)example"},
"G301": "0750",
"global": map[gosec.GlobalOption]string{},
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
conf := toGosecConfig(test.settings)
assert.Equal(t, test.expected, conf)
})
}
}
================================================
FILE: pkg/golinters/gosec/testdata/gosec.go
================================================
//golangcitest:args -Egosec
package testdata
import (
"crypto/md5" // want "G501: Blocklisted import crypto/md5: weak cryptographic primitive"
"fmt"
"log"
"os"
"os/exec"
)
func Gosec() {
h := md5.New() // want "G401: Use of weak cryptographic primitive"
log.Print(h)
}
func GosecNolintGosec() {
h := md5.New() //nolint:gosec
log.Print(h)
}
func GosecNoErrorCheckingByDefault() {
f, _ := os.Create("foo")
fmt.Println(f)
}
func GosecG204SubprocWithFunc() {
arg := func() string {
return "/tmp/dummy"
}
exec.Command("ls", arg()).Run() // want "G104: Errors unhandled"
}
================================================
FILE: pkg/golinters/gosec/testdata/gosec.yml
================================================
version: "2"
linters:
settings:
gosec:
includes:
- G306
- G101
config:
G306: "0666"
G101:
pattern: "(?i)simple"
ignore_entropy: false
entropy_threshold: "80.0"
per_char_threshold: "3.0"
truncate: "32"
================================================
FILE: pkg/golinters/gosec/testdata/gosec_cgo.go
================================================
//go:build ignore
// TODO(ldez) the linter doesn't support cgo.
//golangcitest:args -Egosec
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"crypto/md5"
"log"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func Gosec() {
h := md5.New() // want "G401: Use of weak cryptographic primitive"
log.Print(h)
}
================================================
FILE: pkg/golinters/gosec/testdata/gosec_global_option.go
================================================
//golangcitest:args -Egosec
//golangcitest:config_path testdata/gosec_global_option.yml
package testdata
import (
"crypto/md5" // want "G501: Blocklisted import crypto/md5: weak cryptographic primitive"
"log"
)
func Gosec() {
// #nosec G401
h := md5.New() // want "G401: Use of weak cryptographic primitive"
log.Print(h)
}
================================================
FILE: pkg/golinters/gosec/testdata/gosec_global_option.yml
================================================
version: "2"
linters:
settings:
gosec:
config:
global:
nosec: true
================================================
FILE: pkg/golinters/gosec/testdata/gosec_nosec.go
================================================
//golangcitest:args -Egosec
//golangcitest:config_path testdata/gosec_nosec.yml
package testdata
import (
"crypto/md5" // want "G501: Blocklisted import crypto/md5: weak cryptographic primitive"
"log"
)
func Gosec() {
// #nosec G401
h := md5.New()
log.Print(h)
}
================================================
FILE: pkg/golinters/gosec/testdata/gosec_nosec.yml
================================================
version: "2"
linters:
settings:
gosec:
config:
global:
nosec: false
================================================
FILE: pkg/golinters/gosec/testdata/gosec_rules_config.go
================================================
//golangcitest:args -Egosec
//golangcitest:config_path testdata/gosec.yml
package testdata
import "io/ioutil"
const gosecToken = "62ebc7a03d6ca24dca1258fd4b48462f6fed1545"
const gosecSimple = "62ebc7a03d6ca24dca1258fd4b48462f6fed1545" // want "G101: Potential hardcoded credentials"
func gosecCustom() {
ioutil.WriteFile("filename", []byte("test"), 0755) // want "G306: Expect WriteFile permissions to be 0666 or less"
}
================================================
FILE: pkg/golinters/gosec/testdata/gosec_severity_confidence.go
================================================
//golangcitest:args -Egosec
//golangcitest:config_path testdata/gosec_severity_confidence.yml
package testdata
import (
"fmt"
"io/ioutil"
"net/http"
)
var url string = "https://www.abcdefghijk.com"
func gosecVariableURL() {
resp, err := http.Get(url) // want "G107: Potential HTTP request made with variable url"
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Printf("%s", body)
}
func gosecHardcodedCredentials() {
username := "admin"
var password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
fmt.Println("Doing something with: ", username, password)
}
================================================
FILE: pkg/golinters/gosec/testdata/gosec_severity_confidence.yml
================================================
version: "2"
linters:
settings:
gosec:
severity: "medium"
confidence: "medium"
================================================
FILE: pkg/golinters/gosmopolitan/gosmopolitan.go
================================================
package gosmopolitan
import (
"strings"
"github.com/xen0n/gosmopolitan"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.GosmopolitanSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"allowtimelocal": settings.AllowTimeLocal,
"escapehatches": strings.Join(settings.EscapeHatches, ","),
"watchforscripts": strings.Join(settings.WatchForScripts, ","),
// Should be managed with `linters.exclusions.rules`.
"lookattests": true,
}
}
return goanalysis.
NewLinterFromAnalyzer(gosmopolitan.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/gosmopolitan/gosmopolitan_integration_test.go
================================================
package gosmopolitan
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan.go
================================================
//golangcitest:args -Egosmopolitan
package testdata
import (
"fmt"
"time"
)
type col struct {
// struct tag should not get reported
Foo string `gorm:"column:bar;not null;comment:'不应该报告这一行'"`
}
func main() {
fmt.Println("hello world")
fmt.Println("你好,世界") // want `string literal contains rune in Han script`
fmt.Println("こんにちは、セカイ")
_ = col{Foo: "hello"}
_ = col{Foo: "你好"} // want `string literal contains rune in Han script`
x := time.Local // want `usage of time.Local`
_ = time.Now().In(x)
_ = time.Date(2023, 1, 2, 3, 4, 5, 678901234, time.Local) // want `usage of time.Local`
}
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan_allow_time_local.go
================================================
//golangcitest:args -Egosmopolitan
//golangcitest:config_path testdata/gosmopolitan_allow_time_local.yml
//golangcitest:expected_exitcode 0
package testdata
import (
"time"
)
func main() {
_ = time.Local
}
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan_allow_time_local.yml
================================================
version: "2"
linters:
settings:
gosmopolitan:
allow-time-local: true
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan_cgo.go
================================================
//golangcitest:args -Egosmopolitan
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"time"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type col struct {
// struct tag should not get reported
Foo string `gorm:"column:bar;not null;comment:'不应该报告这一行'"`
}
func _() {
fmt.Println("hello world")
fmt.Println("你好,世界") // want `string literal contains rune in Han script`
fmt.Println("こんにちは、セカイ")
_ = col{Foo: "hello"}
_ = col{Foo: "你好"} // want `string literal contains rune in Han script`
x := time.Local // want `usage of time.Local`
_ = time.Now().In(x)
_ = time.Date(2023, 1, 2, 3, 4, 5, 678901234, time.Local) // want `usage of time.Local`
}
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan_dont_ignore_test.go
================================================
//golangcitest:args -Egosmopolitan
package testdata
import (
"time"
)
func main() {
_ = "开启检查测试文件" // want `string literal contains rune in Han script`
_ = time.Local // want `usage of time.Local`
}
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan_escape_hatches.go
================================================
//golangcitest:args -Egosmopolitan
//golangcitest:config_path testdata/gosmopolitan_escape_hatches.yml
package testdata
import (
myAlias "fmt"
)
type A string
type B = string
type C struct {
foo string
Bar string
}
func D(fmt string) string {
myAlias.Println(fmt, "测试")
return myAlias.Sprintf("%s 测试", fmt) // want `string literal contains rune in Han script`
}
type X struct {
baz string
}
func main() {
_ = A("测试")
_ = string(A(string("测试")))
_ = B("测试")
_ = C{
foo: "测试",
Bar: "测试",
}
_ = D("测试")
_ = &X{
baz: "测试", // want `string literal contains rune in Han script`
}
}
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan_escape_hatches.yml
================================================
version: "2"
linters:
settings:
gosmopolitan:
escape-hatches:
- 'command-line-arguments.A'
- 'command-line-arguments.B'
- 'command-line-arguments.C'
- 'command-line-arguments.D'
- 'fmt.Println'
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan_scripts.go
================================================
//golangcitest:args -Egosmopolitan
//golangcitest:config_path testdata/gosmopolitan_scripts.yml
package testdata
import (
"fmt"
)
func main() {
fmt.Println("hello world") // want `string literal contains rune in Latin script`
fmt.Println("should not report this line") //nolint:gosmopolitan
fmt.Println("你好,世界")
fmt.Println("こんにちは、セカイ") // want `string literal contains rune in Hiragana script`
}
================================================
FILE: pkg/golinters/gosmopolitan/testdata/gosmopolitan_scripts.yml
================================================
version: "2"
linters:
settings:
gosmopolitan:
watch-for-scripts:
- Hiragana
- Katakana
- Latin
================================================
FILE: pkg/golinters/govet/govet.go
================================================
package govet
import (
"slices"
"strings"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/appends"
"golang.org/x/tools/go/analysis/passes/asmdecl"
"golang.org/x/tools/go/analysis/passes/assign"
"golang.org/x/tools/go/analysis/passes/atomic"
"golang.org/x/tools/go/analysis/passes/atomicalign"
"golang.org/x/tools/go/analysis/passes/bools"
_ "golang.org/x/tools/go/analysis/passes/buildssa" // unused, internal analyzer
"golang.org/x/tools/go/analysis/passes/buildtag"
"golang.org/x/tools/go/analysis/passes/cgocall"
"golang.org/x/tools/go/analysis/passes/composite"
"golang.org/x/tools/go/analysis/passes/copylock"
_ "golang.org/x/tools/go/analysis/passes/ctrlflow" // unused, internal analyzer
"golang.org/x/tools/go/analysis/passes/deepequalerrors"
"golang.org/x/tools/go/analysis/passes/defers"
"golang.org/x/tools/go/analysis/passes/directive"
"golang.org/x/tools/go/analysis/passes/errorsas"
"golang.org/x/tools/go/analysis/passes/fieldalignment"
"golang.org/x/tools/go/analysis/passes/findcall"
"golang.org/x/tools/go/analysis/passes/framepointer"
"golang.org/x/tools/go/analysis/passes/hostport"
"golang.org/x/tools/go/analysis/passes/httpmux"
"golang.org/x/tools/go/analysis/passes/httpresponse"
"golang.org/x/tools/go/analysis/passes/ifaceassert"
_ "golang.org/x/tools/go/analysis/passes/inspect" // unused internal analyzer
"golang.org/x/tools/go/analysis/passes/loopclosure"
"golang.org/x/tools/go/analysis/passes/lostcancel"
"golang.org/x/tools/go/analysis/passes/nilfunc"
"golang.org/x/tools/go/analysis/passes/nilness"
_ "golang.org/x/tools/go/analysis/passes/pkgfact" // unused, internal analyzer
"golang.org/x/tools/go/analysis/passes/printf"
"golang.org/x/tools/go/analysis/passes/reflectvaluecompare"
"golang.org/x/tools/go/analysis/passes/shadow"
"golang.org/x/tools/go/analysis/passes/shift"
"golang.org/x/tools/go/analysis/passes/sigchanyzer"
"golang.org/x/tools/go/analysis/passes/slog"
"golang.org/x/tools/go/analysis/passes/sortslice"
"golang.org/x/tools/go/analysis/passes/stdmethods"
"golang.org/x/tools/go/analysis/passes/stdversion"
"golang.org/x/tools/go/analysis/passes/stringintconv"
"golang.org/x/tools/go/analysis/passes/structtag"
"golang.org/x/tools/go/analysis/passes/testinggoroutine"
"golang.org/x/tools/go/analysis/passes/tests"
"golang.org/x/tools/go/analysis/passes/timeformat"
"golang.org/x/tools/go/analysis/passes/unmarshal"
"golang.org/x/tools/go/analysis/passes/unreachable"
"golang.org/x/tools/go/analysis/passes/unsafeptr"
"golang.org/x/tools/go/analysis/passes/unusedresult"
"golang.org/x/tools/go/analysis/passes/unusedwrite"
"golang.org/x/tools/go/analysis/passes/waitgroup"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/logutils"
)
var (
allAnalyzers = []*analysis.Analyzer{
appends.Analyzer,
asmdecl.Analyzer,
assign.Analyzer,
atomic.Analyzer,
atomicalign.Analyzer,
bools.Analyzer,
buildtag.Analyzer,
cgocall.Analyzer,
composite.Analyzer,
copylock.Analyzer,
deepequalerrors.Analyzer,
defers.Analyzer,
directive.Analyzer,
errorsas.Analyzer,
fieldalignment.Analyzer,
findcall.Analyzer,
framepointer.Analyzer,
hostport.Analyzer,
httpmux.Analyzer,
httpresponse.Analyzer,
ifaceassert.Analyzer,
loopclosure.Analyzer,
lostcancel.Analyzer,
nilfunc.Analyzer,
nilness.Analyzer,
printf.Analyzer,
reflectvaluecompare.Analyzer,
shadow.Analyzer,
shift.Analyzer,
sigchanyzer.Analyzer,
slog.Analyzer,
sortslice.Analyzer,
stdmethods.Analyzer,
stdversion.Analyzer,
stringintconv.Analyzer,
structtag.Analyzer,
testinggoroutine.Analyzer,
tests.Analyzer,
timeformat.Analyzer,
unmarshal.Analyzer,
unreachable.Analyzer,
unsafeptr.Analyzer,
unusedresult.Analyzer,
unusedwrite.Analyzer,
waitgroup.Analyzer,
}
// https://github.com/golang/go/blob/go1.25.2/src/cmd/vet/main.go#L57-L91
defaultAnalyzers = []*analysis.Analyzer{
appends.Analyzer,
asmdecl.Analyzer,
assign.Analyzer,
atomic.Analyzer,
bools.Analyzer,
buildtag.Analyzer,
cgocall.Analyzer,
composite.Analyzer,
copylock.Analyzer,
defers.Analyzer,
directive.Analyzer,
errorsas.Analyzer,
framepointer.Analyzer,
hostport.Analyzer,
httpresponse.Analyzer,
ifaceassert.Analyzer,
loopclosure.Analyzer,
lostcancel.Analyzer,
nilfunc.Analyzer,
printf.Analyzer,
shift.Analyzer,
sigchanyzer.Analyzer,
slog.Analyzer,
stdmethods.Analyzer,
stdversion.Analyzer,
stringintconv.Analyzer,
structtag.Analyzer,
testinggoroutine.Analyzer,
tests.Analyzer,
timeformat.Analyzer,
unmarshal.Analyzer,
unreachable.Analyzer,
unsafeptr.Analyzer,
unusedresult.Analyzer,
waitgroup.Analyzer,
}
)
var (
debugf = logutils.Debug(logutils.DebugKeyGovet)
isDebug = logutils.HaveDebugTag(logutils.DebugKeyGovet)
)
func New(settings *config.GovetSettings) *goanalysis.Linter {
var conf map[string]map[string]any
if settings != nil {
conf = settings.Settings
}
return goanalysis.NewLinter(
"govet",
"Vet examines Go source code and reports suspicious constructs. "+
"It is roughly the same as 'go vet' and uses its passes.",
analyzersFromConfig(settings),
conf,
).WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func analyzersFromConfig(settings *config.GovetSettings) []*analysis.Analyzer {
logAnalyzers("All available analyzers", allAnalyzers)
logAnalyzers("Default analyzers", defaultAnalyzers)
if settings == nil {
return defaultAnalyzers
}
var enabledAnalyzers []*analysis.Analyzer
for _, a := range allAnalyzers {
if isAnalyzerEnabled(a.Name, settings, defaultAnalyzers) {
enabledAnalyzers = append(enabledAnalyzers, a)
}
}
logAnalyzers("Enabled by config analyzers", enabledAnalyzers)
return enabledAnalyzers
}
func isAnalyzerEnabled(name string, cfg *config.GovetSettings, defaultAnalyzers []*analysis.Analyzer) bool {
// TODO(ldez) remove loopclosure when go1.24
if name == loopclosure.Analyzer.Name && config.IsGoGreaterThanOrEqual(cfg.Go, "1.22") {
return false
}
switch {
case cfg.EnableAll:
return !slices.Contains(cfg.Disable, name)
case slices.Contains(cfg.Enable, name):
return true
case slices.Contains(cfg.Disable, name):
return false
case cfg.DisableAll:
return false
default:
return slices.ContainsFunc(defaultAnalyzers, func(a *analysis.Analyzer) bool { return a.Name == name })
}
}
func logAnalyzers(message string, analyzers []*analysis.Analyzer) {
if !isDebug {
return
}
analyzerNames := make([]string, 0, len(analyzers))
for _, a := range analyzers {
analyzerNames = append(analyzerNames, a.Name)
}
slices.Sort(analyzerNames)
debugf("%s (%d): %s", message, len(analyzerNames), strings.Join(analyzerNames, ", "))
}
================================================
FILE: pkg/golinters/govet/govet_integration_test.go
================================================
package govet
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/govet/govet_test.go
================================================
package govet
import (
"slices"
"testing"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/asmdecl"
"golang.org/x/tools/go/analysis/passes/assign"
"golang.org/x/tools/go/analysis/passes/atomic"
"golang.org/x/tools/go/analysis/passes/bools"
"golang.org/x/tools/go/analysis/passes/buildtag"
"golang.org/x/tools/go/analysis/passes/cgocall"
"golang.org/x/tools/go/analysis/passes/shadow"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
func TestGovet(t *testing.T) {
// Checking that every default analyzer is in "all analyzers" list.
checkList := slices.Clone(defaultAnalyzers)
checkList = append(checkList, shadow.Analyzer) // special case, used in analyzersFromConfig
for _, defaultAnalyzer := range checkList {
found := slices.ContainsFunc(allAnalyzers, func(a *analysis.Analyzer) bool {
return a.Name == defaultAnalyzer.Name
})
if !found {
t.Errorf("%s is not in allAnalyzers", defaultAnalyzer.Name)
}
}
}
func sortAnalyzers(a, b *analysis.Analyzer) int {
if a.Name < b.Name {
return -1
}
if a.Name > b.Name {
return 1
}
return 0
}
func TestGovetSorted(t *testing.T) {
// Keeping analyzers sorted so their order match the import order.
t.Run("All", func(t *testing.T) {
if !slices.IsSortedFunc(allAnalyzers, sortAnalyzers) {
t.Error("please keep all analyzers list sorted by name")
}
})
t.Run("Default", func(t *testing.T) {
if !slices.IsSortedFunc(defaultAnalyzers, sortAnalyzers) {
t.Error("please keep default analyzers list sorted by name")
}
})
}
func TestGovetAnalyzerIsEnabled(t *testing.T) {
defaultAnalyzers := []*analysis.Analyzer{
asmdecl.Analyzer,
assign.Analyzer,
atomic.Analyzer,
bools.Analyzer,
buildtag.Analyzer,
cgocall.Analyzer,
}
for _, tc := range []struct {
Enable []string
Disable []string
EnableAll bool
DisableAll bool
Go string
Name string
Enabled bool
}{
{Name: "assign", Enabled: true},
{Name: "cgocall", Enabled: false, DisableAll: true},
{Name: "errorsas", Enabled: false},
{Name: "bools", Enabled: false, Disable: []string{"bools"}},
{Name: "unsafeptr", Enabled: true, Enable: []string{"unsafeptr"}},
{Name: "shift", Enabled: true, EnableAll: true},
{Name: "shadow", EnableAll: true, Disable: []string{"shadow"}, Enabled: false},
} {
cfg := &config.GovetSettings{
Enable: tc.Enable,
Disable: tc.Disable,
EnableAll: tc.EnableAll,
DisableAll: tc.DisableAll,
Go: tc.Go,
}
if enabled := isAnalyzerEnabled(tc.Name, cfg, defaultAnalyzers); enabled != tc.Enabled {
t.Errorf("%+v", tc)
}
}
}
================================================
FILE: pkg/golinters/govet/testdata/fix/in/govet.go
================================================
//golangcitest:args -Egovet
//golangcitest:config_path testdata/govet_fix.yml
//golangcitest:expected_exitcode 0
package testdata
import (
"fmt"
"log"
"os"
)
type Foo struct {
A []string
B bool
C string
D int8
E int32
}
func nonConstantFormat(s string) {
fmt.Printf("%s", s)
fmt.Printf(s, "arg")
fmt.Fprintf(os.Stderr, "%s", s)
log.Printf("%s", s)
}
================================================
FILE: pkg/golinters/govet/testdata/fix/out/govet.go
================================================
//golangcitest:args -Egovet
//golangcitest:config_path testdata/govet_fix.yml
//golangcitest:expected_exitcode 0
package testdata
import (
"fmt"
"log"
"os"
)
type Foo struct {
C string
A []string
E int32
B bool
D int8
}
func nonConstantFormat(s string) {
fmt.Printf("%s", s)
fmt.Printf(s, "arg")
fmt.Fprintf(os.Stderr, "%s", s)
log.Printf("%s", s)
}
================================================
FILE: pkg/golinters/govet/testdata/govet.go
================================================
//golangcitest:args -Egovet
//golangcitest:config_path testdata/govet.yml
package testdata
import (
"fmt"
"io"
"os"
)
func GovetComposites() error {
return &os.PathError{"first", "path", os.ErrNotExist} // want "composites: (os|io/fs)\\.PathError struct literal uses unkeyed fields"
}
func GovetShadow(f io.Reader, buf []byte) (err error) {
if f != nil {
_, err := f.Read(buf) // want `shadow: declaration of .err. shadows declaration at line \d+`
if err != nil {
return err
}
}
// Use variable to trigger shadowing error
_ = err
return
}
func GovetPrintf() {
x := "dummy"
fmt.Printf("%d", x) // want "printf: fmt.Printf format %d has arg x of wrong type string"
}
func GovetStringIntConv() {
i := 42
fmt.Println("i = " + string(i)) // want "stringintconv: conversion from int to string yields a string of one rune, not a string of digits"
}
================================================
FILE: pkg/golinters/govet/testdata/govet.yml
================================================
version: "2"
linters:
settings:
govet:
enable:
- shadow
================================================
FILE: pkg/golinters/govet/testdata/govet_cgo.go
================================================
//golangcitest:args -Egovet
//golangcitest:config_path testdata/govet.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"io"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _(f io.Reader, buf []byte) (err error) {
if f != nil {
_, err := f.Read(buf) // want `shadow: declaration of .err. shadows declaration at line \d+`
if err != nil {
return err
}
}
// Use variable to trigger shadowing error
_ = err
return
}
================================================
FILE: pkg/golinters/govet/testdata/govet_custom_formatter.go
================================================
//golangcitest:args -Egovet
//golangcitest:expected_exitcode 0
package main
import (
"bytes"
"fmt"
"os"
)
const (
escape = "\x1b"
reset = escape + "[0m"
green = escape + "[32m"
minValue = 0.0
maxValue = 1.0
)
// Bar is a progress bar.
type Bar float64
var _ fmt.Formatter = Bar(maxValue)
// Format the progress bar as output
func (h Bar) Format(state fmt.State, r rune) {
switch r {
case 'r':
default:
panic(fmt.Sprintf("%v: unexpected format character", float64(h)))
}
if h > maxValue {
h = maxValue
}
if h < minValue {
h = minValue
}
if state.Flag('-') {
h = maxValue - h
}
width, ok := state.Width()
if !ok {
// default width of 40
width = 40
}
var pad int
extra := len([]byte(green)) + len([]byte(reset))
p := make([]byte, width+extra)
p[0], p[len(p)-1] = '|', '|'
pad += 2
positive := int(Bar(width-pad) * h)
negative := width - pad - positive
n := 1
n += copy(p[n:], green)
n += copy(p[n:], bytes.Repeat([]byte("+"), positive))
n += copy(p[n:], reset)
if negative > 0 {
copy(p[n:len(p)-1], bytes.Repeat([]byte("-"), negative))
}
_, _ = state.Write(p)
}
func main() {
var b Bar = 0.9
_, _ = fmt.Fprintf(os.Stdout, "%r", b)
}
================================================
FILE: pkg/golinters/govet/testdata/govet_fieldalignment.go
================================================
//go:build !(386 || arm || mips || mipsle)
//golangcitest:args -Egovet
//golangcitest:config_path testdata/govet_fieldalignment.yml
package testdata
type gvfaGood struct {
y int32
x byte
z byte
}
type gvfaBad struct { // want "struct of size 12 could be 8"
x byte
y int32
z byte
}
type gvfaPointerGood struct {
P *int
buf [1000]uintptr
}
type gvfaPointerBad struct { // want "struct with 8008 pointer bytes could be 8"
buf [1000]uintptr
P *int
}
type gvfaPointerSorta struct {
a struct {
p *int
q uintptr
}
b struct {
p *int
q [2]uintptr
}
}
type gvfaPointerSortaBad struct { // want "struct with 32 pointer bytes could be 24"
a struct {
p *int
q [2]uintptr
}
b struct {
p *int
q uintptr
}
}
type gvfaZeroGood struct {
a [0]byte
b uint32
}
type gvfaZeroBad struct { // want "struct of size 8 could be 4"
a uint32
b [0]byte
}
================================================
FILE: pkg/golinters/govet/testdata/govet_fieldalignment.yml
================================================
version: "2"
linters:
settings:
govet:
enable:
- fieldalignment
================================================
FILE: pkg/golinters/govet/testdata/govet_fix.yml
================================================
version: "2"
linters:
settings:
govet:
enable:
- assign
- composites
- fieldalignment
- findcall
- printf
- sigchanyzer
- sortslice
- stringintconv
- timeformat
- unreachable
================================================
FILE: pkg/golinters/govet/testdata/govet_ifaceassert.go
================================================
//golangcitest:args -Egovet
//golangcitest:config_path testdata/govet_ifaceassert.yml
package testdata
import (
"io"
)
func GovetIfaceAssert() {
var v interface {
Read()
}
_ = v.(io.Reader) // want "impossible type assertion: no type can implement both interface\\{Read\\(\\)\\} and io\\.Reader \\(conflicting types for Read method\\)"
}
================================================
FILE: pkg/golinters/govet/testdata/govet_ifaceassert.yml
================================================
version: "2"
linters:
settings:
govet:
enable:
- ifaceassert
================================================
FILE: pkg/golinters/grouper/grouper.go
================================================
package grouper
import (
grouper "github.com/leonklingele/grouper/pkg/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.GrouperSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"const-require-single-const": settings.ConstRequireSingleConst,
"const-require-grouping": settings.ConstRequireGrouping,
"import-require-single-import": settings.ImportRequireSingleImport,
"import-require-grouping": settings.ImportRequireGrouping,
"type-require-single-type": settings.TypeRequireSingleType,
"type-require-grouping": settings.TypeRequireGrouping,
"var-require-single-var": settings.VarRequireSingleVar,
"var-require-grouping": settings.VarRequireGrouping,
}
}
return goanalysis.
NewLinterFromAnalyzer(grouper.New()).
WithDesc("Analyze expression groups.").
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/grouper/grouper_integration_test.go
================================================
package grouper
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/grouper/testdata/grouper.go
================================================
//golangcitest:args -Egrouper
//golangcitest:config_path testdata/grouper.yml
package testdata
import "fmt" // want "should only use grouped 'import' declarations"
func dummy() { fmt.Println("dummy") }
================================================
FILE: pkg/golinters/grouper/testdata/grouper.yml
================================================
version: "2"
linters:
settings:
grouper:
import-require-grouping: true
================================================
FILE: pkg/golinters/grouper/testdata/grouper_cgo.go
================================================
//golangcitest:args -Egrouper
//golangcitest:config_path testdata/grouper.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C" // want "should only use grouped 'import' declarations"
import "unsafe" // want "grouper\\(related information\\): found here"
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
================================================
FILE: pkg/golinters/iface/iface.go
================================================
package iface
import (
"slices"
"github.com/uudashr/iface/identical"
"github.com/uudashr/iface/opaque"
"github.com/uudashr/iface/unexported"
"github.com/uudashr/iface/unused"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.IfaceSettings) *goanalysis.Linter {
var conf map[string]map[string]any
if settings != nil {
conf = settings.Settings
}
return goanalysis.NewLinter(
"iface",
"Detect the incorrect use of interfaces, helping developers avoid interface pollution.",
analyzersFromSettings(settings),
conf,
).WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func analyzersFromSettings(settings *config.IfaceSettings) []*analysis.Analyzer {
allAnalyzers := map[string]*analysis.Analyzer{
"identical": identical.Analyzer,
"unused": unused.Analyzer,
"opaque": opaque.Analyzer,
"unexported": unexported.Analyzer,
}
if settings == nil || len(settings.Enable) == 0 {
// Default enable `identical` analyzer only
return []*analysis.Analyzer{identical.Analyzer}
}
var analyzers []*analysis.Analyzer
for _, name := range uniqueNames(settings.Enable) {
if _, ok := allAnalyzers[name]; !ok {
// skip unknown analyzer
continue
}
analyzers = append(analyzers, allAnalyzers[name])
}
return analyzers
}
func uniqueNames(names []string) []string {
slices.Sort(names)
return slices.Compact(names)
}
================================================
FILE: pkg/golinters/iface/iface_integration_test.go
================================================
package iface
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/iface/testdata/fix/in/iface.go
================================================
//golangcitest:args -Eiface
//golangcitest:config_path testdata/iface_fix.yml
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
// identical
type Pinger interface {
Ping() error
}
type Healthcheck interface {
Ping() error
}
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) Server {
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepository interface {
UserOf(id string) (*User, error)
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
================================================
FILE: pkg/golinters/iface/testdata/fix/out/iface.go
================================================
//golangcitest:args -Eiface
//golangcitest:config_path testdata/iface_fix.yml
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
// identical
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) *server {
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
================================================
FILE: pkg/golinters/iface/testdata/iface_all.go
================================================
//golangcitest:args -Eiface
//golangcitest:config_path testdata/iface_all.yml
package testdata
import "fmt"
// identical
type Pinger interface { // want "identical: interface 'Pinger' contains identical methods or type constraints with another interface, causing redundancy"
Ping() error
}
type Healthcheck interface { // want "identical: interface 'Healthcheck' contains identical methods or type constraints with another interface, causing redundancy"
Ping() error
}
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) Server { // want "opaque: 'NewServer' function return 'Server' interface at the 1st result, abstract a single concrete implementation of '\\*server'"
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepository interface { // want "unused: interface 'UserRepository' is declared but not used within the package"
UserOf(id string) (*User, error)
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
================================================
FILE: pkg/golinters/iface/testdata/iface_all.yml
================================================
version: "2"
linters:
settings:
iface:
enable:
- unused
- identical
- opaque
================================================
FILE: pkg/golinters/iface/testdata/iface_cgo.go
================================================
//golangcitest:args -Eiface
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
// identical
type Pinger interface { // want "identical: interface 'Pinger' contains identical methods or type constraints with another interface, causing redundancy"
Ping() error
}
type Healthcheck interface { // want "identical: interface 'Healthcheck' contains identical methods or type constraints with another interface, causing redundancy"
Ping() error
}
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) Server {
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepository interface {
UserOf(id string) (*User, error)
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
================================================
FILE: pkg/golinters/iface/testdata/iface_default.go
================================================
//golangcitest:args -Eiface
package testdata
import "fmt"
// identical
type Pinger interface { // want "identical: interface 'Pinger' contains identical methods or type constraints with another interface, causing redundancy"
Ping() error
}
type Healthcheck interface { // want "identical: interface 'Healthcheck' contains identical methods or type constraints with another interface, causing redundancy"
Ping() error
}
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) Server {
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepository interface {
UserOf(id string) (*User, error)
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
================================================
FILE: pkg/golinters/iface/testdata/iface_fix.yml
================================================
version: "2"
linters:
settings:
iface:
enable:
- unused
- opaque
================================================
FILE: pkg/golinters/iface/testdata/iface_identical.go
================================================
//golangcitest:args -Eiface
//golangcitest:config_path testdata/iface_identical.yml
package testdata
import "fmt"
// identical
type Pinger interface { // want "identical: interface 'Pinger' contains identical methods or type constraints with another interface, causing redundancy"
Ping() error
}
type Healthcheck interface { // want "identical: interface 'Healthcheck' contains identical methods or type constraints with another interface, causing redundancy"
Ping() error
}
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) Server {
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepository interface {
UserOf(id string) (*User, error)
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
================================================
FILE: pkg/golinters/iface/testdata/iface_identical.yml
================================================
version: "2"
linters:
settings:
iface:
enable:
- identical
================================================
FILE: pkg/golinters/iface/testdata/iface_opaque.go
================================================
//golangcitest:args -Eiface
//golangcitest:config_path testdata/iface_opaque.yml
package testdata
import "fmt"
// identical
type Pinger interface {
Ping() error
}
type Healthcheck interface {
Ping() error
}
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) Server { // want "opaque: 'NewServer' function return 'Server' interface at the 1st result, abstract a single concrete implementation of '\\*server'"
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepository interface {
UserOf(id string) (*User, error)
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
================================================
FILE: pkg/golinters/iface/testdata/iface_opaque.yml
================================================
version: "2"
linters:
settings:
iface:
enable:
- opaque
================================================
FILE: pkg/golinters/iface/testdata/iface_unexported.go
================================================
//golangcitest:args -Eiface
//golangcitest:config_path testdata/iface_unexported.yml
package testdata
import "fmt"
// identical
type Pinger interface {
Ping() error
}
type Healthcheck interface {
Ping() error
}
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) Server {
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepository interface {
UserOf(id string) (*User, error)
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
// unexported
type unexportedReader interface {
Read([]byte) (int, error)
}
func ReadAll(r unexportedReader) ([]byte, error) { // want "unexported interface 'unexportedReader' used as parameter in exported function 'ReadAll'"
buf := make([]byte, 1024)
_, err := r.Read(buf)
return buf, err
}
func NewUnexportedReader() unexportedReader { // want "unexported interface 'unexportedReader' used as return value in exported function 'NewUnexportedReader'"
return nil // stub
}
================================================
FILE: pkg/golinters/iface/testdata/iface_unexported.yml
================================================
version: "2"
linters:
settings:
iface:
enable:
- unexported
================================================
FILE: pkg/golinters/iface/testdata/iface_unused.go
================================================
//golangcitest:args -Eiface
//golangcitest:config_path testdata/iface_unused.yml
package testdata
import "fmt"
// identical
type Pinger interface { // want "unused: interface 'Pinger' is declared but not used within the package"
Ping() error
}
type Healthcheck interface { // want "unused: interface 'Healthcheck' is declared but not used within the package"
Ping() error
}
// opaque
type Server interface {
Serve() error
}
type server struct {
addr string
}
func (s server) Serve() error {
return nil
}
func NewServer(addr string) Server {
return &server{addr: addr}
}
// unused
type User struct {
ID string
Name string
}
type UserRepository interface { // want "unused: interface 'UserRepository' is declared but not used within the package"
UserOf(id string) (*User, error)
}
type UserRepositorySQL struct {
}
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}
type Granter interface {
Grant(permission string) error
}
func AllowAll(g Granter) error {
return g.Grant("all")
}
type Allower interface {
Allow(permission string) error
}
func Allow(x any) {
_ = x.(Allower)
fmt.Println("allow")
}
================================================
FILE: pkg/golinters/iface/testdata/iface_unused.yml
================================================
version: "2"
linters:
settings:
iface:
enable:
- unused
================================================
FILE: pkg/golinters/importas/importas.go
================================================
package importas
import (
"fmt"
"strconv"
"strings"
"github.com/julz/importas"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/lint/linter"
)
func New(settings *config.ImportAsSettings) *goanalysis.Linter {
analyzer := importas.Analyzer
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithContextSetter(func(lintCtx *linter.Context) {
if settings == nil {
return
}
if len(settings.Alias) == 0 {
lintCtx.Log.Infof("importas settings found, but no aliases listed. List aliases under alias: key.")
}
if err := analyzer.Flags.Set("no-unaliased", strconv.FormatBool(settings.NoUnaliased)); err != nil {
lintCtx.Log.Errorf("failed to parse configuration: %v", err)
}
if err := analyzer.Flags.Set("no-extra-aliases", strconv.FormatBool(settings.NoExtraAliases)); err != nil {
lintCtx.Log.Errorf("failed to parse configuration: %v", err)
}
uniqPackages := make(map[string]config.ImportAsAlias)
uniqAliases := make(map[string]config.ImportAsAlias)
for _, a := range settings.Alias {
if a.Pkg == "" {
lintCtx.Log.Errorf("invalid configuration, empty package: pkg=%s alias=%s", a.Pkg, a.Alias)
continue
}
if v, ok := uniqPackages[a.Pkg]; ok {
lintCtx.Log.Errorf("invalid configuration, multiple aliases for the same package: pkg=%s aliases=[%s,%s]", a.Pkg, a.Alias, v.Alias)
} else {
uniqPackages[a.Pkg] = a
}
// Skips the duplication check when:
// - the alias is empty.
// - the alias is a regular expression replacement pattern (ie. contains `$`).
v, ok := uniqAliases[a.Alias]
if ok && a.Alias != "" && !strings.Contains(a.Alias, "$") {
lintCtx.Log.Errorf("invalid configuration, multiple packages with the same alias: alias=%s packages=[%s,%s]", a.Alias, a.Pkg, v.Pkg)
} else {
uniqAliases[a.Alias] = a
}
err := analyzer.Flags.Set("alias", fmt.Sprintf("%s:%s", a.Pkg, a.Alias))
if err != nil {
lintCtx.Log.Errorf("failed to parse configuration: %v", err)
}
}
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/importas/importas_integration_test.go
================================================
package importas
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/importas/testdata/fix/in/importas.go
================================================
//golangcitest:args -Eimportas
//golangcitest:config_path testdata/importas.yml
//golangcitest:expected_exitcode 0
package testdata
import (
wrong_alias "fmt"
"os"
wrong_alias_again "os"
wrong "golang.org/x/tools/go/analysis"
)
func ImportAsWrongAlias() {
wrong_alias.Println("foo")
wrong_alias_again.Stdout.WriteString("bar")
os.Stdout.WriteString("test")
_ = wrong.Analyzer{}
}
================================================
FILE: pkg/golinters/importas/testdata/fix/out/importas.go
================================================
//golangcitest:args -Eimportas
//golangcitest:config_path testdata/importas.yml
//golangcitest:expected_exitcode 0
package testdata
import (
fff "fmt"
"os"
std_os "os"
ananas "golang.org/x/tools/go/analysis"
)
func ImportAsWrongAlias() {
fff.Println("foo")
std_os.Stdout.WriteString("bar")
os.Stdout.WriteString("test")
_ = ananas.Analyzer{}
}
================================================
FILE: pkg/golinters/importas/testdata/importas.go
================================================
//golangcitest:args -Eimportas
//golangcitest:config_path testdata/importas.yml
package testdata
import (
wrong_alias "fmt" // want `import "fmt" imported as "wrong_alias" but must be "fff" according to config`
"os"
wrong_alias_again "os" // want `import "os" imported as "wrong_alias_again" but must be "std_os" according to config`
wrong "golang.org/x/tools/go/analysis" // want `import "golang.org/x/tools/go/analysis" imported as "wrong" but must be "ananas" according to config`
)
func ImportAsWrongAlias() {
wrong_alias.Println("foo")
wrong_alias_again.Stdout.WriteString("bar")
os.Stdout.WriteString("test")
_ = wrong.Analyzer{}
}
================================================
FILE: pkg/golinters/importas/testdata/importas.yml
================================================
version: "2"
linters:
settings:
importas:
alias:
- pkg: fmt
alias: fff
- pkg: os
alias: std_os
- pkg: golang.org/x/tools/go/analysis
alias: ananas
================================================
FILE: pkg/golinters/importas/testdata/importas_cgo.go
================================================
//golangcitest:args -Eimportas
//golangcitest:config_path testdata/importas.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
wrong_alias "fmt" // want `import "fmt" imported as "wrong_alias" but must be "fff" according to config`
"os"
wrong_alias_again "os" // want `import "os" imported as "wrong_alias_again" but must be "std_os" according to config`
"unsafe"
wrong "golang.org/x/tools/go/analysis" // want `import "golang.org/x/tools/go/analysis" imported as "wrong" but must be "ananas" according to config`
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
wrong_alias.Println("foo")
wrong_alias_again.Stdout.WriteString("bar")
os.Stdout.WriteString("test")
_ = wrong.Analyzer{}
}
================================================
FILE: pkg/golinters/importas/testdata/importas_several_empty_aliases.go
================================================
//golangcitest:args -Eimportas
//golangcitest:config_path testdata/importas_several_empty_aliases.yml
//golangcitest:expected_exitcode 0
package testdata
import (
"fmt"
"math"
"os"
)
func _() {
fmt.Println("a")
fmt.Fprint(os.Stderr, "b")
println(math.MaxInt)
}
================================================
FILE: pkg/golinters/importas/testdata/importas_several_empty_aliases.yml
================================================
version: "2"
linters:
settings:
importas:
alias:
- pkg: fmt
alias: ''
- pkg: os
alias: ''
- pkg: math
alias: ''
================================================
FILE: pkg/golinters/importas/testdata/importas_strict.go
================================================
//golangcitest:args -Eimportas
//golangcitest:config_path testdata/importas_strict.yml
package testdata
import (
wrong_alias "fmt" // want `import "fmt" imported as "wrong_alias" but must be "fff" according to config`
"os" // want `import "os" imported without alias but must be with alias "std_os" according to config`
wrong_alias_again "os" // want `import "os" imported as "wrong_alias_again" but must be "std_os" according to config`
wrong "golang.org/x/tools/go/analysis" // want `import "golang.org/x/tools/go/analysis" imported as "wrong" but must be "ananas" according to config`
)
func ImportAsStrictWrongAlias() {
wrong_alias.Println("foo")
wrong_alias_again.Stdout.WriteString("bar")
os.Stdout.WriteString("test")
_ = wrong.Analyzer{}
}
================================================
FILE: pkg/golinters/importas/testdata/importas_strict.yml
================================================
version: "2"
linters:
settings:
importas:
no-unaliased: true
alias:
- pkg: fmt
alias: fff
- pkg: os
alias: std_os
- pkg: golang.org/x/tools/go/analysis
alias: ananas
================================================
FILE: pkg/golinters/inamedparam/inamedparam.go
================================================
package inamedparam
import (
"github.com/macabu/inamedparam"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.INamedParamSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"skip-single-param": settings.SkipSingleParam,
}
}
return goanalysis.
NewLinterFromAnalyzer(inamedparam.Analyzer).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/inamedparam/inamedparam_integration_test.go
================================================
package inamedparam
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/inamedparam/testdata/inamedparam.go
================================================
//golangcitest:args -Einamedparam
package testdata
import "context"
type tStruct struct {
a int
}
type Doer interface {
Do() string
}
type NamedParam interface {
Void()
NoArgs() string
WithName(ctx context.Context, number int, toggle bool, tStruct *tStruct, doer Doer) (bool, error)
WithoutName(
context.Context, // want "interface method WithoutName must have named param for type context.Context"
int, // want "interface method WithoutName must have named param for type int"
bool, // want "interface method WithoutName must have named param for type bool"
tStruct, // want "interface method WithoutName must have named param for type tStruct"
Doer, // want "interface method WithoutName must have named param for type Doer"
struct{ b bool }, // want "interface method WithoutName must have all named params"
)
}
================================================
FILE: pkg/golinters/inamedparam/testdata/inamedparam_cgo.go
================================================
//golangcitest:args -Einamedparam
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"context"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type tStruct struct {
a int
}
type Doer interface {
Do() string
}
type NamedParam interface {
Void()
NoArgs() string
WithName(ctx context.Context, number int, toggle bool, tStruct *tStruct, doer Doer) (bool, error)
WithoutName(
context.Context, // want "interface method WithoutName must have named param for type context.Context"
int, // want "interface method WithoutName must have named param for type int"
bool, // want "interface method WithoutName must have named param for type bool"
tStruct, // want "interface method WithoutName must have named param for type tStruct"
Doer, // want "interface method WithoutName must have named param for type Doer"
struct{ b bool }, // want "interface method WithoutName must have all named params"
)
}
================================================
FILE: pkg/golinters/inamedparam/testdata/inamedparam_skip_single_param.go
================================================
//golangcitest:args -Einamedparam
//golangcitest:config_path testdata/inamedparam_skip_single_param.yml
package testdata
import "context"
type NamedParam interface {
Void()
SingleParam(string) error
WithName(ctx context.Context, number int, toggle bool) (bool, error)
WithoutName(
context.Context, // want "interface method WithoutName must have named param for type context.Context"
int, // want "interface method WithoutName must have named param for type int"
)
}
================================================
FILE: pkg/golinters/inamedparam/testdata/inamedparam_skip_single_param.yml
================================================
version: "2"
linters:
settings:
inamedparam:
skip-single-param: true
================================================
FILE: pkg/golinters/ineffassign/ineffassign.go
================================================
package ineffassign
import (
"github.com/gordonklaus/ineffassign/pkg/ineffassign"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.IneffassignSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"check-escaping-errors": settings.CheckEscapingErrors,
}
}
return goanalysis.
NewLinterFromAnalyzer(ineffassign.Analyzer).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/ineffassign/ineffassign_integration_test.go
================================================
package ineffassign
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/ineffassign/testdata/ineffassign.go
================================================
//golangcitest:args -Eineffassign
package testdata
import "math"
func _() {
x := math.MinInt8
for {
_ = x
x = 0 // want "ineffectual assignment to x"
x = 0
}
}
================================================
FILE: pkg/golinters/ineffassign/testdata/ineffassign_cgo.go
================================================
//go:build ignore
// TODO(ldez) the linter doesn't support cgo.
//golangcitest:args -Eineffassign
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"math"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
x := math.MinInt8
for {
_ = x
x = 0 // want "ineffectual assignment to x"
x = 0
}
}
================================================
FILE: pkg/golinters/interfacebloat/interfacebloat.go
================================================
package interfacebloat
import (
"github.com/sashamelentyev/interfacebloat/pkg/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.InterfaceBloatSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
analyzer.InterfaceMaxMethodsFlag: settings.Max,
}
}
return goanalysis.
NewLinterFromAnalyzer(analyzer.New()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/interfacebloat/interfacebloat_integration_test.go
================================================
package interfacebloat
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/interfacebloat/testdata/interfacebloat.go
================================================
//golangcitest:args -Einterfacebloat
package testdata
import "time"
type InterfaceBloatExample01 interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}
func InterfaceBloatExample02() {
var _ interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}
}
func InterfaceBloatExample03() interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
} {
return nil
}
type InterfaceBloatExample04 struct {
Foo interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}
}
type InterfaceBloatSmall01 interface {
a01() time.Duration
a02()
a03()
a04()
a05()
}
type InterfaceBloatSmall02 interface {
a06()
a07()
a08()
a09()
a10()
a11()
}
type InterfaceBloatExample05 interface {
InterfaceBloatSmall01
InterfaceBloatSmall02
}
type InterfaceBloatExample06 interface {
interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}
}
type InterfaceBloatTypeGeneric interface {
~uint8 | ~uint16 | ~uint32 | ~uint64 | uint |
~int8 | ~int16 | ~int32 | ~int64 | int |
~float32 | ~float64 |
~string
}
func InterfaceBloatExampleNoProblem() interface {
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
} {
return nil
}
================================================
FILE: pkg/golinters/interfacebloat/testdata/interfacebloat_cgo.go
================================================
//golangcitest:args -Einterfacebloat
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"time"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type _ interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}
================================================
FILE: pkg/golinters/internal/commons.go
================================================
package internal
import "github.com/golangci/golangci-lint/v2/pkg/logutils"
// LinterLogger must be use only when the context logger is not available.
var LinterLogger = logutils.NewStderrLog(logutils.DebugKeyLinter)
================================================
FILE: pkg/golinters/internal/util.go
================================================
package internal
import (
"fmt"
"strings"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func FormatCode(code string) string {
if strings.Contains(code, "`") {
return code // TODO: properly escape or remove
}
return fmt.Sprintf("`%s`", code)
}
func GetGoFileNames(pass *analysis.Pass) []string {
var filenames []string
for _, f := range pass.Files {
position, b := goanalysis.GetGoFilePosition(pass, f)
if !b {
continue
}
filenames = append(filenames, position.Filename)
}
return filenames
}
================================================
FILE: pkg/golinters/intrange/intrange.go
================================================
package intrange
import (
"github.com/ckaznocha/intrange"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(intrange.Analyzer).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/intrange/intrange_integration_test.go
================================================
package intrange
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/intrange/testdata/fix/in/intrange.go
================================================
//go:build go1.22
//golangcitest:args -Eintrange
//golangcitest:expected_exitcode 0
package testdata
import "math"
func CheckIntrange() {
for i := 0; i < 10; i++ {
}
for i := uint8(0); i < math.MaxInt8; i++ {
}
for i := 0; i < 10; i += 2 {
}
for i := 0; i < 10; i++ {
i += 1
}
}
================================================
FILE: pkg/golinters/intrange/testdata/fix/out/intrange.go
================================================
//go:build go1.22
//golangcitest:args -Eintrange
//golangcitest:expected_exitcode 0
package testdata
import "math"
func CheckIntrange() {
for range 10 {
}
for range uint8(math.MaxInt8) {
}
for i := 0; i < 10; i += 2 {
}
for i := 0; i < 10; i++ {
i += 1
}
}
================================================
FILE: pkg/golinters/intrange/testdata/intrange.go
================================================
//go:build go1.22
//golangcitest:args -Eintrange
package testdata
import "math"
func CheckIntrange() {
for i := 0; i < 10; i++ { // want `for loop can be changed to use an integer range \(Go 1\.22\+\)`
}
for i := uint8(0); i < math.MaxInt8; i++ { // want `for loop can be changed to use an integer range \(Go 1\.22\+\)`
}
for i := 0; i < 10; i += 2 {
}
for i := 0; i < 10; i++ {
i += 1
}
}
================================================
FILE: pkg/golinters/intrange/testdata/intrange_cgo.go
================================================
//go:build go1.22
//golangcitest:args -Eintrange
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"math"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func CheckIntrange() {
for i := 0; i < 10; i++ { // want `for loop can be changed to use an integer range \(Go 1\.22\+\)`
}
for i := uint8(0); i < math.MaxInt8; i++ { // want `for loop can be changed to use an integer range \(Go 1\.22\+\)`
}
for i := 0; i < 10; i += 2 {
}
for i := 0; i < 10; i++ {
i += 1
}
}
================================================
FILE: pkg/golinters/iotamixing/iotamixing.go
================================================
package iotamixing
import (
im "github.com/AdminBenni/iota-mixing/pkg/analyzer"
"github.com/AdminBenni/iota-mixing/pkg/analyzer/flags"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.IotaMixingSettings) *goanalysis.Linter {
cfg := map[string]any{}
if settings != nil {
cfg[flags.ReportIndividualFlagName] = settings.ReportIndividual
}
analyzer := im.GetIotaMixingAnalyzer()
flags.SetupFlags(&analyzer.Flags)
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/iotamixing/iotamixing_integration_test.go
================================================
package iotamixing
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/iotamixing/testdata/iotamixing.go
================================================
//golangcitest:args -Eiotamixing
package testdata
import "fmt"
// iota mixing in const block containing an iota and r-val declared above.
const ( // want "iota mixing. keep iotas in separate blocks to consts with r-val"
InvalidPerBlockIotaDeclAboveAnything = "anything"
InvalidPerBlockIotaDeclAboveNotZero = iota
InvalidPerBlockIotaDeclAboveNotOne
InvalidPerBlockIotaDeclAboveNotTwo
)
// iota mixing in const block containing an iota and r-val declared below.
const ( // want "iota mixing. keep iotas in separate blocks to consts with r-val"
InvalidPerBlockIotaDeclBelowZero = iota
InvalidPerBlockIotaDeclBelowOne
InvalidPerBlockIotaDeclBelowTwo
InvalidPerBlockIotaDeclBelowAnything = "anything"
)
// iota mixing in const block containing an iota and r-val declared between consts.
const ( // want "iota mixing. keep iotas in separate blocks to consts with r-val"
InvalidPerBlockIotaDeclBetweenZero = iota
InvalidPerBlockIotaDeclBetweenOne
InvalidPerBlockIotaDeclBetweenAnything = "anything"
InvalidPerBlockIotaDeclBetweenNotTwo
)
// iota mixing in const block containing an iota and r-vals declared above, between, and below consts.
const ( // want "iota mixing. keep iotas in separate blocks to consts with r-val"
InvalidPerBlockIotaDeclMultipleAbove = "above"
InvalidPerBlockIotaDeclMultipleNotZero = iota
InvalidPerBlockIotaDeclMultipleNotOne
InvalidPerBlockIotaDeclMultipleBetween = "between"
InvalidPerBlockIotaDeclMultipleNotTwo
InvalidPerBlockIotaDeclMultipleBelow = "below"
)
// no iota mixing in a const block containing an iota and no r-vals.
const (
ValidPerBlockIotaZero = iota
ValidPerBlockIotaOne
ValidPerBlockIotaTwo
)
// no iota mixing in a const block containing r-vals and no iota.
const (
ValidPerBlockRegularSomething = "something"
ValidPerBlockRegularAnything = "anything"
)
func _() {
fmt.Println("using the std import so goland doesn't nuke it")
}
================================================
FILE: pkg/golinters/iotamixing/testdata/iotamixing_report-individual.go
================================================
//golangcitest:args -Eiotamixing
//golangcitest:config_path testdata/iotamixing_report-individual.yml
package testdata
import "fmt"
const (
InvalidPerIndividualIotaDeclAboveAnything = "anything" // want "InvalidPerIndividualIotaDeclAboveAnything is a const with r-val in same const block as iota. keep iotas in separate const blocks"
InvalidPerIndividualIotaDeclAboveNotZero = iota
InvalidPerIndividualIotaDeclAboveNotOne
InvalidPerIndividualIotaDeclAboveNotTwo
)
const (
InvalidPerIndividualIotaDeclBelowZero = iota
InvalidPerIndividualIotaDeclBelowOne
InvalidPerIndividualIotaDeclBelowTwo
InvalidPerIndividualIotaDeclBelowAnything = "anything" // want "InvalidPerIndividualIotaDeclBelowAnything is a const with r-val in same const block as iota. keep iotas in separate const blocks"
)
const (
InvalidPerIndividualIotaDeclBetweenZero = iota
InvalidPerIndividualIotaDeclBetweenOne
InvalidPerIndividualIotaDeclBetweenAnything = "anything" // want "InvalidPerIndividualIotaDeclBetweenAnything is a const with r-val in same const block as iota. keep iotas in separate const blocks"
InvalidPerIndividualIotaDeclBetweenNotTwo
)
const (
InvalidPerIndividualIotaDeclMultipleAbove = "above" // want "InvalidPerIndividualIotaDeclMultipleAbove is a const with r-val in same const block as iota. keep iotas in separate const blocks"
InvalidPerIndividualIotaDeclMultipleNotZero = iota
InvalidPerIndividualIotaDeclMultipleNotOne
InvalidPerIndividualIotaDeclMultipleBetween = "between" // want "InvalidPerIndividualIotaDeclMultipleBetween is a const with r-val in same const block as iota. keep iotas in separate const blocks"
InvalidPerIndividualIotaDeclMultipleNotTwo
InvalidPerIndividualIotaDeclMultipleBelow = "below" // want "InvalidPerIndividualIotaDeclMultipleBelow is a const with r-val in same const block as iota. keep iotas in separate const blocks"
)
const (
ValidPerIndividualIotaZero = iota
ValidPerIndividualIotaOne
ValidPerIndividualIotaTwo
)
const (
ValidPerIndividualRegularSomething = "something"
ValidPerIndividualRegularAnything = "anything"
)
func _() {
fmt.Println("using the std import so goland doesn't nuke it")
}
================================================
FILE: pkg/golinters/iotamixing/testdata/iotamixing_report-individual.yml
================================================
version: "2"
linters:
settings:
iotamixing:
report-individual: true
================================================
FILE: pkg/golinters/ireturn/ireturn.go
================================================
package ireturn
import (
"strings"
"github.com/butuzov/ireturn/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.IreturnSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"allow": strings.Join(settings.Allow, ","),
"reject": strings.Join(settings.Reject, ","),
"nonolint": true,
}
}
return goanalysis.
NewLinterFromAnalyzer(analyzer.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/ireturn/ireturn_integration_test.go
================================================
package ireturn
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/ireturn/testdata/ireturn.go
================================================
//golangcitest:args -Eireturn
package testdata
type (
IreturnDoer interface{ Do() }
ireturnDoer struct{}
)
func New() IreturnDoer { return new(ireturnDoer) } // want `New returns interface \(command-line-arguments.IreturnDoer\)`
func (d *ireturnDoer) Do() { /*...*/ }
func Newer() *ireturnDoer { return new(ireturnDoer) }
================================================
FILE: pkg/golinters/ireturn/testdata/ireturn_allow.go
================================================
//golangcitest:args -Eireturn
//golangcitest:config_path testdata/ireturn_allow.yml
//golangcitest:expected_exitcode 0
package testdata
type (
IreturnAllowDoer interface{ Do() }
ireturnAllowDoer struct{}
)
func NewAllowDoer() IreturnAllowDoer { return new(ireturnAllowDoer) }
func (d *ireturnAllowDoer) Do() { /*...*/ }
func NewerAllowDoer() *ireturnAllowDoer { return new(ireturnAllowDoer) }
================================================
FILE: pkg/golinters/ireturn/testdata/ireturn_allow.yml
================================================
version: "2"
linters:
settings:
ireturn:
allow:
- IreturnAllowDoer
================================================
FILE: pkg/golinters/ireturn/testdata/ireturn_cgo.go
================================================
//golangcitest:args -Eireturn
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
type (
IreturnDoer interface{ Do() }
ireturnDoer struct{}
)
func _() IreturnDoer { return new(ireturnDoer) } // want `_ returns interface \(command-line-arguments.IreturnDoer\)`
func (d *ireturnDoer) Do() { /*...*/ }
func _() *ireturnDoer { return new(ireturnDoer) }
================================================
FILE: pkg/golinters/ireturn/testdata/ireturn_reject_generics.go
================================================
//golangcitest:args -Eireturn
//golangcitest:config_path testdata/ireturn_reject_generics.yml
package testdata
import (
"bytes"
"io"
)
func NewWriter() io.Writer {
var buf bytes.Buffer
return &buf
}
func TestError() error {
return nil
}
func Get[K comparable, V int64 | float64](m map[K]V) V { // want `Get returns generic interface \(V\)`
var s V
for _, v := range m {
s += v
}
return s
}
================================================
FILE: pkg/golinters/ireturn/testdata/ireturn_reject_generics.yml
================================================
version: "2"
linters:
settings:
ireturn:
reject:
- generic
================================================
FILE: pkg/golinters/ireturn/testdata/ireturn_reject_stdlib.go
================================================
//golangcitest:args -Eireturn
//golangcitest:config_path testdata/ireturn_reject_stdlib.yml
package testdata
import (
"bytes"
"io"
)
func NewWriter() io.Writer { // want `NewWriter returns interface \(io.Writer\)`
var buf bytes.Buffer
return &buf
}
func TestError() error {
return nil
}
type Foo interface {
Foo()
}
type foo int
func (f foo) Foo() {}
func NewFoo() Foo {
return foo(1)
}
================================================
FILE: pkg/golinters/ireturn/testdata/ireturn_reject_stdlib.yml
================================================
version: "2"
linters:
settings:
ireturn:
reject:
- stdlib
================================================
FILE: pkg/golinters/lll/lll.go
================================================
package lll
import (
"bufio"
"errors"
"fmt"
"go/ast"
"os"
"strings"
"unicode/utf8"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const goCommentDirectivePrefix = "//go:"
func New(settings *config.LllSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: "lll",
Doc: "Reports long lines",
Run: func(pass *analysis.Pass) (any, error) {
err := runLll(pass, settings)
if err != nil {
return nil, err
}
return nil, nil
},
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func runLll(pass *analysis.Pass, settings *config.LllSettings) error {
spaces := strings.Repeat(" ", settings.TabWidth)
for _, file := range pass.Files {
err := getLLLIssuesForFile(pass, file, settings.LineLength, spaces)
if err != nil {
return err
}
}
return nil
}
func getLLLIssuesForFile(pass *analysis.Pass, file *ast.File, maxLineLen int, tabSpaces string) error {
position, isGoFile := goanalysis.GetGoFilePosition(pass, file)
if !isGoFile {
return nil
}
nonAdjPosition := pass.Fset.PositionFor(file.Pos(), false)
f, err := os.Open(position.Filename)
if err != nil {
return fmt.Errorf("can't open file %s: %w", position.Filename, err)
}
defer f.Close()
ft := pass.Fset.File(file.Pos())
lineNumber := 0
multiImportEnabled := false
scanner := bufio.NewScanner(f)
for scanner.Scan() {
lineNumber++
line := scanner.Text()
line = strings.ReplaceAll(line, "\t", tabSpaces)
if strings.HasPrefix(line, goCommentDirectivePrefix) {
continue
}
if strings.HasPrefix(line, "import") {
multiImportEnabled = strings.HasSuffix(line, "(")
continue
}
if multiImportEnabled {
if line == ")" {
multiImportEnabled = false
}
continue
}
lineLen := utf8.RuneCountInString(line)
if lineLen > maxLineLen {
pass.Report(analysis.Diagnostic{
Pos: ft.LineStart(goanalysis.AdjustPos(lineNumber, nonAdjPosition.Line, position.Line)),
Message: fmt.Sprintf("The line is %d characters long, which exceeds the maximum of %d characters.",
lineLen, maxLineLen),
})
}
}
if err := scanner.Err(); err != nil {
// scanner.Scan() might fail if the line is longer than bufio.MaxScanTokenSize
// In the case where the specified maxLineLen is smaller than bufio.MaxScanTokenSize
// we can return this line as a long line instead of returning an error.
// The reason for this change is that this case might happen with autogenerated files
// The go-bindata tool for instance might generate a file with a very long line.
// In this case, as it's an auto generated file, the warning returned by lll will
// be ignored.
// But if we return a linter error here, and this error happens for an autogenerated
// file the error will be discarded (fine), but all the subsequent errors for lll will
// be discarded for other files, and we'll miss legit error.
if errors.Is(err, bufio.ErrTooLong) && maxLineLen < bufio.MaxScanTokenSize {
pass.Report(analysis.Diagnostic{
Pos: ft.LineStart(goanalysis.AdjustPos(lineNumber, nonAdjPosition.Line, position.Line)),
Message: fmt.Sprintf("line is more than %d characters", bufio.MaxScanTokenSize),
})
} else {
return fmt.Errorf("can't scan file %s: %w", position.Filename, err)
}
}
return nil
}
================================================
FILE: pkg/golinters/lll/lll_integration_test.go
================================================
package lll
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/lll/testdata/lll.go
================================================
//golangcitest:args -Elll
//golangcitest:config_path testdata/lll.yml
package testdata
import (
_ "unsafe"
)
func Lll() {
// want +1 "line is 141 characters"
// In my experience, long lines are the lines with comments, not the code. So this is a long comment, a very long comment, yes very long.
}
//go:generate mockgen -source lll.go -destination a_verylong_generate_mock_my_lll_interface.go --package testdata -self_package github.com/golangci/golangci-lint/test/testdata
type MyLllInterface interface {
}
//go:linkname VeryLongNameForTestAndLinkNameFunction github.com/golangci/golangci-lint/test/testdata.VeryLongNameForTestAndLinkedNameFunction
func VeryLongNameForTestAndLinkNameFunction()
func VeryLongNameForTestAndLinkedNameFunction() {}
================================================
FILE: pkg/golinters/lll/testdata/lll.yml
================================================
version: "2"
linters:
settings:
lll:
tab-width: 4
================================================
FILE: pkg/golinters/lll/testdata/lll_cgo.go
================================================
//golangcitest:args -Elll
//golangcitest:config_path testdata/lll.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
// want +1 "The line is 137 characters long, which exceeds the maximum of 120 characters."
// In my experience, long lines are the lines with comments, not the code. So this is a long comment, a very long comment, yes very long.
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
================================================
FILE: pkg/golinters/lll/testdata/lll_import.yml
================================================
version: "2"
linters:
settings:
lll:
tab-width: 4
line-length: 60
================================================
FILE: pkg/golinters/lll/testdata/lll_import_multi.go
================================================
//golangcitest:args -Elll
//golangcitest:config_path testdata/lll_import.yml
//golangcitest:expected_exitcode 0
package testdata
import (
anotherVeryLongImportAliasNameForTest "github.com/golangci/golangci-lint/v2/internal/golinters"
veryLongImportAliasNameForTest "github.com/golangci/golangci-lint/v2/internal/golinters"
)
func LllMultiImport() {
_ = veryLongImportAliasNameForTest.NewLLL(nil)
_ = anotherVeryLongImportAliasNameForTest.NewLLL(nil)
}
================================================
FILE: pkg/golinters/lll/testdata/lll_import_single.go
================================================
//golangcitest:args -Elll
//golangcitest:config_path testdata/lll_import.yml
//golangcitest:expected_exitcode 0
package testdata
import veryLongImportAliasNameForTest "github.com/golangci/golangci-lint/v2/internal/golinters"
func LllSingleImport() {
_ = veryLongImportAliasNameForTest.NewLLL(nil)
}
================================================
FILE: pkg/golinters/lll/testdata/lll_max_scan_token_size.go
================================================
//golangcitest:args -Elll
//golangcitest:config_path testdata/lll.yml
package testdata
// want "line is more than 65536 characters"
// Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus.
================================================
FILE: pkg/golinters/lll/testdata/lll_max_scan_token_size_cgo.go
================================================
//golangcitest:args -Elll
//golangcitest:config_path testdata/lll.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
// want "line is more than 65536 characters"
// Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar varius. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In auctor lobortis lacus. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna. Vestibulum ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia erat. Praesent blandit laoreet nibh. Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In consectetuer turpis ut velit. Nulla sit amet est. Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Curabitur suscipit suscipit tellus. Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu quis ligula mattis placerat. Duis lobortis massa imperdiet quam. Suspendisse potenti. Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. Vestibulum eu odio. Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna cursus.
================================================
FILE: pkg/golinters/loggercheck/loggercheck.go
================================================
package loggercheck
import (
"github.com/timonwong/loggercheck"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.LoggerCheckSettings) *goanalysis.Linter {
var opts []loggercheck.Option
if settings != nil {
var disable []string
if !settings.Kitlog {
disable = append(disable, "kitlog")
}
if !settings.Klog {
disable = append(disable, "klog")
}
if !settings.Logr {
disable = append(disable, "logr")
}
if !settings.Slog {
disable = append(disable, "slog")
}
if !settings.Zap {
disable = append(disable, "zap")
}
opts = []loggercheck.Option{
loggercheck.WithDisable(disable),
loggercheck.WithRequireStringKey(settings.RequireStringKey),
loggercheck.WithRules(settings.Rules),
loggercheck.WithNoPrintfLike(settings.NoPrintfLike),
}
}
return goanalysis.
NewLinterFromAnalyzer(loggercheck.NewAnalyzer(opts...)).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/loggercheck/loggercheck_integration_test.go
================================================
package loggercheck
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/loggercheck/testdata/go.mod
================================================
module loggercheck
go 1.25.0
require (
github.com/go-kit/log v0.2.1
github.com/go-logr/logr v1.4.3
go.uber.org/zap v1.27.1
k8s.io/klog/v2 v2.130.1
)
require (
github.com/go-logfmt/logfmt v0.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
)
================================================
FILE: pkg/golinters/loggercheck/testdata/go.sum
================================================
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_cgo.go
================================================
//golangcitest:args -Eloggercheck
package loggercheck
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"log/slog"
"unsafe"
"github.com/go-logr/logr"
"go.uber.org/zap"
"k8s.io/klog/v2"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func ExampleDefaultLogr() {
log := logr.Discard()
log = log.WithValues("key") // want `odd number of arguments passed as key-value pairs for logging`
log.Info("message", "key1", "value1", "key2", "value2", "key3") // want `odd number of arguments passed as key-value pairs for logging`
log.Error(fmt.Errorf("error"), "message", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
log.Error(fmt.Errorf("error"), "message", "key1", "value1", "key2", "value2")
}
func ExampleDefaultKlog() {
klog.InfoS("message", "key1") // want `odd number of arguments passed as key-value pairs for logging`
}
func ExampleZapSugarNotChecked() {
sugar := zap.NewExample().Sugar()
defer sugar.Sync()
sugar.Infow("message", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
}
func ExampleSlog() {
logger := slog.With("key1", "value1")
logger.Info("msg", "key1") // want `odd number of arguments passed as key-value pairs for logging`
slog.Info("msg", "key1") // want `odd number of arguments passed as key-value pairs for logging`
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_custom.go
================================================
//golangcitest:args -Eloggercheck
//golangcitest:config_path testdata/loggercheck_custom.yml
package loggercheck
import (
"errors"
"go.uber.org/zap"
)
var l = New()
type Logger struct {
s *zap.SugaredLogger
}
func New() *Logger {
logger := zap.NewExample().Sugar()
return &Logger{s: logger}
}
func (l *Logger) With(keysAndValues ...interface{}) *Logger {
return &Logger{
s: l.s.With(keysAndValues...),
}
}
func (l *Logger) Debugw(msg string, keysAndValues ...interface{}) {
l.s.Debugw(msg, keysAndValues...)
}
func (l *Logger) Infow(msg string, keysAndValues ...interface{}) {
l.s.Infow(msg, keysAndValues...)
}
func (l *Logger) Warnw(msg string, keysAndValues ...interface{}) {
l.s.Warnw(msg, keysAndValues...)
}
func (l *Logger) Errorw(msg string, keysAndValues ...interface{}) {
l.s.Errorw(msg, keysAndValues...)
}
func (l *Logger) Fatalw(msg string, keysAndValues ...interface{}) {
l.s.Fatalw(msg, keysAndValues...)
}
func (l *Logger) Sync() error {
return l.s.Sync()
}
// package level wrap func
func With(keysAndValues ...interface{}) *Logger {
return &Logger{
s: l.s.With(keysAndValues...),
}
}
func Debugw(msg string, keysAndValues ...interface{}) {
l.s.Debugw(msg, keysAndValues...)
}
func Infow(msg string, keysAndValues ...interface{}) {
l.s.Infow(msg, keysAndValues...)
}
func Warnw(msg string, keysAndValues ...interface{}) {
l.s.Warnw(msg, keysAndValues...)
}
func Errorw(msg string, keysAndValues ...interface{}) {
l.s.Errorw(msg, keysAndValues...)
}
func Fatalw(msg string, keysAndValues ...interface{}) {
l.s.Fatalw(msg, keysAndValues...)
}
func Sync() error {
return l.s.Sync()
}
func ExampleCustomLogger() {
err := errors.New("example error")
// custom SugaredLogger
log := New()
defer log.Sync()
log.Infow("abc", "key1", "value1")
log.Infow("abc", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
log.Errorw("message", "err", err, "key1", "value1")
log.Errorw("message", err, "key1", "value1", "key2", "value2") // want `odd number of arguments passed as key-value pairs for logging`
// with test
log.With("with_key1", "with_value1").Infow("message", "key1", "value1")
log.With("with_key1", "with_value1").Infow("message", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
log.With("with_key1").Infow("message", "key1", "value1") // want `odd number of arguments passed as key-value pairs for logging`
}
func ExampleCustomLoggerPackageLevelFunc() {
err := errors.New("example error")
defer Sync()
Infow("abc", "key1", "value1")
Infow("abc", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
Errorw("message", "err", err, "key1", "value1")
Errorw("message", err, "key1", "value1", "key2", "value2") // want `odd number of arguments passed as key-value pairs for logging`
// with test
With("with_key1", "with_value1").Infow("message", "key1", "value1")
With("with_key1", "with_value1").Infow("message", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
With("with_key1").Infow("message", "key1", "value1") // want `odd number of arguments passed as key-value pairs for logging`
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_custom.yml
================================================
version: "2"
linters:
settings:
loggercheck:
rules:
- (*command-line-arguments.Logger).Debugw
- (*command-line-arguments.Logger).Infow
- (*command-line-arguments.Logger).Warnw
- (*command-line-arguments.Logger).Errorw
- (*command-line-arguments.Logger).With
- command-line-arguments.Debugw
- command-line-arguments.Infow
- command-line-arguments.Warnw
- command-line-arguments.Errorw
- command-line-arguments.With
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_default.go
================================================
//golangcitest:args -Eloggercheck
package loggercheck
import (
"fmt"
"log/slog"
"github.com/go-logr/logr"
"go.uber.org/zap"
"k8s.io/klog/v2"
)
func ExampleDefaultLogr() {
log := logr.Discard()
log = log.WithValues("key") // want `odd number of arguments passed as key-value pairs for logging`
log.Info("message", "key1", "value1", "key2", "value2", "key3") // want `odd number of arguments passed as key-value pairs for logging`
log.Error(fmt.Errorf("error"), "message", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
log.Error(fmt.Errorf("error"), "message", "key1", "value1", "key2", "value2")
}
func ExampleDefaultKlog() {
klog.InfoS("message", "key1") // want `odd number of arguments passed as key-value pairs for logging`
}
func ExampleZapSugarNotChecked() {
sugar := zap.NewExample().Sugar()
defer sugar.Sync()
sugar.Infow("message", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
}
func ExampleSlog() {
logger := slog.With("key1", "value1")
logger.Info("msg", "key1") // want `odd number of arguments passed as key-value pairs for logging`
slog.Info("msg", "key1") // want `odd number of arguments passed as key-value pairs for logging`
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_kitlogonly.go
================================================
//golangcitest:args -Eloggercheck
//golangcitest:config_path testdata/loggercheck_kitlogonly.yml
package loggercheck
import (
kitlog "github.com/go-kit/log"
"github.com/go-logr/logr"
"go.uber.org/zap"
"k8s.io/klog/v2"
)
func ExampleKitLogOnly_NoLogr() {
log := logr.Discard()
log.Info("message", "key1", "value1", "key2", "value2", "key3")
klog.InfoS("message", "key1")
sugar := zap.NewExample().Sugar()
sugar.Infow("message", "key1", "value1", "key2")
sugar.Errorw("error message", "key1")
}
func ExampleKitLogOnly() {
logger := kitlog.NewNopLogger()
logger.Log("msg", "message", "key1", "value1")
logger.Log("msg") // want `odd number of arguments passed as key-value pairs for logging`
logger.Log("msg", "message", "key1") // want `odd number of arguments passed as key-value pairs for logging`
kitlog.With(logger, "key1", "value1").Log("msg", "message")
kitlog.With(logger, "key1").Log("msg", "message") // want `odd number of arguments passed as key-value pairs for logging`
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_kitlogonly.yml
================================================
version: "2"
linters:
settings:
loggercheck:
kitlog: true
klog: false
logr: false
slog: false
zap: false
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_logronly.go
================================================
//golangcitest:args -Eloggercheck
//golangcitest:config_path testdata/loggercheck_logronly.yml
package loggercheck
import (
"fmt"
"github.com/go-logr/logr"
"go.uber.org/zap"
"k8s.io/klog/v2"
)
func ExampleLogrOnly() {
log := logr.Discard()
log.Info("message", "key1", "value1", "key2", "value2", "key3") // want `odd number of arguments passed as key-value pairs for logging`
klog.InfoS("message", "key1")
sugar := zap.NewExample().Sugar()
sugar.Infow("message", "key1", "value1", "key2")
sugar.Errorw("error message", "key1")
// Will not check by default (-requirestringkey)
log.Error(fmt.Errorf("error"), "message", []byte("key1"), "value1")
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_logronly.yml
================================================
version: "2"
linters:
settings:
loggercheck:
logr: true
klog: false
slog: false
zap: false
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_noprintflike.go
================================================
//golangcitest:args -Eloggercheck
//golangcitest:config_path testdata/loggercheck_noprintflike.yml
package loggercheck
import (
"github.com/go-logr/logr"
)
func ExampleNoPrintfLike() {
log := logr.Discard()
log.Info("This message is ok")
log.Info("Should not contains printf like format specifiers: %s %d %w") // want `logging message should not use format specifier "%s"`
log.Info("It also checks for the key value pairs", "key", "value %.2f") // want `logging message should not use format specifier "%\.2f"`
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_noprintflike.yml
================================================
version: "2"
linters:
settings:
loggercheck:
no-printf-like: true
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_requirestringkey.go
================================================
//golangcitest:args -Eloggercheck
//golangcitest:config_path testdata/loggercheck_requirestringkey.yml
package loggercheck
import (
"github.com/go-logr/logr"
)
func ExampleRequireStringKey() {
log := logr.Discard()
log.Info("message", "key1", "value1")
const key1 = "key1"
log.Info("message", key1, "value1")
key2 := []byte(key1)
log.Info("message", key2, "value2") // want `logging keys are expected to be inlined constant strings, please replace "key2" provided with string`
key3 := key1
log.Info("message", key3, "value3") // want `logging keys are expected to be inlined constant strings, please replace "key3" provided with string`
log.Info("message", "键1", "value1") // want `logging keys are expected to be alphanumeric strings, please remove any non-latin characters from "键1"`
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_requirestringkey.yml
================================================
version: "2"
linters:
settings:
loggercheck:
require-string-key: true
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_slogonly.go
================================================
//golangcitest:args -Eloggercheck
//golangcitest:config_path testdata/loggercheck_slogonly.yml
package loggercheck
import "log/slog"
func ExampleSlogOnly() {
logger := slog.With("key1", "value1")
logger.Info("msg", "key1") // want `odd number of arguments passed as key-value pairs for logging`
slog.Info("msg", "key1") // want `odd number of arguments passed as key-value pairs for logging`
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_slogonly.yml
================================================
version: "2"
linters:
settings:
loggercheck:
logr: false
klog: false
slog: true
zap: false
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_zaponly.go
================================================
//golangcitest:args -Eloggercheck
//golangcitest:config_path testdata/loggercheck_zaponly.yml
package loggercheck
import "go.uber.org/zap"
func ExampleZapOnly() {
sugar := zap.NewExample().Sugar()
sugar.Infow("message", "key1", "value1", "key2") // want `odd number of arguments passed as key-value pairs for logging`
sugar.Errorw("error message", "key1") // want `odd number of arguments passed as key-value pairs for logging`
}
================================================
FILE: pkg/golinters/loggercheck/testdata/loggercheck_zaponly.yml
================================================
version: "2"
linters:
settings:
loggercheck:
logr: false
klog: false
slog: false
zap: true
================================================
FILE: pkg/golinters/maintidx/maintidx.go
================================================
package maintidx
import (
"github.com/yagipy/maintidx"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.MaintIdxSettings) *goanalysis.Linter {
cfg := map[string]any{
"under": 20,
}
if settings != nil {
cfg["under"] = settings.Under
}
return goanalysis.
NewLinterFromAnalyzer(maintidx.Analyzer).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/maintidx/maintidx_integration_test.go
================================================
package maintidx
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/maintidx/testdata/maintidx.go
================================================
//golangcitest:args -Emaintidx
package testdata
func over20() {
}
func under20() { // want "Function name: under20, Cyclomatic Complexity: 76, Halstead Volume: 1636.00, Maintainability Index: 17"
for true {
if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
}
}
}
================================================
FILE: pkg/golinters/maintidx/testdata/maintidx_cgo.go
================================================
//golangcitest:args -Emaintidx
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"math"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() { // want "Function name: _, Cyclomatic Complexity: 77, Halstead Volume: 1718.01, Maintainability Index: 17"
for true {
if false {
if false {
n := 0
switch n {
case 0:
case 1:
case math.MaxInt:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
}
}
}
================================================
FILE: pkg/golinters/maintidx/testdata/maintidx_under_100.go
================================================
//golangcitest:args -Emaintidx
//golangcitest:config_path testdata/maintidx_under_100.yml
package testdata
func over20() { // want "Function name: over20, Cyclomatic Complexity: 1, Halstead Volume: 8.00, Maintainability Index: 86"
}
func under20() { // want "Function name: under20, Cyclomatic Complexity: 76, Halstead Volume: 1636.00, Maintainability Index: 17"
for true {
if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else if false {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
} else {
if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else if false {
n := 0
switch n {
case 0:
case 1:
default:
}
} else {
n := 0
switch n {
case 0:
case 1:
default:
}
}
}
}
}
================================================
FILE: pkg/golinters/maintidx/testdata/maintidx_under_100.yml
================================================
version: "2"
linters:
settings:
maintidx:
under: 100
================================================
FILE: pkg/golinters/makezero/makezero.go
================================================
package makezero
import (
"fmt"
"github.com/ashanbrown/makezero/v2/makezero"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.MakezeroSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: "makezero",
Doc: "Find slice declarations with non-zero initial length",
Run: func(pass *analysis.Pass) (any, error) {
err := runMakeZero(pass, settings)
if err != nil {
return nil, err
}
return nil, nil
},
}).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func runMakeZero(pass *analysis.Pass, settings *config.MakezeroSettings) error {
zero := makezero.NewLinter(settings.Always)
for _, file := range pass.Files {
hints, err := zero.Run(pass.Fset, pass.TypesInfo, file)
if err != nil {
return fmt.Errorf("makezero linter failed on file %q: %w", file.Name.String(), err)
}
for _, hint := range hints {
pass.Report(analysis.Diagnostic{
Pos: hint.Pos(),
Message: hint.Details(),
})
}
}
return nil
}
================================================
FILE: pkg/golinters/makezero/makezero_integration_test.go
================================================
package makezero
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/makezero/testdata/makezero.go
================================================
//golangcitest:args -Emakezero
package testdata
import "math"
func Makezero() []int {
x := make([]int, math.MaxInt8)
return append(x, 1) // want "append to slice `x` with non-zero initialized length"
}
func MakezeroMultiple() []int {
x, y := make([]int, math.MaxInt8), make([]int, math.MaxInt8)
return append(x, // want "append to slice `x` with non-zero initialized length"
append(y, 1)...) // want "append to slice `y` with non-zero initialized length"
}
func MakezeroNolint() []int {
x := make([]int, math.MaxInt8)
return append(x, 1) //nolint:makezero // ok that we're appending to an uninitialized slice
}
================================================
FILE: pkg/golinters/makezero/testdata/makezero_always.go
================================================
//golangcitest:args -Emakezero
//golangcitest:config_path testdata/makezero_always.yml
package testdata
import "math"
func MakezeroAlways() []int {
x := make([]int, math.MaxInt8) // want "slice `x` does not have non-zero initial length"
return x
}
func MakezeroAlwaysNolint() []int {
x := make([]int, math.MaxInt8) //nolint:makezero // ok that this is not initialized
return x
}
================================================
FILE: pkg/golinters/makezero/testdata/makezero_always.yml
================================================
version: "2"
linters:
settings:
makezero:
always: true
================================================
FILE: pkg/golinters/makezero/testdata/makezero_cgo.go
================================================
//golangcitest:args -Emakezero
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"math"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() []int {
x := make([]int, math.MaxInt8)
return append(x, 1) // want "append to slice `x` with non-zero initialized length"
}
================================================
FILE: pkg/golinters/mirror/mirror.go
================================================
package mirror
import (
"github.com/butuzov/mirror"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
// mirror only lints test files if the `--with-tests` flag is passed,
// so we pass the `with-tests` flag as true to the analyzer before running it.
// This can be turned off by using the regular golangci-lint flags such as `--tests` or `--skip-files`
// or can be disabled per linter via exclude rules.
// (see https://github.com/golangci/golangci-lint/issues/2527#issuecomment-1023707262)
cfg := map[string]any{
"with-tests": true,
}
return goanalysis.
NewLinterFromAnalyzer(mirror.NewAnalyzer()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/mirror/mirror_integration_test.go
================================================
package mirror
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/mirror/testdata/fix/in/mirror.go
================================================
//golangcitest:args -Emirror
//golangcitest:expected_exitcode 0
package testdata
import (
"unicode/utf8"
)
func foobar() {
_ = utf8.RuneCount([]byte("foobar"))
}
================================================
FILE: pkg/golinters/mirror/testdata/fix/out/mirror.go
================================================
//golangcitest:args -Emirror
//golangcitest:expected_exitcode 0
package testdata
import (
"unicode/utf8"
)
func foobar() {
_ = utf8.RuneCountInString("foobar")
}
================================================
FILE: pkg/golinters/mirror/testdata/mirror.go
================================================
//golangcitest:args -Emirror
package testdata
import (
"strings"
"unicode/utf8"
)
func foobar() {
_ = utf8.RuneCount([]byte("foobar")) // want `avoid allocations with utf8\.RuneCountInString`
_ = strings.Compare(string([]byte{'f', 'o', 'o', 'b', 'a', 'r'}), string([]byte{'f', 'o', 'o', 'b', 'a', 'r'})) // want `avoid allocations with bytes\.Compare`
}
================================================
FILE: pkg/golinters/mirror/testdata/mirror_cgo.go
================================================
//golangcitest:args -Emirror
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"strings"
"unicode/utf8"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
_ = utf8.RuneCount([]byte("foobar")) // want `avoid allocations with utf8\.RuneCountInString`
_ = strings.Compare(string([]byte{'f', 'o', 'o', 'b', 'a', 'r'}), string([]byte{'f', 'o', 'o', 'b', 'a', 'r'})) // want `avoid allocations with bytes\.Compare`
}
================================================
FILE: pkg/golinters/misspell/misspell.go
================================================
package misspell
import (
"fmt"
"go/ast"
"go/token"
"strings"
"unicode"
"github.com/golangci/misspell"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "misspell"
func New(settings *config.MisspellSettings) *goanalysis.Linter {
replacer, err := createMisspellReplacer(settings)
if err != nil {
internal.LinterLogger.Fatalf("%s: %v", linterName, err)
}
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: linterName,
Doc: "Finds commonly misspelled English words",
Run: func(pass *analysis.Pass) (any, error) {
for _, file := range pass.Files {
err := runMisspellOnFile(pass, file, replacer, settings.Mode)
if err != nil {
return nil, err
}
}
return nil, nil
},
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func createMisspellReplacer(settings *config.MisspellSettings) (*misspell.Replacer, error) {
replacer := &misspell.Replacer{
Replacements: misspell.DictMain,
}
// Figure out regional variations
switch strings.ToUpper(settings.Locale) {
case "":
// nothing
case "US":
replacer.AddRuleList(misspell.DictAmerican)
case "UK", "GB":
replacer.AddRuleList(misspell.DictBritish)
case "NZ", "AU", "CA":
return nil, fmt.Errorf("unknown locale: %q", settings.Locale)
}
err := appendExtraWords(replacer, settings.ExtraWords)
if err != nil {
return nil, fmt.Errorf("process extra words: %w", err)
}
if len(settings.IgnoreRules) != 0 {
replacer.RemoveRule(settings.IgnoreRules)
}
// It can panic.
replacer.Compile()
return replacer, nil
}
func runMisspellOnFile(pass *analysis.Pass, file *ast.File, replacer *misspell.Replacer, mode string) error {
position, isGoFile := goanalysis.GetGoFilePosition(pass, file)
if !isGoFile {
return nil
}
// Uses the non-adjusted file to work with cgo:
// if we read the real file, the positions are wrong in some cases.
fileContent, err := pass.ReadFile(pass.Fset.PositionFor(file.Pos(), false).Filename)
if err != nil {
return fmt.Errorf("can't get file %s contents: %w", position.Filename, err)
}
// `r.ReplaceGo` doesn't find issues inside strings: it searches only inside comments.
// `r.Replace` searches all words: it treats input as a plain text.
// The standalone misspell tool uses `r.Replace` by default.
var replace func(input string) (string, []misspell.Diff)
switch strings.ToLower(mode) {
case "restricted":
replace = replacer.ReplaceGo
default:
replace = replacer.Replace
}
f := pass.Fset.File(file.Pos())
_, diffs := replace(string(fileContent))
for _, diff := range diffs {
text := fmt.Sprintf("`%s` is a misspelling of `%s`", diff.Original, diff.Corrected)
start := f.LineStart(diff.Line) + token.Pos(diff.Column)
end := f.LineStart(diff.Line) + token.Pos(diff.Column+len(diff.Original))
pass.Report(analysis.Diagnostic{
Pos: start,
End: end,
Message: text,
SuggestedFixes: []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: start,
End: end,
NewText: []byte(diff.Corrected),
}},
}},
})
}
return nil
}
func appendExtraWords(replacer *misspell.Replacer, extraWords []config.MisspellExtraWords) error {
if len(extraWords) == 0 {
return nil
}
extra := make([]string, 0, len(extraWords)*2)
for _, word := range extraWords {
if word.Typo == "" || word.Correction == "" {
return fmt.Errorf("typo (%q) and correction (%q) fields should not be empty", word.Typo, word.Correction)
}
if strings.ContainsFunc(word.Typo, func(r rune) bool { return !unicode.IsLetter(r) }) {
return fmt.Errorf("the word %q in the 'typo' field should only contain letters", word.Typo)
}
if strings.ContainsFunc(word.Correction, func(r rune) bool { return !unicode.IsLetter(r) }) {
return fmt.Errorf("the word %q in the 'correction' field should only contain letters", word.Correction)
}
extra = append(extra, strings.ToLower(word.Typo), strings.ToLower(word.Correction))
}
replacer.AddRuleList(extra)
return nil
}
================================================
FILE: pkg/golinters/misspell/misspell_integration_test.go
================================================
package misspell
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/misspell/misspell_test.go
================================================
package misspell
import (
"testing"
"github.com/golangci/misspell"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/v2/pkg/config"
)
func Test_appendExtraWords(t *testing.T) {
extraWords := []config.MisspellExtraWords{
{
Typo: "iff",
Correction: "if",
},
{
Typo: "canCELation",
Correction: "canceLLaTION",
},
}
replacer := &misspell.Replacer{}
err := appendExtraWords(replacer, extraWords)
require.NoError(t, err)
expected := []string{"iff", "if", "cancelation", "cancellation"}
assert.Equal(t, expected, replacer.Replacements)
}
func Test_appendExtraWords_error(t *testing.T) {
testCases := []struct {
desc string
extraWords []config.MisspellExtraWords
expected string
}{
{
desc: "empty fields",
extraWords: []config.MisspellExtraWords{{
Typo: "",
Correction: "",
}},
expected: `typo ("") and correction ("") fields should not be empty`,
},
{
desc: "empty typo",
extraWords: []config.MisspellExtraWords{{
Typo: "",
Correction: "if",
}},
expected: `typo ("") and correction ("if") fields should not be empty`,
},
{
desc: "empty correction",
extraWords: []config.MisspellExtraWords{{
Typo: "iff",
Correction: "",
}},
expected: `typo ("iff") and correction ("") fields should not be empty`,
},
{
desc: "invalid characters in typo",
extraWords: []config.MisspellExtraWords{{
Typo: "i'ff",
Correction: "if",
}},
expected: `the word "i'ff" in the 'typo' field should only contain letters`,
},
{
desc: "invalid characters in correction",
extraWords: []config.MisspellExtraWords{{
Typo: "iff",
Correction: "i'f",
}},
expected: `the word "i'f" in the 'correction' field should only contain letters`,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
replacer := &misspell.Replacer{}
err := appendExtraWords(replacer, test.extraWords)
require.EqualError(t, err, test.expected)
})
}
}
================================================
FILE: pkg/golinters/misspell/testdata/fix/in/misspell.go
================================================
//golangcitest:args -Emisspell
//golangcitest:expected_exitcode 0
package p
import "log"
// langauge lala
// lala langauge
// langauge
// langauge langauge
// check Langauge
// and check langAuge
func langaugeMisspell() {
var langauge, langaugeAnd string
log.Printf("it's becouse of them: %s, %s", langauge, langaugeAnd)
}
================================================
FILE: pkg/golinters/misspell/testdata/fix/out/misspell.go
================================================
//golangcitest:args -Emisspell
//golangcitest:expected_exitcode 0
package p
import "log"
// language lala
// lala language
// language
// language language
// check Language
// and check langAuge
func langaugeMisspell() {
var language, langaugeAnd string
log.Printf("it's because of them: %s, %s", language, langaugeAnd)
}
================================================
FILE: pkg/golinters/misspell/testdata/misspell.go
================================================
//golangcitest:args -Emisspell
//golangcitest:config_path testdata/misspell.yml
package testdata
func Misspell() {
// comment with incorrect spelling: occured // want "`occured` is a misspelling of `occurred`"
}
// the word langauge should be ignored here: it's set in config
// the word Dialogue should be ignored here: it's set in config
================================================
FILE: pkg/golinters/misspell/testdata/misspell.yml
================================================
version: "2"
linters:
settings:
misspell:
locale: US
ignore-rules:
- langauge
- Dialogue
================================================
FILE: pkg/golinters/misspell/testdata/misspell_cgo.go
================================================
//golangcitest:args -Emisspell
//golangcitest:config_path testdata/misspell.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func Misspell() {
// comment with incorrect spelling: occured // want "`occured` is a misspelling of `occurred`"
}
// the word langauge should be ignored here: it's set in config
// the word Dialogue should be ignored here: it's set in config
func _() error {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
return fmt.Errorf("an unknown error ocurred") // want "`ocurred` is a misspelling of `occurred`"
}
================================================
FILE: pkg/golinters/misspell/testdata/misspell_custom.go
================================================
//golangcitest:args -Emisspell
//golangcitest:config_path testdata/misspell_custom.yml
package testdata
func Misspell() {
// comment with incorrect spelling: occured // want "`occured` is a misspelling of `occurred`"
}
// the word iff should be reported here // want "\\`iff\\` is a misspelling of \\`if\\`"
// the word cancelation should be reported here // want "\\`cancelation\\` is a misspelling of \\`cancellation\\`"
================================================
FILE: pkg/golinters/misspell/testdata/misspell_custom.yml
================================================
version: "2"
linters:
settings:
misspell:
extra-words:
- typo: "iff"
correction: "if"
- typo: "cancelation"
correction: "cancellation"
================================================
FILE: pkg/golinters/mnd/mnd.go
================================================
package mnd
import (
mnd "github.com/tommy-muehle/go-mnd/v2"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.MndSettings) *goanalysis.Linter {
cfg := map[string]any{}
if settings != nil {
if len(settings.Checks) > 0 {
cfg["checks"] = settings.Checks
}
if len(settings.IgnoredNumbers) > 0 {
cfg["ignored-numbers"] = settings.IgnoredNumbers
}
if len(settings.IgnoredFiles) > 0 {
cfg["ignored-files"] = settings.IgnoredFiles
}
if len(settings.IgnoredFunctions) > 0 {
cfg["ignored-functions"] = settings.IgnoredFunctions
}
}
return goanalysis.
NewLinterFromAnalyzer(mnd.Analyzer).
WithDesc("An analyzer to detect magic numbers.").
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/mnd/mnd_integration_test.go
================================================
package mnd
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/mnd/testdata/mnd.go
================================================
//golangcitest:args -Emnd
package testdata
import (
"log"
"net/http"
"time"
)
func UseMagicNumber() {
c := &http.Client{
Timeout: 2 * time.Second, // want "Magic number: 2, in detected"
}
res, err := c.Get("https://www.google.com")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != 200 { // want "Magic number: 200, in detected"
log.Println("Something went wrong")
}
}
func UseNoMagicNumber() {
c := &http.Client{
Timeout: time.Second,
}
res, err := c.Get("https://www.google.com")
if err != nil {
log.Fatal(err)
}
if res.StatusCode != http.StatusOK {
log.Println("Something went wrong")
}
}
================================================
FILE: pkg/golinters/mnd/testdata/mnd_cgo.go
================================================
//golangcitest:args -Emnd
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"log"
"net/http"
"time"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
c := &http.Client{
Timeout: 2 * time.Second, // want "Magic number: 2, in detected"
}
res, err := c.Get("https://www.google.com")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != 200 { // want "Magic number: 200, in detected"
log.Println("Something went wrong")
}
}
================================================
FILE: pkg/golinters/mnd/testdata/mnd_custom.go
================================================
//golangcitest:args -Emnd
//golangcitest:config_path testdata/mnd_custom.yml
package testdata
import (
"log"
"net/http"
"os"
"time"
)
func Mnd() {
c := &http.Client{
Timeout: 5 * time.Second,
}
res, err := c.Get("https://www.google.com")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != 200 { // want "Magic number: 200, in detected"
log.Println("Something went wrong")
}
_ = os.Mkdir("my/dir", 0777)
_ = os.Mkdir("my/dir", 0775) // want "Magic number: 0775, in detected"
}
================================================
FILE: pkg/golinters/mnd/testdata/mnd_custom.yml
================================================
version: "2"
linters:
settings:
mnd:
ignored-numbers:
- '5'
- '0777'
================================================
FILE: pkg/golinters/modernize/modernize.go
================================================
package modernize
import (
"slices"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/modernize"
)
func New(settings *config.ModernizeSettings) *goanalysis.Linter {
var analyzers []*analysis.Analyzer
if settings == nil {
analyzers = modernize.Suite
} else {
for _, analyzer := range modernize.Suite {
if slices.Contains(settings.Disable, analyzer.Name) {
continue
}
analyzers = append(analyzers, analyzer)
}
}
return goanalysis.NewLinter(
"modernize",
"A suite of analyzers that suggest simplifications to Go code, using modern language and library features.",
analyzers,
nil).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/modernize/modernize_integration_test.go
================================================
package modernize
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/any.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package any
func _(x interface{}) {} // want "interface{} can be replaced by any"
func _() {
var x interface{} // want "interface{} can be replaced by any"
const any = 1
var y interface{} // nope: any is shadowed here
_, _ = x, y
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/fieldsseq.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package fieldsseq
import (
"bytes"
"strings"
)
func _() {
for _, line := range strings.Fields("") { // want "Ranging over FieldsSeq is more efficient"
println(line)
}
for i, line := range strings.Fields("") { // nope: uses index var
println(i, line)
}
for i, _ := range strings.Fields("") { // nope: uses index var
println(i)
}
for i := range strings.Fields("") { // nope: uses index var
println(i)
}
for _ = range strings.Fields("") { // want "Ranging over FieldsSeq is more efficient"
}
for range strings.Fields("") { // want "Ranging over FieldsSeq is more efficient"
}
for range bytes.Fields(nil) { // want "Ranging over FieldsSeq is more efficient"
}
{
lines := strings.Fields("") // want "Ranging over FieldsSeq is more efficient"
for _, line := range lines {
println(line)
}
}
{
lines := strings.Fields("") // nope: lines is used not just by range
for _, line := range lines {
println(line)
}
println(lines)
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/fmtappendf.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package fmtappendf
import (
"fmt"
)
func two() string {
return "two"
}
func bye() {
_ = []byte(fmt.Sprintf("bye %d", 1)) // want "Replace .*Sprintf.* with fmt.Appendf"
}
func funcsandvars() {
one := "one"
_ = []byte(fmt.Sprintf("bye %d %s %s", 1, two(), one)) // want "Replace .*Sprintf.* with fmt.Appendf"
}
func typealias() {
type b = byte
type bt = []byte
_ = []b(fmt.Sprintf("bye %d", 1)) // want "Replace .*Sprintf.* with fmt.Appendf"
_ = bt(fmt.Sprintf("bye %d", 1)) // want "Replace .*Sprintf.* with fmt.Appendf"
}
func otherprints() {
_ = []byte(fmt.Sprint("bye %d", 1)) // want "Replace .*Sprint.* with fmt.Append"
_ = []byte(fmt.Sprintln("bye %d", 1)) // want "Replace .*Sprintln.* with fmt.Appendln"
}
func comma() {
type S struct{ Bytes []byte }
var _ = struct{ A S }{
A: S{
Bytes: []byte( // want "Replace .*Sprint.* with fmt.Appendf"
fmt.Sprintf("%d", 0),
),
},
}
_ = []byte( // want "Replace .*Sprint.* with fmt.Appendf"
fmt.Sprintf("%d", 0),
)
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/forvar.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package forvar
func _(m map[int]int, s []int) {
// changed
for i := range s {
i := i // want "copying variable is unneeded"
go f(i)
}
for _, v := range s {
v := v // want "copying variable is unneeded"
go f(v)
}
for k, v := range m {
k := k // want "copying variable is unneeded"
v := v // want "copying variable is unneeded"
go f(k)
go f(v)
}
for k, v := range m {
v := v // want "copying variable is unneeded"
k := k // want "copying variable is unneeded"
go f(k)
go f(v)
}
for k, v := range m {
k, v := k, v // want "copying variable is unneeded"
go f(k)
go f(v)
}
for k, v := range m {
v, k := v, k // want "copying variable is unneeded"
go f(k)
go f(v)
}
for i := range s {
/* hi */ i := i // want "copying variable is unneeded"
go f(i)
}
// nope
var i, k, v int
for i = range s { // nope, scope change
i := i
go f(i)
}
for _, v = range s { // nope, scope change
v := v
go f(v)
}
for k = range m { // nope, scope change
k := k
go f(k)
}
for k, v = range m { // nope, scope change
k := k
v := v
go f(k)
go f(v)
}
for _, v = range m { // nope, scope change
v := v
go f(v)
}
for _, v = range m { // nope, not x := x
v := i
go f(v)
}
for k, v := range m { // nope, LHS and RHS differ
v, k := k, v
go f(k)
go f(v)
}
for k, v := range m { // nope, not a simple redecl
k, v, x := k, v, 1
go f(k)
go f(v)
go f(x)
}
for i := range s { // nope, not a simple redecl
i := (i)
go f(i)
}
for i := range s { // nope, not a simple redecl
i := i + 1
go f(i)
}
}
func f(n int) {}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/mapsloop.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package mapsloop
import (
"iter"
"maps"
)
var _ = maps.Clone[M] // force "maps" import so that each diagnostic doesn't add one
type M map[int]string
// -- src is map --
func useCopy(dst, src map[int]string) {
// Replace loop by maps.Copy.
for key, value := range src {
// A
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
}
func useCopyGeneric[K comparable, V any, M ~map[K]V](dst, src M) {
// Replace loop by maps.Copy.
for key, value := range src {
// A
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
}
func useCopyNotClone(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace make(...) by maps.Copy.
dst := make(map[int]string, len(src))
// A
for key, value := range src {
// B
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
// C
}
// A
dst = map[int]string{}
// B
for key, value := range src {
// C
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
println(dst)
}
func useCopyParen(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace (make)(...) by maps.Clone.
dst := (make)(map[int]string, len(src))
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
dst = (map[int]string{})
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
println(dst)
}
func useCopy_typesDiffer(src M) {
// Replace loop but not make(...) as maps.Copy(src) would return wrong type M.
dst := make(map[int]string, len(src))
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
println(dst)
}
func useCopy_typesDiffer2(src map[int]string) {
// Replace loop but not make(...) as maps.Copy(src) would return wrong type map[int]string.
dst := make(M, len(src))
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
println(dst)
}
func useClone_typesDiffer3(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace loop and make(...) as maps.Clone(src) returns map[int]string
// which is assignable to M.
var dst M
dst = make(M, len(src))
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
println(dst)
}
func useClone_typesDiffer4(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace loop and make(...) as maps.Clone(src) returns map[int]string
// which is assignable to M.
var dst M
dst = make(M, len(src))
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
println(dst)
}
func useClone_generic[Map ~map[K]V, K comparable, V any](src Map) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace loop and make(...) by maps.Clone
dst := make(Map, len(src))
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
println(dst)
}
// -- src is iter.Seq2 --
func useInsert_assignableToSeq2(dst map[int]string, src func(yield func(int, string) bool)) {
// Replace loop by maps.Insert because src is assignable to iter.Seq2.
for k, v := range src {
dst[k] = v // want "Replace m\\[k\\]=v loop with maps.Insert"
}
}
func useCollect(src iter.Seq2[int, string]) {
// Replace loop and make(...) by maps.Collect.
var dst map[int]string
dst = make(map[int]string) // A
// B
for key, value := range src {
// C
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Collect"
}
}
func useInsert_typesDifferAssign(src iter.Seq2[int, string]) {
// Replace loop and make(...): maps.Collect returns an unnamed map type
// that is assignable to M.
var dst M
dst = make(M)
// A
for key, value := range src {
// B
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Collect"
}
}
func useInsert_typesDifferDeclare(src iter.Seq2[int, string]) {
// Replace loop but not make(...) as maps.Collect would return an
// unnamed map type that would change the type of dst.
dst := make(M)
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Insert"
}
}
// -- non-matches --
type isomerOfSeq2 func(yield func(int, string) bool)
func nopeInsertRequiresAssignableToSeq2(dst map[int]string, src isomerOfSeq2) {
for k, v := range src { // nope: src is not assignable to maps.Insert's iter.Seq2 parameter
dst[k] = v
}
}
func nopeSingleVarRange(dst map[int]bool, src map[int]string) {
for key := range src { // nope: must be "for k, v"
dst[key] = true
}
}
func nopeBodyNotASingleton(src map[int]string) {
var dst map[int]string
for key, value := range src {
dst[key] = value
println() // nope: other things in the loop body
}
}
// Regression test for https://github.com/golang/go/issues/70815#issuecomment-2581999787.
func nopeAssignmentHasIncrementOperator(src map[int]int) {
dst := make(map[int]int)
for k, v := range src {
dst[k] += v
}
}
func nopeNotAMap(src map[int]string) {
var dst []string
for k, v := range src {
dst[k] = v
}
}
func nopeNotAMapGeneric[E any, M ~map[int]E, S ~[]E](src M) {
var dst S
for k, v := range src {
dst[k] = v
}
}
func nopeHasImplicitWidening(src map[string]int) {
dst := make(map[string]any)
for k, v := range src {
dst[k] = v
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/mapsloop_dot.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package mapsloop
import . "maps"
var _ = Clone[M] // force "maps" import so that each diagnostic doesn't add one
type M map[int]string
func useCopyDot(dst, src map[int]string) {
// Replace loop by maps.Copy.
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
}
func useCloneDot(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace make(...) by maps.Copy.
dst := make(map[int]string, len(src))
for key, value := range src {
dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
}
println(dst)
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/minmax.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package minmax
func ifmin(a, b int) {
x := a // A
// B
if a < b { // want "if statement can be modernized using max"
// C
x = b // D
// E
}
print(x)
}
func ifmax(a, b int) {
x := a
if a > b { // want "if statement can be modernized using min"
x = b
}
print(x)
}
func ifminvariant(a, b int) {
x := a
if x > b { // want "if statement can be modernized using min"
x = b
}
print(x)
}
func ifmaxvariant(a, b int) {
x := b
if a < x { // want "if statement can be modernized using min"
x = a
}
print(x)
}
func ifelsemin(a, b int) {
var x int // A
// B
if a <= b { // want "if/else statement can be modernized using min"
// C
x = a // D
// E
} else {
// F
x = b // G
// H
}
print(x)
}
func ifelsemax(a, b int) {
// A
var x int // B
// C
if a >= b { // want "if/else statement can be modernized using max"
// D
x = a // E
// F
} else {
// G
x = b
}
print(x)
}
func shadowed() int {
hour, min := 3600, 60
var time int
if hour < min { // silent: the built-in min function is shadowed here
time = hour
} else {
time = min
}
return time
}
func nopeIfStmtHasInitStmt() {
x := 1
if y := 2; y < x { // silent: IfStmt has an Init stmt
x = y
}
print(x)
}
// Regression test for a bug: fix was "y := max(x, y)".
func oops() {
x := 1
y := 2
if x > y { // want "if statement can be modernized using max"
y = x
}
print(y)
}
// Regression test for a bug: += is not a simple assignment.
func nopeAssignHasIncrementOperator() {
x := 1
y := 0
y += 2
if x > y {
y = x
}
print(y)
}
// Regression test for https://github.com/golang/go/issues/71721.
func nopeNotAMinimum(x, y int) int {
// A value of -1 or 0 will use a default value (30).
if x <= 0 {
y = 30
} else {
y = x
}
return y
}
// Regression test for https://github.com/golang/go/issues/71847#issuecomment-2673491596
func nopeHasElseBlock(x int) int {
y := x
// Before, this was erroneously reduced to y = max(x, 0)
if y < 0 {
y = 0
} else {
y += 2
}
return y
}
func fix72727(a, b int) {
o := a - 42
// some important comment. DO NOT REMOVE.
if o < b { // want "if statement can be modernized using max"
o = b
}
}
type myfloat float64
// The built-in min/max differ in their treatment of NaN,
// so reject floating-point numbers (#72829).
func nopeFloat(a, b myfloat) (res myfloat) {
if a < b {
res = a
} else {
res = b
}
return
}
// Regression test for golang/go#72928.
func underscoreAssign(a, b int) {
if a > b {
_ = a
}
}
// Regression test for https://github.com/golang/go/issues/73576.
func nopeIfElseIf(a int) int {
x := 0
if a < 0 {
x = 0
} else if a > 100 {
x = 100
} else {
x = a
}
return x
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/rangeint.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package rangeint
import (
"os"
os1 "os"
)
func _(i int, s struct{ i int }, slice []int) {
for i := 0; i < 10; i++ { // want "for loop can be modernized using range over int"
println(i)
}
for j := int(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := int8(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := int16(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := int32(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := int64(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := uint8(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := uint16(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := uint32(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := uint64(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := int8(0.); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := int8(.0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
for j := os.FileMode(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
{
var i int
for i = 0; i < 10; i++ { // want "for loop can be modernized using range over int"
}
// NB: no uses of i after loop.
}
for i := 0; i < 10; i++ { // want "for loop can be modernized using range over int"
// i unused within loop
}
for i := 0; i < len(slice); i++ { // want "for loop can be modernized using range over int"
println(slice[i])
}
for i := 0; i < len(""); i++ { // want "for loop can be modernized using range over int"
// NB: not simplified to range ""
}
// nope
for j := .0; j < 10; j++ { // nope: j is a float type
println(j)
}
for j := float64(0); j < 10; j++ { // nope: j is a float type
println(j)
}
for i := 0; i < 10; { // nope: missing increment
}
for i := 0; i < 10; i-- { // nope: negative increment
}
for i := 0; ; i++ { // nope: missing comparison
}
for i := 0; i <= 10; i++ { // nope: wrong comparison
}
for ; i < 10; i++ { // nope: missing init
}
for s.i = 0; s.i < 10; s.i++ { // nope: not an ident
}
for i := 0; i < 10; i++ { // nope: takes address of i
println(&i)
}
for i := 0; i < 10; i++ { // nope: increments i
i++
}
for i := 0; i < 10; i++ { // nope: assigns i
i = 8
}
// The limit expression must be loop invariant;
// see https://github.com/golang/go/issues/72917
for i := 0; i < f(); i++ { // nope
}
{
var s struct{ limit int }
for i := 0; i < s.limit; i++ { // nope: limit is not a const or local var
}
}
{
const k = 10
for i := 0; i < k; i++ { // want "for loop can be modernized using range over int"
}
}
{
var limit = 10
for i := 0; i < limit; i++ { // want "for loop can be modernized using range over int"
}
}
{
var limit = 10
for i := 0; i < limit; i++ { // nope: limit is address-taken
}
print(&limit)
}
{
limit := 10
limit++
for i := 0; i < limit; i++ { // nope: limit is assigned other than by its declaration
}
}
for i := 0; i < Global; i++ { // nope: limit is an exported global var; may be updated elsewhere
}
for i := 0; i < len(table); i++ { // want "for loop can be modernized using range over int"
}
{
s := []string{}
for i := 0; i < len(s); i++ { // nope: limit is not loop-invariant
s = s[1:]
}
}
for i := 0; i < len(slice); i++ { // nope: i is incremented within loop
i += 1
}
for Global = 0; Global < 10; Global++ { // nope: loop index is a global variable.
}
}
var Global int
var table = []string{"hello", "world"}
func f() int { return 0 }
// Repro for part of #71847: ("for range n is invalid if the loop body contains i++"):
func _(s string) {
var i int // (this is necessary)
for i = 0; i < len(s); i++ { // nope: loop body increments i
if true {
i++ // nope
}
}
}
// Repro for #71952: for and range loops have different final values
// on i (n and n-1, respectively) so we can't offer the fix if i is
// used after the loop.
func nopePostconditionDiffers() {
i := 0
for i = 0; i < 5; i++ {
println(i)
}
println(i) // must print 5, not 4
}
// Non-integer untyped constants need to be explicitly converted to int.
func issue71847d() {
const limit = 1e3 // float
for i := 0; i < limit; i++ { // want "for loop can be modernized using range over int"
}
for i := int(0); i < limit; i++ { // want "for loop can be modernized using range over int"
}
for i := uint(0); i < limit; i++ { // want "for loop can be modernized using range over int"
}
const limit2 = 1 + 0i // complex
for i := 0; i < limit2; i++ { // want "for loop can be modernized using range over int"
}
}
func issue72726() {
var n, kd int
for i := 0; i < n; i++ { // want "for loop can be modernized using range over int"
// nope: j will be invisible once it's refactored to 'for j := range min(n-j, kd+1)'
for j := 0; j < min(n-j, kd+1); j++ { // nope
_, _ = i, j
}
}
for i := 0; i < i; i++ { // nope
}
var i int
for i = 0; i < i/2; i++ { // nope
}
var arr []int
for i = 0; i < arr[i]; i++ { // nope
}
}
func todo() {
for j := os1.FileMode(0); j < 10; j++ { // want "for loop can be modernized using range over int"
println(j)
}
}
type T uint
type TAlias = uint
func Fn(a int) T {
return T(a)
}
func issue73037() {
var q T
for a := T(0); a < q; a++ { // want "for loop can be modernized using range over int"
println(a)
}
for a := Fn(0); a < q; a++ {
println(a)
}
var qa TAlias
for a := TAlias(0); a < qa; a++ { // want "for loop can be modernized using range over int"
println(a)
}
for a := T(0); a < 10; a++ { // want "for loop can be modernized using range over int"
for b := T(0); b < 10; b++ { // want "for loop can be modernized using range over int"
println(a, b)
}
}
}
func issue75289() {
// A use of i within a defer may be textually before the loop but runs
// after, so it should cause the loop to be rejected as a candidate
// to avoid it observing a different final value of i.
{
var i int
defer func() { println(i) }()
for i = 0; i < 10; i++ { // nope: i is accessed after the loop (via defer)
}
}
// A use of i within a defer within the loop is also a dealbreaker.
{
var i int
for i = 0; i < 10; i++ { // nope: i is accessed after the loop (via defer)
defer func() { println(i) }()
}
}
// This (outer) defer is irrelevant.
defer func() {
var i int
for i = 0; i < 10; i++ { // want "for loop can be modernized using range over int"
}
}()
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/reflecttypefor.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package reflecttypefor
import (
"io"
"reflect"
"time"
)
var (
x any
_ = reflect.TypeOf(x) // nope (dynamic)
_ = reflect.TypeOf(0) // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeOf(uint(0)) // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeOf(error(nil)) // nope (likely a mistake)
_ = reflect.TypeOf((*error)(nil)) // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeOf(io.Reader(nil)) // nope (likely a mistake)
_ = reflect.TypeOf((*io.Reader)(nil)) // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeOf(*new(time.Time)) // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeOf(time.Time{}) // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeOf(time.Duration(0)) // want "reflect.TypeOf call can be simplified using TypeFor"
)
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/slicescontains.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package slicescontains
import "slices"
var _ = slices.Contains[[]int] // force import of "slices" to avoid duplicate import edits
func nopeNoBreak(slice []int, needle int) {
for i := range slice {
if slice[i] == needle {
println("found")
}
}
}
func rangeIndex(slice []int, needle int) {
for i := range slice { // want "Loop can be simplified using slices.Contains"
if slice[i] == needle {
println("found")
break
}
}
}
func rangeValue(slice []int, needle int) {
for _, elem := range slice { // want "Loop can be simplified using slices.Contains"
if elem == needle {
println("found")
break
}
}
}
func returns(slice []int, needle int) {
for i := range slice { // want "Loop can be simplified using slices.Contains"
if slice[i] == needle {
println("found")
return
}
}
}
func assignTrueBreak(slice []int, needle int) {
found := false
for _, elem := range slice { // want "Loop can be simplified using slices.Contains"
if elem == needle {
found = true
break
}
}
print(found)
}
func assignFalseBreak(slice []int, needle int) {
found := true
for _, elem := range slice { // want "Loop can be simplified using slices.Contains"
if elem == needle {
found = false
break
}
}
print(found)
}
func assignFalseBreakInSelectSwitch(slice []int, needle int) {
// Exercise RangeStmt in CommClause, CaseClause.
select {
default:
found := false
for _, elem := range slice { // want "Loop can be simplified using slices.Contains"
if elem == needle {
found = true
break
}
}
print(found)
}
switch {
default:
found := false
for _, elem := range slice { // want "Loop can be simplified using slices.Contains"
if elem == needle {
found = true
break
}
}
print(found)
}
}
func returnTrue(slice []int, needle int) bool {
for _, elem := range slice { // want "Loop can be simplified using slices.Contains"
if elem == needle {
return true
}
}
return false
}
func returnFalse(slice []int, needle int) bool {
for _, elem := range slice { // want "Loop can be simplified using slices.Contains"
if elem == needle {
return false
}
}
return true
}
func containsFunc(slice []int, needle int) bool {
for _, elem := range slice { // want "Loop can be simplified using slices.ContainsFunc"
if predicate(elem) {
return true
}
}
return false
}
func nopeLoopBodyHasFreeContinuation(slice []int, needle int) bool {
for _, elem := range slice {
if predicate(elem) {
if needle == 7 {
continue // this statement defeats loop elimination
}
return true
}
}
return false
}
func generic[T any](slice []T, f func(T) bool) bool {
for _, elem := range slice { // want "Loop can be simplified using slices.ContainsFunc"
if f(elem) {
return true
}
}
return false
}
func predicate(int) bool
// Regression tests for bad fixes when needle
// and haystack have different types (#71313):
func nopeNeedleHaystackDifferentTypes(x any, args []error) {
for _, arg := range args {
if arg == x {
return
}
}
}
func nopeNeedleHaystackDifferentTypes2(x error, args []any) {
for _, arg := range args {
if arg == x {
return
}
}
}
func nopeVariadicNamedContainsFunc(slice []int) bool {
for _, elem := range slice {
if variadicPredicate(elem) {
return true
}
}
return false
}
func variadicPredicate(int, ...any) bool
func nopeVariadicContainsFunc(slice []int) bool {
f := func(int, ...any) bool {
return true
}
for _, elem := range slice {
if f(elem) {
return true
}
}
return false
}
// Negative test case for implicit C->I conversion
type I interface{ F() }
type C int
func (C) F() {}
func nopeImplicitConversionContainsFunc(slice []C, f func(I) bool) bool {
for _, elem := range slice {
if f(elem) { // implicit conversion from C to I
return true
}
}
return false
}
func nopeTypeParamWidening[T any](slice []T, f func(any) bool) bool {
for _, elem := range slice {
if f(elem) { // implicit conversion from T to any
return true
}
}
return false
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/slicessort.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package slicessort
import "sort"
type myint int
func _(s []myint) {
sort.Slice(s, func(i, j int) bool { return s[i] < s[j] }) // want "sort.Slice can be modernized using slices.Sort"
}
func _(x *struct{ s []int }) {
sort.Slice(x.s, func(first, second int) bool { return x.s[first] < x.s[second] }) // want "sort.Slice can be modernized using slices.Sort"
}
func _(s []int) {
sort.Slice(s, func(i, j int) bool { return s[i] > s[j] }) // nope: wrong comparison operator
}
func _(s []int) {
sort.Slice(s, func(i, j int) bool { return s[j] < s[i] }) // nope: wrong index var
}
func _(sense bool, s2 []struct{ x int }) {
sort.Slice(s2, func(i, j int) bool { return s2[i].x < s2[j].x }) // nope: not a simple index operation
// Regression test for a crash: the sole statement of a
// comparison func body is not necessarily a return!
sort.Slice(s2, func(i, j int) bool {
if sense {
return s2[i].x < s2[j].x
} else {
return s2[i].x > s2[j].x
}
})
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/splitseq.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package splitseq
import (
"bytes"
"strings"
)
func _() {
for _, line := range strings.Split("", "") { // want "Ranging over SplitSeq is more efficient"
println(line)
}
for i, line := range strings.Split("", "") { // nope: uses index var
println(i, line)
}
for i, _ := range strings.Split("", "") { // nope: uses index var
println(i)
}
for i := range strings.Split("", "") { // nope: uses index var
println(i)
}
for _ = range strings.Split("", "") { // want "Ranging over SplitSeq is more efficient"
}
for range strings.Split("", "") { // want "Ranging over SplitSeq is more efficient"
}
for range bytes.Split(nil, nil) { // want "Ranging over SplitSeq is more efficient"
}
{
lines := strings.Split("", "") // want "Ranging over SplitSeq is more efficient"
for _, line := range lines {
println(line)
}
}
{
lines := strings.Split("", "") // nope: lines is used not just by range
for _, line := range lines {
println(line)
}
println(lines)
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/stditerators.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package stditerators
import "go/types"
func _(tuple *types.Tuple) {
for i := 0; i < tuple.Len(); i++ { // want "Len/At loop can simplified using Tuple.Variables iteration"
print(tuple.At(i))
}
}
func _(scope *types.Scope) {
for i := 0; i < scope.NumChildren(); i++ { // want "NumChildren/Child loop can simplified using Scope.Children iteration"
print(scope.Child(i))
}
{
const child = 0 // shadowing of preferred name at def
for i := 0; i < scope.NumChildren(); i++ { // want "NumChildren/Child loop can simplified using Scope.Children iteration"
print(scope.Child(i))
}
}
{
for i := 0; i < scope.NumChildren(); i++ {
const child = 0 // nope: shadowing of fresh name at use
print(scope.Child(i))
}
}
{
for i := 0; i < scope.NumChildren(); i++ { // want "NumChildren/Child loop can simplified using Scope.Children iteration"
elem := scope.Child(i) // => preferred name = "elem"
print(elem)
}
}
{
for i := 0; i < scope.NumChildren(); i++ { // want "NumChildren/Child loop can simplified using Scope.Children iteration"
first := scope.Child(0) // the name heuristic should not be fooled by this
print(first, scope.Child(i))
}
}
}
func _(union, union2 *types.Union) {
for i := 0; i < union.Len(); i++ { // want "Len/Term loop can simplified using Union.Terms iteration"
print(union.Term(i))
print(union.Term(i))
}
for i := union.Len() - 1; i >= 0; i-- { // nope: wrong loop form
print(union.Term(i))
}
for i := 0; i <= union.Len(); i++ { // nope: wrong loop form
print(union.Term(i))
}
for i := 0; i <= union.Len(); i++ { // nope: use of i not in x.At(i)
print(i, union.Term(i))
}
for i := 0; i <= union.Len(); i++ { // nope: x.At and x.Len have different receivers
print(i, union2.Term(i))
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/stringsbuilder.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package stringsbuilder
// basic test
func _() {
var s string
s += "before"
for range 10 {
s += "in" // want "using string \\+= string in a loop is inefficient"
s += "in2"
}
s += "after"
print(s)
}
// with initializer
func _() {
var s = "a"
for range 10 {
s += "b" // want "using string \\+= string in a loop is inefficient"
}
print(s)
}
// with empty initializer
func _() {
var s = ""
for range 10 {
s += "b" // want "using string \\+= string in a loop is inefficient"
}
print(s)
}
// with short decl
func _() {
s := "a"
for range 10 {
s += "b" // want "using string \\+= string in a loop is inefficient"
}
print(s)
}
// with short decl and empty initializer
func _() {
s := ""
for range 10 {
s += "b" // want "using string \\+= string in a loop is inefficient"
}
print(s)
}
// nope: += must appear at least once within a loop.
func _() {
var s string
s += "a"
s += "b"
s += "c"
print(s)
}
// nope: the declaration of s is not in a block.
func _() {
if s := "a"; true {
for range 10 {
s += "x"
}
print(s)
}
}
// in a switch (special case of "in a block" logic)
func _() {
switch {
default:
s := "a"
for range 10 {
s += "b" // want "using string \\+= string in a loop is inefficient"
}
print(s)
}
}
// nope: don't handle direct assignments to the string (only +=).
func _(x string) string {
var s string
s = x
for range 3 {
s += "" + x
}
return s
}
// Regression test for bug in a GenDecl with parens.
func issue75318(slice []string) string {
var (
msg string
)
for _, s := range slice {
msg += s // want "using string \\+= string in a loop is inefficient"
}
return msg
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/stringscutprefix.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package stringscutprefix
import (
"strings"
)
var (
s, pre, suf string
)
// test supported cases of pattern 1 - CutPrefix
func _() {
if strings.HasPrefix(s, pre) { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a := strings.TrimPrefix(s, pre)
_ = a
}
if strings.HasPrefix("", "") { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a := strings.TrimPrefix("", "")
_ = a
}
if strings.HasPrefix(s, "") { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
println([]byte(strings.TrimPrefix(s, "")))
}
if strings.HasPrefix(s, "") { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a, b := "", strings.TrimPrefix(s, "")
_, _ = a, b
}
if strings.HasPrefix(s, "") { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a, b := strings.TrimPrefix(s, ""), strings.TrimPrefix(s, "") // only replace the first occurrence
s = "123"
b = strings.TrimPrefix(s, "") // only replace the first occurrence
_, _ = a, b
}
var a, b string
if strings.HasPrefix(s, "") { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a, b = "", strings.TrimPrefix(s, "")
_, _ = a, b
}
}
// test basic cases for CutSuffix - only covering the key differences
func _() {
if strings.HasSuffix(s, suf) { // want "HasSuffix \\+ TrimSuffix can be simplified to CutSuffix"
a := strings.TrimSuffix(s, suf)
_ = a
}
if strings.HasSuffix(s, "") { // want "HasSuffix \\+ TrimSuffix can be simplified to CutSuffix"
println([]byte(strings.TrimSuffix(s, "")))
}
}
// test cases that are not supported by pattern1 - CutPrefix
func _() {
ok := strings.HasPrefix("", "")
if ok { // noop, currently it doesn't track the result usage of HasPrefix
a := strings.TrimPrefix("", "")
_ = a
}
if strings.HasPrefix(s, pre) {
a := strings.TrimPrefix("", "") // noop, as the argument isn't the same
_ = a
}
if strings.HasPrefix(s, pre) {
var result string
result = strings.TrimPrefix("", "") // noop, as we believe define is more popular.
_ = result
}
if strings.HasPrefix("", "") {
a := strings.TrimPrefix(s, pre) // noop, as the argument isn't the same
_ = a
}
if s1 := s; strings.HasPrefix(s1, pre) {
a := strings.TrimPrefix(s1, pre) // noop, as IfStmt.Init is present
_ = a
}
}
// test basic unsupported case for CutSuffix
func _() {
if strings.HasSuffix(s, suf) {
a := strings.TrimSuffix("", "") // noop, as the argument isn't the same
_ = a
}
}
var value0 string
// test supported cases of pattern2 - CutPrefix
func _() {
if after := strings.TrimPrefix(s, pre); after != s { // want "TrimPrefix can be simplified to CutPrefix"
println(after)
}
if after := strings.TrimPrefix(s, pre); s != after { // want "TrimPrefix can be simplified to CutPrefix"
println(after)
}
if after := strings.TrimPrefix(s, pre); s != after { // want "TrimPrefix can be simplified to CutPrefix"
println(strings.TrimPrefix(s, pre)) // noop here
}
if after := strings.TrimPrefix(s, ""); s != after { // want "TrimPrefix can be simplified to CutPrefix"
println(after)
}
var ok bool // define an ok variable to test the fix won't shadow it for its if stmt body
_ = ok
if after := strings.TrimPrefix(s, pre); after != s { // want "TrimPrefix can be simplified to CutPrefix"
println(after)
}
var predefined string
if predefined = strings.TrimPrefix(s, pre); s != predefined { // noop
println(predefined)
}
if predefined = strings.TrimPrefix(s, pre); s != predefined { // noop
println(&predefined)
}
var value string
if value = strings.TrimPrefix(s, pre); s != value { // noop
println(value)
}
lhsMap := make(map[string]string)
if lhsMap[""] = strings.TrimPrefix(s, pre); s != lhsMap[""] { // noop
println(lhsMap[""])
}
arr := make([]string, 0)
if arr[0] = strings.TrimPrefix(s, pre); s != arr[0] { // noop
println(arr[0])
}
type example struct {
field string
}
var e example
if e.field = strings.TrimPrefix(s, pre); s != e.field { // noop
println(e.field)
}
}
// test basic cases for pattern2 - CutSuffix
func _() {
if before := strings.TrimSuffix(s, suf); before != s { // want "TrimSuffix can be simplified to CutSuffix"
println(before)
}
if before := strings.TrimSuffix(s, suf); s != before { // want "TrimSuffix can be simplified to CutSuffix"
println(before)
}
}
// test cases that not supported by pattern2 - CutPrefix
func _() {
if after := strings.TrimPrefix(s, pre); s != pre { // noop
println(after)
}
if after := strings.TrimPrefix(s, pre); after != pre { // noop
println(after)
}
if strings.TrimPrefix(s, pre) != s {
println(strings.TrimPrefix(s, pre))
}
}
// test basic unsupported case for pattern2 - CutSuffix
func _() {
if before := strings.TrimSuffix(s, suf); s != suf { // noop
println(before)
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/testingcontext_test.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package testingcontext
import (
"context"
"testing"
)
func Test(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) // want "context.WithCancel can be modernized using t.Context"
defer cancel()
_ = ctx
func() {
ctx, cancel := context.WithCancel(context.Background()) // Nope. scope of defer is not the testing func.
defer cancel()
_ = ctx
}()
{
ctx, cancel := context.WithCancel(context.TODO()) // want "context.WithCancel can be modernized using t.Context"
defer cancel()
_ = ctx
var t int // not in scope of the call to WithCancel
_ = t
}
{
ctx := context.Background()
ctx, cancel := context.WithCancel(context.Background()) // Nope. ctx is redeclared.
defer cancel()
_ = ctx
}
{
var t int
ctx, cancel := context.WithCancel(context.Background()) // Nope. t is shadowed.
defer cancel()
_ = ctx
_ = t
}
t.Run("subtest", func(t2 *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) // want "context.WithCancel can be modernized using t2.Context"
defer cancel()
_ = ctx
})
}
func TestAlt(t2 *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) // want "context.WithCancel can be modernized using t2.Context"
defer cancel()
_ = ctx
}
func Testnot(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) // Nope. Not a test func.
defer cancel()
_ = ctx
}
func Benchmark(b *testing.B) {
ctx, cancel := context.WithCancel(context.Background()) // want "context.WithCancel can be modernized using b.Context"
defer cancel()
_ = ctx
b.Run("subtest", func(b2 *testing.B) {
ctx, cancel := context.WithCancel(context.Background()) // want "context.WithCancel can be modernized using b2.Context"
defer cancel()
_ = ctx
})
}
func Fuzz(f *testing.F) {
ctx, cancel := context.WithCancel(context.Background()) // want "context.WithCancel can be modernized using f.Context"
defer cancel()
_ = ctx
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/in/waitgroup.go
================================================
//go:build go1.25
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package waitgroup
import (
"fmt"
"sync"
)
// supported case for pattern 1.
func _() {
var wg sync.WaitGroup
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
defer wg.Done()
fmt.Println()
}()
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
defer wg.Done()
}()
for range 10 {
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
defer wg.Done()
fmt.Println()
}()
}
}
// supported case for pattern 2.
func _() {
var wg sync.WaitGroup
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
fmt.Println()
wg.Done()
}()
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
wg.Done()
}()
for range 10 {
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
fmt.Println()
wg.Done()
}()
}
}
// this function puts some wrong usages but waitgroup modernizer will still offer fixes.
func _() {
var wg sync.WaitGroup
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
defer wg.Done()
defer wg.Done()
fmt.Println()
}()
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
defer wg.Done()
fmt.Println()
wg.Done()
}()
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
fmt.Println()
wg.Done()
wg.Done()
}()
}
// this function puts the unsupported cases of pattern 1.
func _() {
var wg sync.WaitGroup
wg.Add(1)
go func() {}()
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(1)
wg.Add(1)
go func() {
fmt.Println()
defer wg.Done()
}()
wg.Add(1)
go func() { // noop: no wg.Done call inside function body.
fmt.Println()
}()
go func() { // noop: no Add call before this go stmt.
defer wg.Done()
fmt.Println()
}()
wg.Add(2) // noop: only support Add(1).
go func() {
defer wg.Done()
}()
var wg1 sync.WaitGroup
wg1.Add(1) // noop: Add and Done should be the same object.
go func() {
defer wg.Done()
fmt.Println()
}()
wg.Add(1) // noop: Add and Done should be the same object.
go func() {
defer wg1.Done()
fmt.Println()
}()
}
// this function puts the unsupported cases of pattern 2.
func _() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
wg.Done()
fmt.Println()
}()
go func() { // noop: no Add call before this go stmt.
fmt.Println()
wg.Done()
}()
var wg1 sync.WaitGroup
wg1.Add(1) // noop: Add and Done should be the same object.
go func() {
fmt.Println()
wg.Done()
}()
wg.Add(1) // noop: Add and Done should be the same object.
go func() {
fmt.Println()
wg1.Done()
}()
}
type Server struct {
wg sync.WaitGroup
}
type ServerContainer struct {
serv Server
}
func _() {
var s Server
s.wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
print()
s.wg.Done()
}()
var sc ServerContainer
sc.serv.wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
print()
sc.serv.wg.Done()
}()
var wg sync.WaitGroup
arr := [1]*sync.WaitGroup{&wg}
arr[0].Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
go func() {
print()
arr[0].Done()
}()
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/any.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package any
func _(x any) {} // want "interface{} can be replaced by any"
func _() {
var x any // want "interface{} can be replaced by any"
const any = 1
var y interface{} // nope: any is shadowed here
_, _ = x, y
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/fieldsseq.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package fieldsseq
import (
"bytes"
"strings"
)
func _() {
for line := range strings.FieldsSeq("") { // want "Ranging over FieldsSeq is more efficient"
println(line)
}
for i, line := range strings.Fields("") { // nope: uses index var
println(i, line)
}
for i, _ := range strings.Fields("") { // nope: uses index var
println(i)
}
for i := range strings.Fields("") { // nope: uses index var
println(i)
}
for range strings.FieldsSeq("") { // want "Ranging over FieldsSeq is more efficient"
}
for range strings.FieldsSeq("") { // want "Ranging over FieldsSeq is more efficient"
}
for range bytes.FieldsSeq(nil) { // want "Ranging over FieldsSeq is more efficient"
}
{
lines := strings.FieldsSeq("") // want "Ranging over FieldsSeq is more efficient"
for line := range lines {
println(line)
}
}
{
lines := strings.Fields("") // nope: lines is used not just by range
for _, line := range lines {
println(line)
}
println(lines)
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/fmtappendf.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package fmtappendf
import (
"fmt"
)
func two() string {
return "two"
}
func bye() {
_ = fmt.Appendf(nil, "bye %d", 1) // want "Replace .*Sprintf.* with fmt.Appendf"
}
func funcsandvars() {
one := "one"
_ = fmt.Appendf(nil, "bye %d %s %s", 1, two(), one) // want "Replace .*Sprintf.* with fmt.Appendf"
}
func typealias() {
type b = byte
type bt = []byte
_ = fmt.Appendf(nil, "bye %d", 1) // want "Replace .*Sprintf.* with fmt.Appendf"
_ = fmt.Appendf(nil, "bye %d", 1) // want "Replace .*Sprintf.* with fmt.Appendf"
}
func otherprints() {
_ = fmt.Append(nil, "bye %d", 1) // want "Replace .*Sprint.* with fmt.Append"
_ = fmt.Appendln(nil, "bye %d", 1) // want "Replace .*Sprintln.* with fmt.Appendln"
}
func comma() {
type S struct{ Bytes []byte }
var _ = struct{ A S }{
A: S{
Bytes: fmt.Appendf(nil, "%d", 0),
},
}
_ = fmt.Appendf(nil, "%d", 0)
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/forvar.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package forvar
func _(m map[int]int, s []int) {
// changed
for i := range s {
go f(i)
}
for _, v := range s {
go f(v)
}
for k, v := range m {
go f(k)
go f(v)
}
for k, v := range m {
go f(k)
go f(v)
}
for k, v := range m {
go f(k)
go f(v)
}
for k, v := range m {
go f(k)
go f(v)
}
for i := range s {
go f(i)
}
// nope
var i, k, v int
for i = range s { // nope, scope change
i := i
go f(i)
}
for _, v = range s { // nope, scope change
v := v
go f(v)
}
for k = range m { // nope, scope change
k := k
go f(k)
}
for k, v = range m { // nope, scope change
k := k
v := v
go f(k)
go f(v)
}
for _, v = range m { // nope, scope change
v := v
go f(v)
}
for _, v = range m { // nope, not x := x
v := i
go f(v)
}
for k, v := range m { // nope, LHS and RHS differ
v, k := k, v
go f(k)
go f(v)
}
for k, v := range m { // nope, not a simple redecl
k, v, x := k, v, 1
go f(k)
go f(v)
go f(x)
}
for i := range s { // nope, not a simple redecl
i := (i)
go f(i)
}
for i := range s { // nope, not a simple redecl
i := i + 1
go f(i)
}
}
func f(n int) {}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/mapsloop.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package mapsloop
import (
"iter"
"maps"
)
var _ = maps.Clone[M] // force "maps" import so that each diagnostic doesn't add one
type M map[int]string
// -- src is map --
func useCopy(dst, src map[int]string) {
// Replace loop by maps.Copy.
// A
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
}
func useCopyGeneric[K comparable, V any, M ~map[K]V](dst, src M) {
// Replace loop by maps.Copy.
// A
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
}
func useCopyNotClone(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace make(...) by maps.Copy.
dst := make(map[int]string, len(src))
// A
// B
// want "Replace m\\[k\\]=v loop with maps.Copy"
// C
maps.Copy(dst, src)
// A
dst = map[int]string{}
// B
// C
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
println(dst)
}
func useCopyParen(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace (make)(...) by maps.Clone.
dst := (make)(map[int]string, len(src))
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
dst = (map[int]string{})
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
println(dst)
}
func useCopy_typesDiffer(src M) {
// Replace loop but not make(...) as maps.Copy(src) would return wrong type M.
dst := make(map[int]string, len(src))
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
println(dst)
}
func useCopy_typesDiffer2(src map[int]string) {
// Replace loop but not make(...) as maps.Copy(src) would return wrong type map[int]string.
dst := make(M, len(src))
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
println(dst)
}
func useClone_typesDiffer3(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace loop and make(...) as maps.Clone(src) returns map[int]string
// which is assignable to M.
var dst M
dst = make(M, len(src))
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
println(dst)
}
func useClone_typesDiffer4(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace loop and make(...) as maps.Clone(src) returns map[int]string
// which is assignable to M.
var dst M
dst = make(M, len(src))
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
println(dst)
}
func useClone_generic[Map ~map[K]V, K comparable, V any](src Map) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace loop and make(...) by maps.Clone
dst := make(Map, len(src))
// want "Replace m\\[k\\]=v loop with maps.Copy"
maps.Copy(dst, src)
println(dst)
}
// -- src is iter.Seq2 --
func useInsert_assignableToSeq2(dst map[int]string, src func(yield func(int, string) bool)) {
// Replace loop by maps.Insert because src is assignable to iter.Seq2.
// want "Replace m\\[k\\]=v loop with maps.Insert"
maps.Insert(dst, src)
}
func useCollect(src iter.Seq2[int, string]) {
// Replace loop and make(...) by maps.Collect.
var dst map[int]string
// A
// B
// C
// want "Replace m\\[k\\]=v loop with maps.Collect"
dst = maps.Collect(src)
}
func useInsert_typesDifferAssign(src iter.Seq2[int, string]) {
// Replace loop and make(...): maps.Collect returns an unnamed map type
// that is assignable to M.
var dst M
// A
// B
// want "Replace m\\[k\\]=v loop with maps.Collect"
dst = maps.Collect(src)
}
func useInsert_typesDifferDeclare(src iter.Seq2[int, string]) {
// Replace loop but not make(...) as maps.Collect would return an
// unnamed map type that would change the type of dst.
dst := make(M)
// want "Replace m\\[k\\]=v loop with maps.Insert"
maps.Insert(dst, src)
}
// -- non-matches --
type isomerOfSeq2 func(yield func(int, string) bool)
func nopeInsertRequiresAssignableToSeq2(dst map[int]string, src isomerOfSeq2) {
for k, v := range src { // nope: src is not assignable to maps.Insert's iter.Seq2 parameter
dst[k] = v
}
}
func nopeSingleVarRange(dst map[int]bool, src map[int]string) {
for key := range src { // nope: must be "for k, v"
dst[key] = true
}
}
func nopeBodyNotASingleton(src map[int]string) {
var dst map[int]string
for key, value := range src {
dst[key] = value
println() // nope: other things in the loop body
}
}
// Regression test for https://github.com/golang/go/issues/70815#issuecomment-2581999787.
func nopeAssignmentHasIncrementOperator(src map[int]int) {
dst := make(map[int]int)
for k, v := range src {
dst[k] += v
}
}
func nopeNotAMap(src map[int]string) {
var dst []string
for k, v := range src {
dst[k] = v
}
}
func nopeNotAMapGeneric[E any, M ~map[int]E, S ~[]E](src M) {
var dst S
for k, v := range src {
dst[k] = v
}
}
func nopeHasImplicitWidening(src map[string]int) {
dst := make(map[string]any)
for k, v := range src {
dst[k] = v
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/mapsloop_dot.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package mapsloop
import . "maps"
var _ = Clone[M] // force "maps" import so that each diagnostic doesn't add one
type M map[int]string
func useCopyDot(dst, src map[int]string) {
// Replace loop by maps.Copy.
// want "Replace m\\[k\\]=v loop with maps.Copy"
Copy(dst, src)
}
func useCloneDot(src map[int]string) {
// Clone is tempting but wrong when src may be nil; see #71844.
// Replace make(...) by maps.Copy.
dst := make(map[int]string, len(src))
// want "Replace m\\[k\\]=v loop with maps.Copy"
Copy(dst, src)
println(dst)
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/minmax.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package minmax
func ifmin(a, b int) {
x := max(
// A
// B
a,
// want "if statement can be modernized using max"
// C
// D
// E
b)
print(x)
}
func ifmax(a, b int) {
x := min(a,
// want "if statement can be modernized using min"
b)
print(x)
}
func ifminvariant(a, b int) {
x := min(a,
// want "if statement can be modernized using min"
b)
print(x)
}
func ifmaxvariant(a, b int) {
x := min(a,
// want "if statement can be modernized using min"
b)
print(x)
}
func ifelsemin(a, b int) {
var x int // A
// B
x = min(
// want "if/else statement can be modernized using min"
// C
// D
// E
a,
// F
// G
// H
b)
print(x)
}
func ifelsemax(a, b int) {
// A
var x int // B
// C
x = max(
// want "if/else statement can be modernized using max"
// D
// E
// F
a,
// G
b)
print(x)
}
func shadowed() int {
hour, min := 3600, 60
var time int
if hour < min { // silent: the built-in min function is shadowed here
time = hour
} else {
time = min
}
return time
}
func nopeIfStmtHasInitStmt() {
x := 1
if y := 2; y < x { // silent: IfStmt has an Init stmt
x = y
}
print(x)
}
// Regression test for a bug: fix was "y := max(x, y)".
func oops() {
x := 1
y := max(x,
// want "if statement can be modernized using max"
2)
print(y)
}
// Regression test for a bug: += is not a simple assignment.
func nopeAssignHasIncrementOperator() {
x := 1
y := 0
y += 2
if x > y {
y = x
}
print(y)
}
// Regression test for https://github.com/golang/go/issues/71721.
func nopeNotAMinimum(x, y int) int {
// A value of -1 or 0 will use a default value (30).
if x <= 0 {
y = 30
} else {
y = x
}
return y
}
// Regression test for https://github.com/golang/go/issues/71847#issuecomment-2673491596
func nopeHasElseBlock(x int) int {
y := x
// Before, this was erroneously reduced to y = max(x, 0)
if y < 0 {
y = 0
} else {
y += 2
}
return y
}
func fix72727(a, b int) {
o := max(
// some important comment. DO NOT REMOVE.
a-42,
// want "if statement can be modernized using max"
b)
}
type myfloat float64
// The built-in min/max differ in their treatment of NaN,
// so reject floating-point numbers (#72829).
func nopeFloat(a, b myfloat) (res myfloat) {
if a < b {
res = a
} else {
res = b
}
return
}
// Regression test for golang/go#72928.
func underscoreAssign(a, b int) {
if a > b {
_ = a
}
}
// Regression test for https://github.com/golang/go/issues/73576.
func nopeIfElseIf(a int) int {
x := 0
if a < 0 {
x = 0
} else if a > 100 {
x = 100
} else {
x = a
}
return x
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/rangeint.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package rangeint
import (
"os"
os1 "os"
)
func _(i int, s struct{ i int }, slice []int) {
for i := range 10 { // want "for loop can be modernized using range over int"
println(i)
}
for j := range 10 { // want "for loop can be modernized using range over int"
println(j)
}
for j := range int8(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range int16(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range int32(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range int64(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range uint8(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range uint16(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range uint32(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range uint64(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range int8(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range int8(10) { // want "for loop can be modernized using range over int"
println(j)
}
for j := range os1.FileMode(10) { // want "for loop can be modernized using range over int"
println(j)
}
{
var i int
for i = range 10 { // want "for loop can be modernized using range over int"
}
// NB: no uses of i after loop.
}
for range 10 { // want "for loop can be modernized using range over int"
// i unused within loop
}
for i := range slice { // want "for loop can be modernized using range over int"
println(slice[i])
}
for range len("") { // want "for loop can be modernized using range over int"
// NB: not simplified to range ""
}
// nope
for j := .0; j < 10; j++ { // nope: j is a float type
println(j)
}
for j := float64(0); j < 10; j++ { // nope: j is a float type
println(j)
}
for i := 0; i < 10; { // nope: missing increment
}
for i := 0; i < 10; i-- { // nope: negative increment
}
for i := 0; ; i++ { // nope: missing comparison
}
for i := 0; i <= 10; i++ { // nope: wrong comparison
}
for ; i < 10; i++ { // nope: missing init
}
for s.i = 0; s.i < 10; s.i++ { // nope: not an ident
}
for i := 0; i < 10; i++ { // nope: takes address of i
println(&i)
}
for i := 0; i < 10; i++ { // nope: increments i
i++
}
for i := 0; i < 10; i++ { // nope: assigns i
i = 8
}
// The limit expression must be loop invariant;
// see https://github.com/golang/go/issues/72917
for i := 0; i < f(); i++ { // nope
}
{
var s struct{ limit int }
for i := 0; i < s.limit; i++ { // nope: limit is not a const or local var
}
}
{
const k = 10
for range k { // want "for loop can be modernized using range over int"
}
}
{
var limit = 10
for range limit { // want "for loop can be modernized using range over int"
}
}
{
var limit = 10
for i := 0; i < limit; i++ { // nope: limit is address-taken
}
print(&limit)
}
{
limit := 10
limit++
for i := 0; i < limit; i++ { // nope: limit is assigned other than by its declaration
}
}
for i := 0; i < Global; i++ { // nope: limit is an exported global var; may be updated elsewhere
}
for range table { // want "for loop can be modernized using range over int"
}
{
s := []string{}
for i := 0; i < len(s); i++ { // nope: limit is not loop-invariant
s = s[1:]
}
}
for i := 0; i < len(slice); i++ { // nope: i is incremented within loop
i += 1
}
for Global = 0; Global < 10; Global++ { // nope: loop index is a global variable.
}
}
var Global int
var table = []string{"hello", "world"}
func f() int { return 0 }
// Repro for part of #71847: ("for range n is invalid if the loop body contains i++"):
func _(s string) {
var i int // (this is necessary)
for i = 0; i < len(s); i++ { // nope: loop body increments i
if true {
i++ // nope
}
}
}
// Repro for #71952: for and range loops have different final values
// on i (n and n-1, respectively) so we can't offer the fix if i is
// used after the loop.
func nopePostconditionDiffers() {
i := 0
for i = 0; i < 5; i++ {
println(i)
}
println(i) // must print 5, not 4
}
// Non-integer untyped constants need to be explicitly converted to int.
func issue71847d() {
const limit = 1e3 // float
for range int(limit) { // want "for loop can be modernized using range over int"
}
for range int(limit) { // want "for loop can be modernized using range over int"
}
for range uint(limit) { // want "for loop can be modernized using range over int"
}
const limit2 = 1 + 0i // complex
for range int(limit2) { // want "for loop can be modernized using range over int"
}
}
func issue72726() {
var n, kd int
for i := range n { // want "for loop can be modernized using range over int"
// nope: j will be invisible once it's refactored to 'for j := range min(n-j, kd+1)'
for j := 0; j < min(n-j, kd+1); j++ { // nope
_, _ = i, j
}
}
for i := 0; i < i; i++ { // nope
}
var i int
for i = 0; i < i/2; i++ { // nope
}
var arr []int
for i = 0; i < arr[i]; i++ { // nope
}
}
func todo() {
for j := range os1.FileMode(10) { // want "for loop can be modernized using range over int"
println(j)
}
}
type T uint
type TAlias = uint
func Fn(a int) T {
return T(a)
}
func issue73037() {
var q T
for a := range q { // want "for loop can be modernized using range over int"
println(a)
}
for a := Fn(0); a < q; a++ {
println(a)
}
var qa TAlias
for a := range qa { // want "for loop can be modernized using range over int"
println(a)
}
for a := range T(10) { // want "for loop can be modernized using range over int"
for b := range T(10) { // want "for loop can be modernized using range over int"
println(a, b)
}
}
}
func issue75289() {
// A use of i within a defer may be textually before the loop but runs
// after, so it should cause the loop to be rejected as a candidate
// to avoid it observing a different final value of i.
{
var i int
defer func() { println(i) }()
for i = 0; i < 10; i++ { // nope: i is accessed after the loop (via defer)
}
}
// A use of i within a defer within the loop is also a dealbreaker.
{
var i int
for i = 0; i < 10; i++ { // nope: i is accessed after the loop (via defer)
defer func() { println(i) }()
}
}
// This (outer) defer is irrelevant.
defer func() {
var i int
for i = range 10 { // want "for loop can be modernized using range over int"
}
}()
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/reflecttypefor.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package reflecttypefor
import (
"io"
"reflect"
"time"
)
var (
x any
_ = reflect.TypeOf(x) // nope (dynamic)
_ = reflect.TypeFor[int]() // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeFor[uint]() // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeOf(error(nil)) // nope (likely a mistake)
_ = reflect.TypeFor[*error]() // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeOf(io.Reader(nil)) // nope (likely a mistake)
_ = reflect.TypeFor[*io.Reader]() // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeFor[time.Time]() // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeFor[time.Time]() // want "reflect.TypeOf call can be simplified using TypeFor"
_ = reflect.TypeFor[time.Duration]() // want "reflect.TypeOf call can be simplified using TypeFor"
)
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/slicescontains.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package slicescontains
import "slices"
var _ = slices.Contains[[]int] // force import of "slices" to avoid duplicate import edits
func nopeNoBreak(slice []int, needle int) {
for i := range slice {
if slice[i] == needle {
println("found")
}
}
}
func rangeIndex(slice []int, needle int) {
if slices.Contains(slice, needle) {
println("found")
}
}
func rangeValue(slice []int, needle int) {
if slices.Contains(slice, needle) {
println("found")
}
}
func returns(slice []int, needle int) {
if slices.Contains(slice, needle) {
println("found")
return
}
}
func assignTrueBreak(slice []int, needle int) {
found := slices.Contains(slice, needle)
print(found)
}
func assignFalseBreak(slice []int, needle int) {
found := !slices.Contains(slice, needle)
print(found)
}
func assignFalseBreakInSelectSwitch(slice []int, needle int) {
// Exercise RangeStmt in CommClause, CaseClause.
select {
default:
found := slices.Contains(slice, needle)
print(found)
}
switch {
default:
found := slices.Contains(slice, needle)
print(found)
}
}
func returnTrue(slice []int, needle int) bool {
return slices.Contains(slice, needle)
}
func returnFalse(slice []int, needle int) bool {
return !slices.Contains(slice, needle)
}
func containsFunc(slice []int, needle int) bool {
return slices.ContainsFunc(slice, predicate)
}
func nopeLoopBodyHasFreeContinuation(slice []int, needle int) bool {
for _, elem := range slice {
if predicate(elem) {
if needle == 7 {
continue // this statement defeats loop elimination
}
return true
}
}
return false
}
func generic[T any](slice []T, f func(T) bool) bool {
return slices.ContainsFunc(slice, f)
}
func predicate(int) bool
// Regression tests for bad fixes when needle
// and haystack have different types (#71313):
func nopeNeedleHaystackDifferentTypes(x any, args []error) {
for _, arg := range args {
if arg == x {
return
}
}
}
func nopeNeedleHaystackDifferentTypes2(x error, args []any) {
for _, arg := range args {
if arg == x {
return
}
}
}
func nopeVariadicNamedContainsFunc(slice []int) bool {
for _, elem := range slice {
if variadicPredicate(elem) {
return true
}
}
return false
}
func variadicPredicate(int, ...any) bool
func nopeVariadicContainsFunc(slice []int) bool {
f := func(int, ...any) bool {
return true
}
for _, elem := range slice {
if f(elem) {
return true
}
}
return false
}
// Negative test case for implicit C->I conversion
type I interface{ F() }
type C int
func (C) F() {}
func nopeImplicitConversionContainsFunc(slice []C, f func(I) bool) bool {
for _, elem := range slice {
if f(elem) { // implicit conversion from C to I
return true
}
}
return false
}
func nopeTypeParamWidening[T any](slice []T, f func(any) bool) bool {
for _, elem := range slice {
if f(elem) { // implicit conversion from T to any
return true
}
}
return false
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/slicessort.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package slicessort
import "slices"
import "sort"
type myint int
func _(s []myint) {
slices.Sort(s) // want "sort.Slice can be modernized using slices.Sort"
}
func _(x *struct{ s []int }) {
slices.Sort(x.s) // want "sort.Slice can be modernized using slices.Sort"
}
func _(s []int) {
sort.Slice(s, func(i, j int) bool { return s[i] > s[j] }) // nope: wrong comparison operator
}
func _(s []int) {
sort.Slice(s, func(i, j int) bool { return s[j] < s[i] }) // nope: wrong index var
}
func _(sense bool, s2 []struct{ x int }) {
sort.Slice(s2, func(i, j int) bool { return s2[i].x < s2[j].x }) // nope: not a simple index operation
// Regression test for a crash: the sole statement of a
// comparison func body is not necessarily a return!
sort.Slice(s2, func(i, j int) bool {
if sense {
return s2[i].x < s2[j].x
} else {
return s2[i].x > s2[j].x
}
})
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/splitseq.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package splitseq
import (
"bytes"
"strings"
)
func _() {
for line := range strings.SplitSeq("", "") { // want "Ranging over SplitSeq is more efficient"
println(line)
}
for i, line := range strings.Split("", "") { // nope: uses index var
println(i, line)
}
for i, _ := range strings.Split("", "") { // nope: uses index var
println(i)
}
for i := range strings.Split("", "") { // nope: uses index var
println(i)
}
for range strings.SplitSeq("", "") { // want "Ranging over SplitSeq is more efficient"
}
for range strings.SplitSeq("", "") { // want "Ranging over SplitSeq is more efficient"
}
for range bytes.SplitSeq(nil, nil) { // want "Ranging over SplitSeq is more efficient"
}
{
lines := strings.SplitSeq("", "") // want "Ranging over SplitSeq is more efficient"
for line := range lines {
println(line)
}
}
{
lines := strings.Split("", "") // nope: lines is used not just by range
for _, line := range lines {
println(line)
}
println(lines)
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/stditerators.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package stditerators
import "go/types"
func _(tuple *types.Tuple) {
for v := range tuple.Variables() { // want "Len/At loop can simplified using Tuple.Variables iteration"
print(v)
}
}
func _(scope *types.Scope) {
for child := range scope.Children() { // want "NumChildren/Child loop can simplified using Scope.Children iteration"
print(child)
}
{
const child = 0 // shadowing of preferred name at def
for child := range scope.Children() { // want "NumChildren/Child loop can simplified using Scope.Children iteration"
print(child)
}
}
{
for i := 0; i < scope.NumChildren(); i++ {
const child = 0 // nope: shadowing of fresh name at use
print(scope.Child(i))
}
}
{
for elem := range scope.Children() { // want "NumChildren/Child loop can simplified using Scope.Children iteration"
elem := elem // => preferred name = "elem"
print(elem)
}
}
{
for child := range scope.Children() { // want "NumChildren/Child loop can simplified using Scope.Children iteration"
first := scope.Child(0) // the name heuristic should not be fooled by this
print(first, child)
}
}
}
func _(union, union2 *types.Union) {
for term := range union.Terms() { // want "Len/Term loop can simplified using Union.Terms iteration"
print(term)
print(term)
}
for i := union.Len() - 1; i >= 0; i-- { // nope: wrong loop form
print(union.Term(i))
}
for i := 0; i <= union.Len(); i++ { // nope: wrong loop form
print(union.Term(i))
}
for i := 0; i <= union.Len(); i++ { // nope: use of i not in x.At(i)
print(i, union.Term(i))
}
for i := 0; i <= union.Len(); i++ { // nope: x.At and x.Len have different receivers
print(i, union2.Term(i))
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/stringsbuilder.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package stringsbuilder
import "strings"
// basic test
func _() {
var s strings.Builder
s.WriteString("before")
for range 10 {
s.WriteString("in") // want "using string \\+= string in a loop is inefficient"
s.WriteString("in2")
}
s.WriteString("after")
print(s.String())
}
// with initializer
func _() {
var s strings.Builder
s.WriteString("a")
for range 10 {
s.WriteString("b") // want "using string \\+= string in a loop is inefficient"
}
print(s.String())
}
// with empty initializer
func _() {
var s strings.Builder
for range 10 {
s.WriteString("b") // want "using string \\+= string in a loop is inefficient"
}
print(s.String())
}
// with short decl
func _() {
var s strings.Builder
s.WriteString("a")
for range 10 {
s.WriteString("b") // want "using string \\+= string in a loop is inefficient"
}
print(s.String())
}
// with short decl and empty initializer
func _() {
var s strings.Builder
for range 10 {
s.WriteString("b") // want "using string \\+= string in a loop is inefficient"
}
print(s.String())
}
// nope: += must appear at least once within a loop.
func _() {
var s string
s += "a"
s += "b"
s += "c"
print(s)
}
// nope: the declaration of s is not in a block.
func _() {
if s := "a"; true {
for range 10 {
s += "x"
}
print(s)
}
}
// in a switch (special case of "in a block" logic)
func _() {
switch {
default:
var s strings.Builder
s.WriteString("a")
for range 10 {
s.WriteString("b") // want "using string \\+= string in a loop is inefficient"
}
print(s.String())
}
}
// nope: don't handle direct assignments to the string (only +=).
func _(x string) string {
var s string
s = x
for range 3 {
s += "" + x
}
return s
}
// Regression test for bug in a GenDecl with parens.
func issue75318(slice []string) string {
var (
msg strings.Builder
)
for _, s := range slice {
msg.WriteString(s) // want "using string \\+= string in a loop is inefficient"
}
return msg.String()
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/stringscutprefix.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package stringscutprefix
import (
"strings"
)
var (
s, pre, suf string
)
// test supported cases of pattern 1 - CutPrefix
func _() {
if after, ok := strings.CutPrefix(s, pre); ok { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a := after
_ = a
}
if after, ok := strings.CutPrefix("", ""); ok { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a := after
_ = a
}
if after, ok := strings.CutPrefix(s, ""); ok { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
println([]byte(after))
}
if after, ok := strings.CutPrefix(s, ""); ok { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a, b := "", after
_, _ = a, b
}
if after, ok := strings.CutPrefix(s, ""); ok { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a, b := after, strings.TrimPrefix(s, "") // only replace the first occurrence
s = "123"
b = strings.TrimPrefix(s, "") // only replace the first occurrence
_, _ = a, b
}
var a, b string
if after, ok := strings.CutPrefix(s, ""); ok { // want "HasPrefix \\+ TrimPrefix can be simplified to CutPrefix"
a, b = "", after
_, _ = a, b
}
}
// test basic cases for CutSuffix - only covering the key differences
func _() {
if before, ok := strings.CutSuffix(s, suf); ok { // want "HasSuffix \\+ TrimSuffix can be simplified to CutSuffix"
a := before
_ = a
}
if before, ok := strings.CutSuffix(s, ""); ok { // want "HasSuffix \\+ TrimSuffix can be simplified to CutSuffix"
println([]byte(before))
}
}
// test cases that are not supported by pattern1 - CutPrefix
func _() {
ok := strings.HasPrefix("", "")
if ok { // noop, currently it doesn't track the result usage of HasPrefix
a := strings.TrimPrefix("", "")
_ = a
}
if strings.HasPrefix(s, pre) {
a := strings.TrimPrefix("", "") // noop, as the argument isn't the same
_ = a
}
if strings.HasPrefix(s, pre) {
var result string
result = strings.TrimPrefix("", "") // noop, as we believe define is more popular.
_ = result
}
if strings.HasPrefix("", "") {
a := strings.TrimPrefix(s, pre) // noop, as the argument isn't the same
_ = a
}
if s1 := s; strings.HasPrefix(s1, pre) {
a := strings.TrimPrefix(s1, pre) // noop, as IfStmt.Init is present
_ = a
}
}
// test basic unsupported case for CutSuffix
func _() {
if strings.HasSuffix(s, suf) {
a := strings.TrimSuffix("", "") // noop, as the argument isn't the same
_ = a
}
}
var value0 string
// test supported cases of pattern2 - CutPrefix
func _() {
if after, ok := strings.CutPrefix(s, pre); ok { // want "TrimPrefix can be simplified to CutPrefix"
println(after)
}
if after, ok := strings.CutPrefix(s, pre); ok { // want "TrimPrefix can be simplified to CutPrefix"
println(after)
}
if after, ok := strings.CutPrefix(s, pre); ok { // want "TrimPrefix can be simplified to CutPrefix"
println(strings.TrimPrefix(s, pre)) // noop here
}
if after, ok := strings.CutPrefix(s, ""); ok { // want "TrimPrefix can be simplified to CutPrefix"
println(after)
}
var ok bool // define an ok variable to test the fix won't shadow it for its if stmt body
_ = ok
if after, ok := strings.CutPrefix(s, pre); ok { // want "TrimPrefix can be simplified to CutPrefix"
println(after)
}
var predefined string
if predefined = strings.TrimPrefix(s, pre); s != predefined { // noop
println(predefined)
}
if predefined = strings.TrimPrefix(s, pre); s != predefined { // noop
println(&predefined)
}
var value string
if value = strings.TrimPrefix(s, pre); s != value { // noop
println(value)
}
lhsMap := make(map[string]string)
if lhsMap[""] = strings.TrimPrefix(s, pre); s != lhsMap[""] { // noop
println(lhsMap[""])
}
arr := make([]string, 0)
if arr[0] = strings.TrimPrefix(s, pre); s != arr[0] { // noop
println(arr[0])
}
type example struct {
field string
}
var e example
if e.field = strings.TrimPrefix(s, pre); s != e.field { // noop
println(e.field)
}
}
// test basic cases for pattern2 - CutSuffix
func _() {
if before, ok := strings.CutSuffix(s, suf); ok { // want "TrimSuffix can be simplified to CutSuffix"
println(before)
}
if before, ok := strings.CutSuffix(s, suf); ok { // want "TrimSuffix can be simplified to CutSuffix"
println(before)
}
}
// test cases that not supported by pattern2 - CutPrefix
func _() {
if after := strings.TrimPrefix(s, pre); s != pre { // noop
println(after)
}
if after := strings.TrimPrefix(s, pre); after != pre { // noop
println(after)
}
if strings.TrimPrefix(s, pre) != s {
println(strings.TrimPrefix(s, pre))
}
}
// test basic unsupported case for pattern2 - CutSuffix
func _() {
if before := strings.TrimSuffix(s, suf); s != suf { // noop
println(before)
}
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/testingcontext_test.go
================================================
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package testingcontext
import (
"context"
"testing"
)
func Test(t *testing.T) {
ctx := t.Context()
_ = ctx
func() {
ctx, cancel := context.WithCancel(context.Background()) // Nope. scope of defer is not the testing func.
defer cancel()
_ = ctx
}()
{
ctx := t.Context()
_ = ctx
var t int // not in scope of the call to WithCancel
_ = t
}
{
ctx := context.Background()
ctx, cancel := context.WithCancel(context.Background()) // Nope. ctx is redeclared.
defer cancel()
_ = ctx
}
{
var t int
ctx, cancel := context.WithCancel(context.Background()) // Nope. t is shadowed.
defer cancel()
_ = ctx
_ = t
}
t.Run("subtest", func(t2 *testing.T) {
ctx := t2.Context()
_ = ctx
})
}
func TestAlt(t2 *testing.T) {
ctx := t2.Context()
_ = ctx
}
func Testnot(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) // Nope. Not a test func.
defer cancel()
_ = ctx
}
func Benchmark(b *testing.B) {
ctx := b.Context()
_ = ctx
b.Run("subtest", func(b2 *testing.B) {
ctx := b2.Context()
_ = ctx
})
}
func Fuzz(f *testing.F) {
ctx := f.Context()
_ = ctx
}
================================================
FILE: pkg/golinters/modernize/testdata/fix/out/waitgroup.go
================================================
//go:build go1.25
//golangcitest:args -Emodernize
//golangcitest:expected_exitcode 0
package waitgroup
import (
"fmt"
"sync"
)
// supported case for pattern 1.
func _() {
var wg sync.WaitGroup
wg.Go(func() {
fmt.Println()
})
wg.Go(func() {
})
for range 10 {
wg.Go(func() {
fmt.Println()
})
}
}
// supported case for pattern 2.
func _() {
var wg sync.WaitGroup
wg.Go(func() {
fmt.Println()
})
wg.Go(func() {
})
for range 10 {
wg.Go(func() {
fmt.Println()
})
}
}
// this function puts some wrong usages but waitgroup modernizer will still offer fixes.
func _() {
var wg sync.WaitGroup
wg.Go(func() {
defer wg.Done()
fmt.Println()
})
wg.Go(func() {
fmt.Println()
wg.Done()
})
wg.Go(func() {
fmt.Println()
wg.Done()
})
}
// this function puts the unsupported cases of pattern 1.
func _() {
var wg sync.WaitGroup
wg.Add(1)
go func() {}()
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(1)
wg.Add(1)
go func() {
fmt.Println()
defer wg.Done()
}()
wg.Add(1)
go func() { // noop: no wg.Done call inside function body.
fmt.Println()
}()
go func() { // noop: no Add call before this go stmt.
defer wg.Done()
fmt.Println()
}()
wg.Add(2) // noop: only support Add(1).
go func() {
defer wg.Done()
}()
var wg1 sync.WaitGroup
wg1.Add(1) // noop: Add and Done should be the same object.
go func() {
defer wg.Done()
fmt.Println()
}()
wg.Add(1) // noop: Add and Done should be the same object.
go func() {
defer wg1.Done()
fmt.Println()
}()
}
// this function puts the unsupported cases of pattern 2.
func _() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
wg.Done()
fmt.Println()
}()
go func() { // noop: no Add call before this go stmt.
fmt.Println()
wg.Done()
}()
var wg1 sync.WaitGroup
wg1.Add(1) // noop: Add and Done should be the same object.
go func() {
fmt.Println()
wg.Done()
}()
wg.Add(1) // noop: Add and Done should be the same object.
go func() {
fmt.Println()
wg1.Done()
}()
}
type Server struct {
wg sync.WaitGroup
}
type ServerContainer struct {
serv Server
}
func _() {
var s Server
s.wg.Go(func() {
print()
})
var sc ServerContainer
sc.serv.wg.Go(func() {
print()
})
var wg sync.WaitGroup
arr := [1]*sync.WaitGroup{&wg}
arr[0].Go(func() {
print()
})
}
================================================
FILE: pkg/golinters/modernize/testdata/modernize_any.go
================================================
//golangcitest:args -Emodernize
package testdata
func _(x interface{}) {} // want "interface{} can be replaced by any"
func _() {
var x interface{} // want "interface{} can be replaced by any"
const any = 1
var y interface{} // nope: any is shadowed here
_, _ = x, y
}
================================================
FILE: pkg/golinters/modernize/testdata/modernize_custom.go
================================================
//golangcitest:args -Emodernize
//golangcitest:config_path testdata/modernize_custom.yml
//golangcitest:expected_exitcode 0
package testdata
func _(x interface{}) {}
func _() {
var x interface{}
const any = 1
var y interface{} // nope: any is shadowed here
_, _ = x, y
}
================================================
FILE: pkg/golinters/modernize/testdata/modernize_custom.yml
================================================
version: "2"
linters:
settings:
modernize:
disable:
- any
================================================
FILE: pkg/golinters/musttag/musttag.go
================================================
package musttag
import (
"go-simpler.org/musttag"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.MustTagSettings) *goanalysis.Linter {
var funcs []musttag.Func
if settings != nil {
for _, fn := range settings.Functions {
funcs = append(funcs, musttag.Func{
Name: fn.Name,
Tag: fn.Tag,
ArgPos: fn.ArgPos,
})
}
}
return goanalysis.
NewLinterFromAnalyzer(musttag.New(funcs...)).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/musttag/musttag_integration_test.go
================================================
package musttag
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/musttag/testdata/musttag.go
================================================
//golangcitest:args -Emusttag
package testdata
import (
"encoding/asn1"
"encoding/json"
)
// builtin functions:
func musttagJSON() {
var user struct {
Name string
Email string `json:"email"`
}
json.Marshal(user) // want "the given struct should be annotated with the `json` tag"
}
// custom functions from config:
func musttagASN1() {
var user struct {
Name string
Email string `asn1:"email"`
}
asn1.Marshal(user)
}
================================================
FILE: pkg/golinters/musttag/testdata/musttag.yml
================================================
version: "2"
linters:
settings:
musttag:
functions:
- name: encoding/asn1.Marshal
tag: asn1
arg-pos: 0
- name: encoding/asn1.Unmarshal
tag: asn1
arg-pos: 1
================================================
FILE: pkg/golinters/musttag/testdata/musttag_cgo.go
================================================
//golangcitest:args -Emusttag
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"encoding/asn1"
"encoding/json"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
// builtin functions:
func _() {
var user struct {
Name string
Email string `json:"email"`
}
json.Marshal(user) // want "the given struct should be annotated with the `json` tag"
}
// custom functions from config:
func _() {
var user struct {
Name string
Email string `asn1:"email"`
}
asn1.Marshal(user)
}
================================================
FILE: pkg/golinters/musttag/testdata/musttag_custom.go
================================================
//golangcitest:args -Emusttag
//golangcitest:config_path testdata/musttag.yml
package testdata
import (
"encoding/asn1"
"encoding/json"
)
// builtin functions:
func musttagJSONCustom() {
var user struct {
Name string
Email string `json:"email"`
}
json.Marshal(user) // want "the given struct should be annotated with the `json` tag"
}
// custom functions from config:
func musttagASN1Custom() {
var user struct {
Name string
Email string `asn1:"email"`
}
asn1.Marshal(user) // want "the given struct should be annotated with the `asn1` tag"
}
================================================
FILE: pkg/golinters/nakedret/nakedret.go
================================================
package nakedret
import (
"github.com/alexkohler/nakedret/v2"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.NakedretSettings) *goanalysis.Linter {
cfg := &nakedret.NakedReturnRunner{}
if settings != nil {
// SkipTestFiles is intentionally ignored => should be managed with `linters.exclusions.rules`.
cfg.MaxLength = settings.MaxFuncLines
}
return goanalysis.
NewLinterFromAnalyzer(nakedret.NakedReturnAnalyzer(cfg)).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/nakedret/nakedret_integration_test.go
================================================
package nakedret
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/nakedret/testdata/fix/in/nakedret.go
================================================
//golangcitest:args -Enakedret
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
func NakedretIssue() (a int, b string) {
if a > 0 {
return
}
fmt.Println("nakedret")
if b == "" {
return 0, "0"
}
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// len of this function is 33
return
}
func NoNakedretIssue() (a int, b string) {
if a > 0 {
return
}
if b == "" {
return 0, "0"
}
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// len of this function is 30
return
}
================================================
FILE: pkg/golinters/nakedret/testdata/fix/out/nakedret.go
================================================
//golangcitest:args -Enakedret
//golangcitest:expected_exitcode 0
package testdata
import "fmt"
func NakedretIssue() (a int, b string) {
if a > 0 {
return a, b
}
fmt.Println("nakedret")
if b == "" {
return 0, "0"
}
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// len of this function is 33
return a, b
}
func NoNakedretIssue() (a int, b string) {
if a > 0 {
return
}
if b == "" {
return 0, "0"
}
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// len of this function is 30
return
}
================================================
FILE: pkg/golinters/nakedret/testdata/nakedret.go
================================================
//golangcitest:args -Enakedret
package testdata
import "fmt"
func NakedretIssue() (a int, b string) {
if a > 0 {
return // want "naked return in func `NakedretIssue` with 33 lines of code"
}
fmt.Println("nakedret")
if b == "" {
return 0, "0"
}
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// len of this function is 33
return // want "naked return in func `NakedretIssue` with 33 lines of code"
}
func NoNakedretIssue() (a int, b string) {
if a > 0 {
return
}
if b == "" {
return 0, "0"
}
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// len of this function is 30
return
}
================================================
FILE: pkg/golinters/nakedret/testdata/nakedret_cgo.go
================================================
//golangcitest:args -Enakedret
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() (a int, b string) {
if a > 0 {
return // want "naked return in func `_` with 33 lines of code"
}
fmt.Println("nakedret")
if b == "" {
return 0, "0"
}
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// len of this function is 33
return // want "naked return in func `_` with 33 lines of code"
}
================================================
FILE: pkg/golinters/nestif/nestif.go
================================================
package nestif
import (
"github.com/nakabonne/nestif"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.NestifSettings) *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(&analysis.Analyzer{
Name: "nestif",
Doc: "Reports deeply nested if statements",
Run: func(pass *analysis.Pass) (any, error) {
runNestIf(pass, settings)
return nil, nil
},
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
func runNestIf(pass *analysis.Pass, settings *config.NestifSettings) {
checker := &nestif.Checker{
MinComplexity: settings.MinComplexity,
}
for _, file := range pass.Files {
position, isGoFile := goanalysis.GetGoFilePosition(pass, file)
if !isGoFile {
continue
}
issues := checker.Check(file, pass.Fset)
if len(issues) == 0 {
continue
}
nonAdjPosition := pass.Fset.PositionFor(file.Pos(), false)
f := pass.Fset.File(file.Pos())
for _, issue := range issues {
pass.Report(analysis.Diagnostic{
Pos: f.LineStart(goanalysis.AdjustPos(issue.Pos.Line, nonAdjPosition.Line, position.Line)),
Message: issue.Message,
})
}
}
}
================================================
FILE: pkg/golinters/nestif/nestif_integration_test.go
================================================
package nestif
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/nestif/testdata/nestif.go
================================================
//golangcitest:args -Enestif
//golangcitest:config_path testdata/nestif.yml
package testdata
func _() {
var b1, b2, b3, b4 bool
if b1 { // want "`if b1` has complex nested blocks \\(complexity: 1\\)"
if b2 { // +1
}
}
if b1 { // want "`if b1` has complex nested blocks \\(complexity: 3\\)"
if b2 { // +1
if b3 { // +2
}
}
}
if b1 { // want "`if b1` has complex nested blocks \\(complexity: 5\\)"
if b2 { // +1
} else if b3 { // +1
if b4 { // +2
}
} else { // +1
}
}
if b1 { // want "`if b1` has complex nested blocks \\(complexity: 9\\)"
if b2 { // +1
if b3 { // +2
}
}
if b2 { // +1
if b3 { // +2
if b4 { // +3
}
}
}
}
if b1 == b2 == b3 { // want "`if b1 == b2 == b3` has complex nested blocks \\(complexity: 1\\)"
if b4 { // +1
}
}
}
================================================
FILE: pkg/golinters/nestif/testdata/nestif.yml
================================================
version: "2"
linters:
settings:
nestif:
min-complexity: 1
================================================
FILE: pkg/golinters/nestif/testdata/nestif_cgo.go
================================================
//golangcitest:args -Enestif
//golangcitest:config_path testdata/nestif.yml
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() {
fmt.Println("nestif")
var b1, b2, b3, b4 bool
if b1 { // want "`if b1` has complex nested blocks \\(complexity: 1\\)"
if b2 { // +1
}
}
if b1 { // want "`if b1` has complex nested blocks \\(complexity: 3\\)"
if b2 { // +1
if b3 { // +2
}
}
}
if b1 { // want "`if b1` has complex nested blocks \\(complexity: 5\\)"
if b2 { // +1
} else if b3 { // +1
if b4 { // +2
}
} else { // +1
}
}
if b1 { // want "`if b1` has complex nested blocks \\(complexity: 9\\)"
if b2 { // +1
if b3 { // +2
}
}
if b2 { // +1
if b3 { // +2
if b4 { // +3
}
}
}
}
if b1 == b2 == b3 { // want "`if b1 == b2 == b3` has complex nested blocks \\(complexity: 1\\)"
if b4 { // +1
}
}
}
================================================
FILE: pkg/golinters/nilerr/nilerr.go
================================================
package nilerr
import (
"github.com/gostaticanalysis/nilerr"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(nilerr.Analyzer).
WithDesc("Find the code that returns nil even if it checks that the error is not nil.").
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/nilerr/nilerr_integration_test.go
================================================
package nilerr
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/nilerr/testdata/nilerr.go
================================================
//golangcitest:args -Enilerr
package testdata
import "os"
func nilErr1() error {
err := nilErrDo()
if err == nil {
return err // want `error is nil \(line 7\) but it returns error`
}
return nil
}
func nilErr2() error {
err := nilErrDo()
if err == nil {
return err // want `error is nil \(line 16\) but it returns error`
}
return nil
}
func nilErr3() error {
err := nilErrDo()
if err != nil {
return nil // want `error is not nil \(line 25\) but it returns nil`
}
return nil
}
func nilErrDo() error {
return os.ErrNotExist
}
func l() error {
aChan := make(chan error, 1)
bChan := make(chan error, 1)
var aErr error
var bErr error
for i := 0; i < 2; i++ {
select {
case err := <-aChan:
aErr = err
case err := <-bChan:
bErr = err
}
}
if aErr != nil {
return nil // want `error is not nil \(lines \[41 45\]\) but it returns nil`
}
if bErr != nil {
return nil // want `error is not nil \(lines \[42 45\]\) but it returns nil`
}
return nil
}
================================================
FILE: pkg/golinters/nilerr/testdata/nilerr_cgo.go
================================================
//golangcitest:args -Enilerr
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"os"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() error {
err := nilErrDo()
if err == nil {
return err // want `error is nil \(line 26\) but it returns error`
}
return nil
}
func nilErrDo() error {
return os.ErrNotExist
}
================================================
FILE: pkg/golinters/nilnesserr/nilnesserr.go
================================================
package nilnesserr
import (
"github.com/alingse/nilnesserr"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New() *goanalysis.Linter {
analyzer, err := nilnesserr.NewAnalyzer(nilnesserr.LinterSetting{})
if err != nil {
internal.LinterLogger.Fatalf("nilnesserr: create analyzer: %v", err)
}
return goanalysis.
NewLinterFromAnalyzer(analyzer).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/nilnesserr/nilnesserr_integration_test.go
================================================
package nilnesserr
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/nilnesserr/testdata/nilnesserr.go
================================================
//golangcitest:args -Enilnesserr
package testdata
import "fmt"
func do() error {
return fmt.Errorf("do error")
}
func do2() error {
return fmt.Errorf("do2 error")
}
func someCall() error {
err := do()
if err != nil {
return err
}
err2 := do2()
if err2 != nil {
return err // want `return a nil value error after check error`
}
return nil
}
func sameCall2() error {
err := do()
if err == nil {
err2 := do2()
if err2 != nil {
return err // want `return a nil value error after check error`
}
return nil
}
return err
}
================================================
FILE: pkg/golinters/nilnesserr/testdata/nilnesserr_cgo.go
================================================
//golangcitest:args -Enilnesserr
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func do() error {
return fmt.Errorf("do error")
}
func do2() error {
return fmt.Errorf("do2 error")
}
func someCall() error {
err := do()
if err != nil {
return err
}
err2 := do2()
if err2 != nil {
return err // want `return a nil value error after check error`
}
return nil
}
func sameCall2() error {
err := do()
if err == nil {
err2 := do2()
if err2 != nil {
return err // want `return a nil value error after check error`
}
return nil
}
return err
}
================================================
FILE: pkg/golinters/nilnil/nilnil.go
================================================
package nilnil
import (
"github.com/Antonboom/nilnil/pkg/analyzer"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.NilNilSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"detect-opposite": settings.DetectOpposite,
}
if b := settings.OnlyTwo; b != nil {
cfg["only-two"] = *b
}
if len(settings.CheckedTypes) != 0 {
cfg["checked-types"] = settings.CheckedTypes
}
}
return goanalysis.
NewLinterFromAnalyzer(analyzer.New()).
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/nilnil/nilnil_integration_test.go
================================================
package nilnil
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/nilnil/testdata/nilnil.go
================================================
//golangcitest:args -Enilnil
package testdata
import (
"bytes"
"errors"
"fmt"
"go/token"
"io"
"net"
"net/http"
"os"
"unsafe"
)
type User struct{}
func primitivePtr() (*int, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func structPtr() (*User, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func emptyStructPtr() (*struct{}, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func anonymousStructPtr() (*struct{ ID string }, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func unsafePtr() (unsafe.Pointer, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func uintPtr() (uintptr, error) {
return 0, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func uintPtr0b() (uintptr, error) {
return 0b0, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func uintPtr0x() (uintptr, error) {
return 0x00, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func uintPtr0o() (uintptr, error) {
return 0o000, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func chBi() (chan int, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func chIn() (chan<- int, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func chOut() (<-chan int, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func fun() (func(), error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func funWithArgsAndResults() (func(a, b, c int) (int, int), error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func iface() (interface{}, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func anyType() (any, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func m1() (map[int]int, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func m2() (map[int]*User, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
type mapAlias = map[int]*User
func m3() (mapAlias, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
type Storage struct{}
func (s *Storage) GetUser() (*User, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func ifReturn() (*User, error) {
var s Storage
if _, err := s.GetUser(); err != nil {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
return new(User), nil
}
func forReturn() (*User, error) {
for {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
}
func multipleReturn() (*User, error) {
var s Storage
if _, err := s.GetUser(); err != nil {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
if _, err := s.GetUser(); err != nil {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
if _, err := s.GetUser(); err != nil {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
return new(User), nil
}
func nested() {
_ = func() (*User, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
_, _ = func() (*User, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}()
}
func deeplyNested() {
_ = func() {
_ = func() int {
_ = func() {
_ = func() (*User, error) {
_ = func() {}
_ = func() int { return 0 }
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
}
return 0
}
}
}
type MyError interface {
error
Code() string
}
func myError() (*User, MyError) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
// Types.
func structPtrTypeExtPkg() (*os.File, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func primitivePtrTypeExtPkg() (*token.Token, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func funcTypeExtPkg() (http.HandlerFunc, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func ifaceTypeExtPkg() (io.Closer, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
type closerAlias = io.Closer
func ifaceTypeAliasedExtPkg() (closerAlias, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
type (
StructPtrType *User
PrimitivePtrType *int
ChannelType chan int
FuncType func(int) int
Checker interface{ Check() }
)
func structPtrType() (StructPtrType, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func primitivePtrType() (PrimitivePtrType, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func channelType() (ChannelType, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func funcType() (FuncType, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func ifaceType() (Checker, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
type checkerAlias = Checker
func ifaceTypeAliased() (checkerAlias, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
type (
IntegerType int
PtrIntegerType *IntegerType
)
func ptrIntegerType() (PtrIntegerType, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
// Not checked at all.
func withoutArgs() {}
func withoutError1() *User { return nil }
func withoutError2() (*User, *User) { return nil, nil }
func withoutError3() (*User, *User, *User) { return nil, nil, nil }
func withoutError4() (*User, *User, *User, *User) { return nil, nil, nil, nil }
func invalidOrder() (error, *User) { return nil, nil }
func withError3rd() (*User, bool, error) { return nil, false, nil }
func withError4th() (*User, *User, *User, error) { return nil, nil, nil, nil }
func slice() ([]int, error) { return nil, nil }
func strNil() (string, error) { return "nil", nil }
func strEmpty() (string, error) { return "", nil }
// Valid.
func primitivePtrTypeValid() (*int, error) {
if false {
return nil, io.EOF
}
return new(int), nil
}
func structPtrTypeValid() (*User, error) {
if false {
return nil, io.EOF
}
return new(User), nil
}
func unsafePtrValid() (unsafe.Pointer, error) {
if false {
return nil, io.EOF
}
var i int
return unsafe.Pointer(&i), nil
}
func uintPtrValid() (uintptr, error) {
if false {
return 0, io.EOF
}
return 0xc82000c290, nil
}
func channelTypeValid() (ChannelType, error) {
if false {
return nil, io.EOF
}
return make(ChannelType), nil
}
func funcTypeValid() (FuncType, error) {
if false {
return nil, io.EOF
}
return func(i int) int {
return 0
}, nil
}
func ifaceTypeValid() (io.Reader, error) {
if false {
return nil, io.EOF
}
return new(bytes.Buffer), nil
}
// Unsupported.
func implicitNil1() (*User, error) {
err := (error)(nil)
return nil, err
}
func implicitNil2() (*User, error) {
err := io.EOF
err = nil
return nil, err
}
func implicitNil3() (*User, error) {
return nil, wrap(nil)
}
func wrap(err error) error { return err }
// Opposite.
func primitivePtrTypeOpposite() (*int, error) {
if false {
return nil, io.EOF
}
return new(int), errors.New("validation failed")
}
func structPtrTypeOpposite() (*User, error) {
if false {
return nil, io.EOF
}
return new(User), fmt.Errorf("invalid %v", 42)
}
func unsafePtrOpposite() (unsafe.Pointer, error) {
if false {
return nil, io.EOF
}
var i int
return unsafe.Pointer(&i), io.EOF
}
func uintPtrOpposite() (uintptr, error) {
if false {
return 0, io.EOF
}
return 0xc82000c290, wrap(io.EOF)
}
func channelTypeOpposite() (ChannelType, error) {
if false {
return nil, io.EOF
}
return make(ChannelType), fmt.Errorf("wrapped: %w", io.EOF)
}
func funcTypeOpposite() (FuncType, error) {
if false {
return nil, io.EOF
}
return func(i int) int {
return 0
}, errors.New("no func type, please")
}
func ifaceTypeOpposite() (io.Reader, error) {
if false {
return nil, io.EOF
}
return new(bytes.Buffer), new(net.AddrError)
}
================================================
FILE: pkg/golinters/nilnil/testdata/nilnil_cgo.go
================================================
//golangcitest:args -Enilnil
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func _() (unsafe.Pointer, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
================================================
FILE: pkg/golinters/nilnil/testdata/nilnil_detect_opposite.go
================================================
//golangcitest:args -Enilnil
//golangcitest:config_path testdata/nilnil_detect_opposite.yml
package testdata
import (
"bytes"
"errors"
"fmt"
"io"
"net"
"unsafe"
)
func primitivePtrTypeOpposite() (*int, error) {
if false {
return nil, io.EOF
}
return new(int), errors.New("validation failed") // want "return both a non-nil error and a valid value: use separate returns instead"
}
func structPtrTypeOpposite() (*User, error) {
if false {
return nil, io.EOF
}
return new(User), fmt.Errorf("invalid %v", 42) // want "return both a non-nil error and a valid value: use separate returns instead"
}
func unsafePtrOpposite() (unsafe.Pointer, error) {
if false {
return nil, io.EOF
}
var i int
return unsafe.Pointer(&i), io.EOF // want "return both a non-nil error and a valid value: use separate returns instead"
}
func uintPtrOpposite() (uintptr, error) {
if false {
return 0, io.EOF
}
return 0xc82000c290, wrap(io.EOF) // want "return both a non-nil error and a valid value: use separate returns instead"
}
func channelTypeOpposite() (ChannelType, error) {
if false {
return nil, io.EOF
}
return make(ChannelType), fmt.Errorf("wrapped: %w", io.EOF) // want "return both a non-nil error and a valid value: use separate returns instead"
}
func funcTypeOpposite() (FuncType, error) {
if false {
return nil, io.EOF
}
return func(i int) int { // want "return both a non-nil error and a valid value: use separate returns instead"
return 0
}, errors.New("no func type, please")
}
func ifaceTypeOpposite() (io.Reader, error) {
if false {
return nil, io.EOF
}
return new(bytes.Buffer), new(net.AddrError) // want "return both a non-nil error and a valid value: use separate returns instead"
}
type (
User struct{}
StructPtrType *User
PrimitivePtrType *int
ChannelType chan int
FuncType func(int) int
Checker interface{ Check() }
)
func wrap(err error) error { return err }
func structPtr() (*int, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func structPtrValid() (*int, error) {
return new(int), nil
}
================================================
FILE: pkg/golinters/nilnil/testdata/nilnil_detect_opposite.yml
================================================
version: "2"
linters:
settings:
nilnil:
detect-opposite: true
================================================
FILE: pkg/golinters/nilnil/testdata/nilnil_multiple_nils.go
================================================
//golangcitest:args -Enilnil
//golangcitest:config_path testdata/nilnil_multiple_nils.yml
package testdata
func withoutArgs() {}
func withoutError1() *User { return nil }
func withoutError2() (*User, *User) { return nil, nil }
func withoutError3() (*User, *User, *User) { return nil, nil, nil }
func withoutError4() (*User, *User, *User, *User) { return nil, nil, nil, nil }
func invalidOrder() (error, *User) { return nil, nil }
func withError3rd() (*User, bool, error) { return nil, false, nil } // want "return both a `nil` error and an invalid value: use a sentinel error instead"
func withError4th() (*User, *User, *User, error) { return nil, nil, nil, nil } // want "return both a `nil` error and an invalid value: use a sentinel error instead"
type User struct{}
================================================
FILE: pkg/golinters/nilnil/testdata/nilnil_multiple_nils.yml
================================================
version: "2"
linters:
settings:
nilnil:
only-two: false
================================================
FILE: pkg/golinters/nilnil/testdata/nilnil_pointers_only.go
================================================
//golangcitest:args -Enilnil
//golangcitest:config_path testdata/nilnil_pointers_only.yml
package testdata
import "unsafe"
type User struct{}
func primitivePtr() (*int, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func structPtr() (*User, error) {
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func unsafePtr() (unsafe.Pointer, error) {
return nil, nil
}
func uintPtr0o() (uintptr, error) {
return 0o000, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
}
func chBi() (chan int, error) {
return nil, nil
}
func fun() (func(), error) {
return nil, nil
}
func anyType() (any, error) {
return nil, nil
}
func m1() (map[int]int, error) {
return nil, nil
}
================================================
FILE: pkg/golinters/nilnil/testdata/nilnil_pointers_only.yml
================================================
version: "2"
linters:
settings:
nilnil:
checked-types:
- ptr
- uintptr
================================================
FILE: pkg/golinters/nlreturn/nlreturn.go
================================================
package nlreturn
import (
"github.com/ssgreg/nlreturn/v2/pkg/nlreturn"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.NlreturnSettings) *goanalysis.Linter {
var cfg map[string]any
if settings != nil {
cfg = map[string]any{
"block-size": settings.BlockSize,
}
}
return goanalysis.
NewLinterFromAnalyzer(nlreturn.NewAnalyzer()).
WithDesc("Checks for a new line before return and branch statements to increase code clarity").
WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeSyntax)
}
================================================
FILE: pkg/golinters/nlreturn/nlreturn_integration_test.go
================================================
package nlreturn
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/nlreturn/testdata/fix/in/nlreturn.go
================================================
//golangcitest:args -Enlreturn
//golangcitest:expected_exitcode 0
package testdata
func cha() {
ch := make(chan interface{})
ch1 := make(chan interface{})
ch2 := make(chan interface{})
select {
case <-ch:
return
case <-ch1:
{
a := 1
_ = a
{
a := 1
_ = a
return // want "return with no blank line before"
}
return
}
return
case <-ch2:
{
a := 1
_ = a
return // want "return with no blank line before"
}
return // want "return with no blank line before"
}
}
func baz() {
switch 0 {
case 0:
a := 1
_ = a
fallthrough // want "fallthrough with no blank line before"
case 1:
a := 1
_ = a
break // want "break with no blank line before"
case 2:
break
}
}
func foo() int {
v := []int{}
for range v {
return 0
}
for range v {
for range v {
return 0
}
return 0 // want "return with no blank line before"
}
o := []int{
0, 1,
}
return o[0]
}
func bar() int {
o := 1
if o == 1 {
if o == 0 {
return 1
}
return 0 // want "return with no blank line before"
}
return o
}
func main() {
return
}
func bugNoAssignSmthHandling() string {
switch 0 {
case 0:
o := struct {
foo string
}{
"foo",
}
return o.foo // want "return with no blank line before"
case 1:
o := struct {
foo string
}{
"foo",
}
return o.foo
}
return ""
}
func bugNoExprSmthHandling(string) {
switch 0 {
case 0:
bugNoExprSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
bugNoExprSmthHandling(
"",
)
return
}
}
func bugNoDeferSmthHandling(string) {
switch 0 {
case 0:
defer bugNoDeferSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
defer bugNoDeferSmthHandling(
"",
)
return
}
}
func bugNoGoSmthHandling(string) {
switch 0 {
case 0:
go bugNoGoSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
go bugNoGoSmthHandling(
"",
)
return
}
}
================================================
FILE: pkg/golinters/nlreturn/testdata/fix/out/nlreturn.go
================================================
//golangcitest:args -Enlreturn
//golangcitest:expected_exitcode 0
package testdata
func cha() {
ch := make(chan interface{})
ch1 := make(chan interface{})
ch2 := make(chan interface{})
select {
case <-ch:
return
case <-ch1:
{
a := 1
_ = a
{
a := 1
_ = a
return // want "return with no blank line before"
}
return
}
return
case <-ch2:
{
a := 1
_ = a
return // want "return with no blank line before"
}
return // want "return with no blank line before"
}
}
func baz() {
switch 0 {
case 0:
a := 1
_ = a
fallthrough // want "fallthrough with no blank line before"
case 1:
a := 1
_ = a
break // want "break with no blank line before"
case 2:
break
}
}
func foo() int {
v := []int{}
for range v {
return 0
}
for range v {
for range v {
return 0
}
return 0 // want "return with no blank line before"
}
o := []int{
0, 1,
}
return o[0]
}
func bar() int {
o := 1
if o == 1 {
if o == 0 {
return 1
}
return 0 // want "return with no blank line before"
}
return o
}
func main() {
return
}
func bugNoAssignSmthHandling() string {
switch 0 {
case 0:
o := struct {
foo string
}{
"foo",
}
return o.foo // want "return with no blank line before"
case 1:
o := struct {
foo string
}{
"foo",
}
return o.foo
}
return ""
}
func bugNoExprSmthHandling(string) {
switch 0 {
case 0:
bugNoExprSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
bugNoExprSmthHandling(
"",
)
return
}
}
func bugNoDeferSmthHandling(string) {
switch 0 {
case 0:
defer bugNoDeferSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
defer bugNoDeferSmthHandling(
"",
)
return
}
}
func bugNoGoSmthHandling(string) {
switch 0 {
case 0:
go bugNoGoSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
go bugNoGoSmthHandling(
"",
)
return
}
}
================================================
FILE: pkg/golinters/nlreturn/testdata/nlreturn-block-size.go
================================================
//golangcitest:args -Enlreturn
//golangcitest:config_path testdata/nlreturn-block-size.yml
package testdata
func foo0(n int) int {
if n == 1 {
n2 := n * n
return n2
}
return 1
}
func foo1(n int) int {
if n == 1 {
n2 := n * n
n3 := n2 * n
return n3 // want "return with no blank line before"
}
return 1
}
================================================
FILE: pkg/golinters/nlreturn/testdata/nlreturn-block-size.yml
================================================
version: "2"
linters:
settings:
nlreturn:
block-size: 2
================================================
FILE: pkg/golinters/nlreturn/testdata/nlreturn.go
================================================
//golangcitest:args -Enlreturn
package testdata
func cha() {
ch := make(chan interface{})
ch1 := make(chan interface{})
ch2 := make(chan interface{})
select {
case <-ch:
return
case <-ch1:
{
a := 1
_ = a
{
a := 1
_ = a
return // want "return with no blank line before"
}
return
}
return
case <-ch2:
{
a := 1
_ = a
return // want "return with no blank line before"
}
return // want "return with no blank line before"
}
}
func baz() {
switch 0 {
case 0:
a := 1
_ = a
fallthrough // want "fallthrough with no blank line before"
case 1:
a := 1
_ = a
break // want "break with no blank line before"
case 2:
break
}
}
func foo() int {
v := []int{}
for range v {
return 0
}
for range v {
for range v {
return 0
}
return 0 // want "return with no blank line before"
}
o := []int{
0, 1,
}
return o[0]
}
func bar() int {
o := 1
if o == 1 {
if o == 0 {
return 1
}
return 0 // want "return with no blank line before"
}
return o
}
func main() {
return
}
func bugNoAssignSmthHandling() string {
switch 0 {
case 0:
o := struct {
foo string
}{
"foo",
}
return o.foo // want "return with no blank line before"
case 1:
o := struct {
foo string
}{
"foo",
}
return o.foo
}
return ""
}
func bugNoExprSmthHandling(string) {
switch 0 {
case 0:
bugNoExprSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
bugNoExprSmthHandling(
"",
)
return
}
}
func bugNoDeferSmthHandling(string) {
switch 0 {
case 0:
defer bugNoDeferSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
defer bugNoDeferSmthHandling(
"",
)
return
}
}
func bugNoGoSmthHandling(string) {
switch 0 {
case 0:
go bugNoGoSmthHandling(
"",
)
return // want "return with no blank line before"
case 1:
go bugNoGoSmthHandling(
"",
)
return
}
}
================================================
FILE: pkg/golinters/nlreturn/testdata/nlreturn_cgo.go
================================================
//golangcitest:args -Enlreturn
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"math"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func cha() {
ch := make(chan interface{})
ch1 := make(chan interface{})
ch2 := make(chan interface{})
select {
case <-ch:
return
case <-ch1:
{
a := math.MaxInt
_ = a
{
a := 1
_ = a
return // want "return with no blank line before"
}
return
}
return
case <-ch2:
{
a := 1
_ = a
return // want "return with no blank line before"
}
return // want "return with no blank line before"
}
}
================================================
FILE: pkg/golinters/noctx/noctx.go
================================================
package noctx
import (
"github.com/sonatard/noctx"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(noctx.Analyzer).
WithDesc("Detects function and method with missing usage of context.Context").
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/noctx/noctx_integration_test.go
================================================
package noctx
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
================================================
FILE: pkg/golinters/noctx/testdata/noctx.go
================================================
//golangcitest:args -Enoctx
package testdata
import (
"context"
"database/sql"
"net/http"
)
var newRequestPkg = http.NewRequest
func _() {
const url = "https://example.com"
cli := &http.Client{}
ctx := context.Background()
req, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
cli.Do(req)
req2, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, nil) // OK
cli.Do(req2)
req3, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req3 = req3.WithContext(ctx)
cli.Do(req3)
f2 := func(req *http.Request, ctx context.Context) *http.Request {
return req
}
req4, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req4 = f2(req4, ctx)
req41, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req41 = req41.WithContext(ctx)
req41 = f2(req41, ctx)
newRequest := http.NewRequest
req5, _ := newRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
cli.Do(req5)
req51, _ := newRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req51 = req51.WithContext(ctx)
cli.Do(req51)
req52, _ := newRequestPkg(http.MethodPost, url, nil) // TODO: false negative `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
cli.Do(req52)
type MyRequest = http.Request
f3 := func(req *MyRequest, ctx context.Context) *MyRequest {
return req
}
req6, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req6 = f3(req6, ctx)
req61, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req61 = req61.WithContext(ctx)
req61 = f3(req61, ctx)
type MyRequest2 http.Request
f4 := func(req *MyRequest2, ctx context.Context) *MyRequest2 {
return req
}
req7, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req71 := MyRequest2(*req7)
f4(&req71, ctx)
req72, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req72 = req72.WithContext(ctx)
req73 := MyRequest2(*req7)
f4(&req73, ctx)
req8, _ := func() (*http.Request, error) {
return http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
}()
cli.Do(req8)
req82, _ := func() (*http.Request, error) {
req82, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req82 = req82.WithContext(ctx)
return req82, nil
}()
cli.Do(req82)
f5 := func(req, req2 *http.Request, ctx context.Context) (*http.Request, *http.Request) {
return req, req2
}
req9, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req9, _ = f5(req9, req9, ctx)
req91, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req91 = req91.WithContext(ctx)
req9, _ = f5(req91, req91, ctx)
req10, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req11, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req10, req11 = f5(req10, req11, ctx)
req101, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req111, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req111 = req111.WithContext(ctx)
req101, req111 = f5(req101, req111, ctx)
func() (*http.Request, *http.Request) {
req12, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req13, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
return req12, req13
}()
func() (*http.Request, *http.Request) {
req14, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req15, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req15 = req15.WithContext(ctx)
return req14, req15
}()
req121, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req121.AddCookie(&http.Cookie{Name: "k", Value: "v"})
req121 = req121.WithContext(context.WithValue(req121.Context(), struct{}{}, 0))
cli.Do(req121)
}
func _() {
const url = "http://example.com"
cli := &http.Client{}
http.Get(url) // want `net/http\.Get must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
_ = http.Get // OK
f := http.Get // OK
f(url) // want `net/http\.Get must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
http.Head(url) // want `net/http\.Head must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
http.Post(url, "", nil) // want `net/http\.Post must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
http.PostForm(url, nil) // want `net/http\.PostForm must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
cli.Get(url) // want `\(\*net/http\.Client\)\.Get must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
_ = cli.Get // OK
m := cli.Get // OK
m(url) // want `\(\*net/http\.Client\)\.Get must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
cli.Head(url) // want `\(\*net/http\.Client\)\.Head must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
cli.Post(url, "", nil) // want `\(\*net/http\.Client\)\.Post must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
cli.PostForm(url, nil) // want `\(\*net/http\.Client\)\.PostForm must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
}
func _() {
ctx := context.Background()
db, _ := sql.Open("noctx", "noctx://")
db.Exec("select * from testdata") // want `\(\*database/sql\.DB\)\.Exec must not be called. use \(\*database/sql\.DB\)\.ExecContext`
db.ExecContext(ctx, "select * from testdata")
db.Ping() // want `\(\*database/sql\.DB\)\.Ping must not be called. use \(\*database/sql\.DB\)\.PingContext`
db.PingContext(ctx)
db.Prepare("select * from testdata") // want `\(\*database/sql\.DB\)\.Prepare must not be called. use \(\*database/sql\.DB\)\.PrepareContext`
db.PrepareContext(ctx, "select * from testdata")
db.Query("select * from testdata") // want `\(\*database/sql\.DB\)\.Query must not be called. use \(\*database/sql\.DB\)\.QueryContext`
db.QueryContext(ctx, "select * from testdata")
db.QueryRow("select * from testdata") // want `\(\*database/sql\.DB\)\.QueryRow must not be called. use \(\*database/sql\.DB\)\.QueryRowContext`
db.QueryRowContext(ctx, "select * from testdata")
// transactions
tx, _ := db.Begin() // want `\(\*database/sql\.DB\)\.Begin must not be called. use \(\*database/sql\.DB\)\.BeginTx`
tx.Exec("select * from testdata") // want `\(\*database/sql\.Tx\)\.Exec must not be called. use \(\*database/sql\.Tx\)\.ExecContext`
tx.ExecContext(ctx, "select * from testdata")
tx.Prepare("select * from testdata") // want `\(\*database/sql\.Tx\)\.Prepare must not be called. use \(\*database/sql\.Tx\)\.PrepareContext`
tx.PrepareContext(ctx, "select * from testdata")
tx.Query("select * from testdata") // want `\(\*database/sql\.Tx\)\.Query must not be called. use \(\*database/sql\.Tx\)\.QueryContext`
tx.QueryContext(ctx, "select * from testdata")
tx.QueryRow("select * from testdata") // want `\(\*database/sql\.Tx\)\.QueryRow must not be called. use \(\*database/sql\.Tx\)\.QueryRowContext`
tx.QueryRowContext(ctx, "select * from testdata")
_ = tx.Commit()
}
================================================
FILE: pkg/golinters/noctx/testdata/noctx_cgo.go
================================================
//golangcitest:args -Enoctx
package testdata
/*
#include
#include
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"context"
"database/sql"
"net/http"
"unsafe"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
var newRequestPkg = http.NewRequest
func _() {
const url = "https://example.com"
cli := &http.Client{}
ctx := context.Background()
req, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
cli.Do(req)
req2, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, nil) // OK
cli.Do(req2)
req3, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req3 = req3.WithContext(ctx)
cli.Do(req3)
f2 := func(req *http.Request, ctx context.Context) *http.Request {
return req
}
req4, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req4 = f2(req4, ctx)
req41, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req41 = req41.WithContext(ctx)
req41 = f2(req41, ctx)
newRequest := http.NewRequest
req5, _ := newRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
cli.Do(req5)
req51, _ := newRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req51 = req51.WithContext(ctx)
cli.Do(req51)
req52, _ := newRequestPkg(http.MethodPost, url, nil) // TODO: false negative `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
cli.Do(req52)
type MyRequest = http.Request
f3 := func(req *MyRequest, ctx context.Context) *MyRequest {
return req
}
req6, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req6 = f3(req6, ctx)
req61, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req61 = req61.WithContext(ctx)
req61 = f3(req61, ctx)
type MyRequest2 http.Request
f4 := func(req *MyRequest2, ctx context.Context) *MyRequest2 {
return req
}
req7, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req71 := MyRequest2(*req7)
f4(&req71, ctx)
req72, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req72 = req72.WithContext(ctx)
req73 := MyRequest2(*req7)
f4(&req73, ctx)
req8, _ := func() (*http.Request, error) {
return http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
}()
cli.Do(req8)
req82, _ := func() (*http.Request, error) {
req82, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req82 = req82.WithContext(ctx)
return req82, nil
}()
cli.Do(req82)
f5 := func(req, req2 *http.Request, ctx context.Context) (*http.Request, *http.Request) {
return req, req2
}
req9, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req9, _ = f5(req9, req9, ctx)
req91, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req91 = req91.WithContext(ctx)
req9, _ = f5(req91, req91, ctx)
req10, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req11, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req10, req11 = f5(req10, req11, ctx)
req101, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req111, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req111 = req111.WithContext(ctx)
req101, req111 = f5(req101, req111, ctx)
func() (*http.Request, *http.Request) {
req12, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req13, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
return req12, req13
}()
func() (*http.Request, *http.Request) {
req14, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req15, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req15 = req15.WithContext(ctx)
return req14, req15
}()
req121, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext`
req121.AddCookie(&http.Cookie{Name: "k", Value: "v"})
req121 = req121.WithContext(context.WithValue(req121.Context(), struct{}{}, 0))
cli.Do(req121)
}
func _() {
const url = "http://example.com"
cli := &http.Client{}
http.Get(url) // want `net/http\.Get must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
_ = http.Get // OK
f := http.Get // OK
f(url) // want `net/http\.Get must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
http.Head(url) // want `net/http\.Head must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
http.Post(url, "", nil) // want `net/http\.Post must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
http.PostForm(url, nil) // want `net/http\.PostForm must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)`
cli.Get(url) // want `\(\*net/http\.Client\)\.Get must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
_ = cli.Get // OK
m := cli.Get // OK
m(url) // want `\(\*net/http\.Client\)\.Get must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
cli.Head(url) // want `\(\*net/http\.Client\)\.Head must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
cli.Post(url, "", nil) // want `\(\*net/http\.Client\)\.Post must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
cli.PostForm(url, nil) // want `\(\*net/http\.Client\)\.PostForm must not be called. use \(\*net/http.Client\)\.Do\(\*http.Request\)`
}
func _() {
ctx := context.Background()
db, _ := sql.Open("noctx", "noctx://")
db.Exec("select * from testdata") // want `\(\*database/sql\.DB\)\.Exec must not be called. use \(\*database/sql\.DB\)\.ExecContext`
db.ExecContext(ctx, "select * from testdata")
db.Ping() // want `\(\*database/sql\.DB\)\.Ping must not be called. use \(\*database/sql\.DB\)\.PingContext`
db.PingContext(ctx)
db.Prepare("select * from testdata") // want `\(\*database/sql\.DB\)\.Prepare must not be called. use \(\*database/sql\.DB\)\.PrepareContext`
db.PrepareContext(ctx, "select * from testdata")
db.Query("select * from testdata") // want `\(\*database/sql\.DB\)\.Query must not be called. use \(\*database/sql\.DB\)\.QueryContext`
db.QueryContext(ctx, "select * from testdata")
db.QueryRow("select * from testdata") // want `\(\*database/sql\.DB\)\.QueryRow must not be called. use \(\*database/sql\.DB\)\.QueryRowContext`
db.QueryRowContext(ctx, "select * from testdata")
// transactions
tx, _ := db.Begin() // want `\(\*database/sql\.DB\)\.Begin must not be called. use \(\*database/sql\.DB\)\.BeginTx`
tx.Exec("select * from testdata") // want `\(\*database/sql\.Tx\)\.Exec must not be called. use \(\*database/sql\.Tx\)\.ExecContext`
tx.ExecContext(ctx, "select * from testdata")
tx.Prepare("select * from testdata") // want `\(\*database/sql\.Tx\)\.Prepare must not be called. use \(\*database/sql\.Tx\)\.PrepareContext`
tx.PrepareContext(ctx, "select * from testdata")
tx.Query("select * from testdata") // want `\(\*database/sql\.Tx\)\.Query must not be called. use \(\*database/sql\.Tx\)\.QueryContext`
tx.QueryContext(ctx, "select * from testdata")
tx.QueryRow("select * from testdata") // want `\(\*database/sql\.Tx\)\.QueryRow must not be called. use \(\*database/sql\.Tx\)\.QueryRowContext`
tx.QueryRowContext(ctx, "select * from testdata")
_ = tx.Commit()
}
================================================
FILE: pkg/golinters/noinlineerr/noinlineerr.go
================================================
package noinlineerr
import (
"github.com/AlwxSin/noinlineerr"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
return goanalysis.
NewLinterFromAnalyzer(noinlineerr.NewAnalyzer()).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
================================================
FILE: pkg/golinters/noinlineerr/noinlineerr_integration_test.go
================================================
package noinlineerr
import (
"testing"
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
)
func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}
func TestFix(t *testing.T) {
integration.RunFix(t)
}
func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
================================================
FILE: pkg/golinters/noinlineerr/testdata/fix/in/noinlineerr.go
================================================
//golangcitest:args -Enoinlineerr
//golangcitest:expected_exitcode 0
package testdata
type MyAliasErr error
type MyCustomError struct{}
func (mc *MyCustomError) Error() string {
return "error"
}
func doSomething() error {
return nil
}
func doSmthManyArgs(a, b, c, d int) error {
return nil
}
func doSmthMultipleReturn() (bool, error) {
return false, nil
}
func doMyAliasErr() MyAliasErr {
return nil
}
func doMyCustomErr() *MyCustomError {
return &MyCustomError{}
}
func invalid() error {
err := doSomething()
if err != nil {
return err
}
err = doSmthManyArgs(0,
0,
0,
0,
)
if err != nil {
return err
}
err = doMyAliasErr()
if err != nil {
return err
}
err = doMyCustomErr()
if err != nil {
return err
}
return nil
}
================================================
FILE: pkg/golinters/noinlineerr/testdata/fix/out/noinlineerr.go
================================================
//golangcitest:args -Enoinlineerr
//golangcitest:expected_exitcode 0
package testdata
type MyAliasErr error
type MyCustomError struct{}
func (mc *MyCustomError) Error() string {
return "error"
}
func doSomething() error {
return nil
}
func doSmthManyArgs(a, b, c, d int) error {
return nil
}
func doSmthMultipleReturn() (bool, error) {
return false, nil
}
func doMyAliasErr() MyAliasErr {
return nil
}
func doMyCustomErr() *MyCustomError {
return &MyCustomError{}
}
func invalid() error {
err := doSomething()
if err != nil {
return err
}
err = doSmthManyArgs(0,
0,
0,
0,
)
if err != nil {
return err
}
err = doMyAliasErr()
if err != nil {
return err
}
err = doMyCustomErr()
if err != nil {
return err
}
return nil
}
================================================
FILE: pkg/golinters/noinlineerr/testdata/noinlineerr.go
================================================
//golangcitest:args -Enoinlineerr
package testdata
import (
"fmt"
"strconv"
)
type MyAliasErr error
type MyCustomError struct {}
func (mc *MyCustomError) Error() string {
return "error"
}
func doSomething() error {
return nil
}
func doSmthManyArgs(a, b, c, d int) error {
return nil
}
func doSmthMultipleReturn() (bool, error) {
return false, nil
}
func doMyAliasErr() MyAliasErr {
return nil
}
func doMyCustomErr() *MyCustomError {
return &MyCustomError{}
}
func valid() error {
err := doSomething() // ok
if err != nil {
return err
}
err = doSmthManyArgs(0, 0, 0, 0) // ok
if err != nil {
return err
}
_, err = doSmthMultipleReturn() // ok
if err != nil {
return err
}
if ok, _ := strconv.ParseBool("1"); ok {
fmt.Println("ok")
}
return nil
}
func invalid() error {
if err := doSomething(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`"
return err
}
if err := doSmthManyArgs(0, // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`"
0,
0,
0,
); err != nil {
return err
}
if _, err := doSmthMultipleReturn(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`"
_ = false
return err
}
if err := doMyAliasErr(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`"
return err
}
if err := doMyCustomErr(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`"
return err
}
return nil
}
================================================
FILE: pkg/golinters/nolintlint/internal/README.md
================================================
# nolintlint
nolintlint is a Go static analysis tool to find ill-formed or insufficiently explained `//nolint` directives for golangci-lint
(or any other linter, using this package)
## Purpose
To ensure that lint exceptions have explanations. Consider the case below:
```Go
import "crypto/md5" //nolint:all
func hash(data []byte) []byte {
return md5.New().Sum(data) //nolint:all
}
```
In the above case, nolint directives are present, but the user has no idea why this is being done or which linter
is being suppressed (in this case, gosec recommends against use of md5). `nolintlint` can require that the code provide an explanation, which might look as follows:
```Go
import "crypto/md5" //nolint:gosec // this is not used in a secure application
func hash(data []byte) []byte {
return md5.New().Sum(data) //nolint:gosec // this result is not used in a secure application
}
```
`nolintlint` can also identify cases where you may have written `// nolint`. Finally, `nolintlint`, can also enforce that you
use the machine-readable nolint directive format `//nolint:all` and that you mention what linter is being suppressed, as shown above when we write `//nolint:gosec`.
================================================
FILE: pkg/golinters/nolintlint/internal/issues.go
================================================
package internal
import (
"fmt"
"strings"
"unicode"
)
func formatExtraLeadingSpace(fullDirective string) string {
return fmt.Sprintf("directive `%s` should not have more than one leading space", fullDirective)
}
func formatNotMachine(fullDirective string) string {
expected := fullDirective[:2] + strings.TrimLeftFunc(fullDirective[2:], unicode.IsSpace)
return fmt.Sprintf("directive `%s` should be written without leading space as `%s`",
fullDirective, expected)
}
func formatNotSpecific(fullDirective, directiveWithOptionalLeadingSpace string) string {
return fmt.Sprintf("directive `%s` should mention specific linter such as `%s:my-linter`",
fullDirective, directiveWithOptionalLeadingSpace)
}
func formatParseError(fullDirective, directiveWithOptionalLeadingSpace string) string {
return fmt.Sprintf("directive `%s` should match `%s[:] [// ]`",
fullDirective,
directiveWithOptionalLeadingSpace)
}
func formatNoExplanation(fullDirective, fullDirectiveWithoutExplanation string) string {
return fmt.Sprintf("directive `%s` should provide explanation such as `%s // this is why`",
fullDirective, fullDirectiveWithoutExplanation)
}
func formatUnusedCandidate(fullDirective, expectedLinter string) string {
details := fmt.Sprintf("directive `%s` is unused", fullDirective)
if expectedLinter != "" {
details += fmt.Sprintf(" for linter %q", expectedLinter)
}
return details
}
================================================
FILE: pkg/golinters/nolintlint/internal/nolintlint.go
================================================
// Package internal provides a linter to ensure that all //nolint directives are followed by explanations
package internal
import (
"go/token"
"regexp"
"strings"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
const LinterName = "nolintlint"
const (
NeedsMachineOnly Needs = 1 << iota
NeedsSpecific
NeedsExplanation
NeedsUnused
NeedsAll = NeedsMachineOnly | NeedsSpecific | NeedsExplanation
)
type Needs uint
const commentMark = "//"
var commentPattern = regexp.MustCompile(`^//\s*(nolint)(:\s*[\w-]+\s*(?:,\s*[\w-]+\s*)*)?\b`)
// matches a complete nolint directive
var fullDirectivePattern = regexp.MustCompile(`^//\s*nolint(?::(\s*[\w-]+\s*(?:,\s*[\w-]+\s*)*))?\s*(//.*)?\s*\n?$`)
type Linter struct {
needs Needs // indicates which linter checks to perform
excludeByLinter map[string]bool
}
// NewLinter creates a linter that enforces that the provided directives fulfill the provided requirements
func NewLinter(needs Needs, excludes []string) (*Linter, error) {
excludeByName := make(map[string]bool)
for _, e := range excludes {
excludeByName[e] = true
}
return &Linter{
needs: needs | NeedsMachineOnly,
excludeByLinter: excludeByName,
}, nil
}
var (
leadingSpacePattern = regexp.MustCompile(`^//(\s*)`)
trailingBlankExplanation = regexp.MustCompile(`\s*(//\s*)?$`)
)
//nolint:funlen,gocyclo // the function is going to be refactored in the future
func (l Linter) Run(pass *analysis.Pass) ([]*goanalysis.Issue, error) {
var issues []*goanalysis.Issue
for _, file := range pass.Files {
for _, c := range file.Comments {
for _, comment := range c.List {
if !commentPattern.MatchString(comment.Text) {
continue
}
// check for a space between the "//" and the directive
leadingSpaceMatches := leadingSpacePattern.FindStringSubmatch(comment.Text)
var leadingSpace string
if len(leadingSpaceMatches) > 0 {
leadingSpace = leadingSpaceMatches[1]
}
directiveWithOptionalLeadingSpace := commentMark
if leadingSpace != "" {
directiveWithOptionalLeadingSpace += " "
}
split := strings.Split(strings.SplitN(comment.Text, ":", 2)[0], commentMark)
directiveWithOptionalLeadingSpace += strings.TrimSpace(split[1])
pos := pass.Fset.Position(comment.Pos())
end := pass.Fset.Position(comment.End())
// check for, report and eliminate leading spaces, so we can check for other issues
if leadingSpace != "" {
removeWhitespace := []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: token.Pos(pos.Offset),
End: token.Pos(pos.Offset + len(commentMark) + len(leadingSpace)),
NewText: []byte(commentMark),
}},
}}
if (l.needs & NeedsMachineOnly) != 0 {
issue := &result.Issue{
FromLinter: LinterName,
Text: formatNotMachine(comment.Text),
Pos: pos,
SuggestedFixes: removeWhitespace,
}
issues = append(issues, goanalysis.NewIssue(issue, pass))
} else if len(leadingSpace) > 1 {
issue := &result.Issue{
FromLinter: LinterName,
Text: formatExtraLeadingSpace(comment.Text),
Pos: pos,
SuggestedFixes: removeWhitespace,
}
issues = append(issues, goanalysis.NewIssue(issue, pass))
}
}
fullMatches := fullDirectivePattern.FindStringSubmatch(comment.Text)
if len(fullMatches) == 0 {
issue := &result.Issue{
FromLinter: LinterName,
Text: formatParseError(comment.Text, directiveWithOptionalLeadingSpace),
Pos: pos,
}
issues = append(issues, goanalysis.NewIssue(issue, pass))
continue
}
lintersText, explanation := fullMatches[1], fullMatches[2]
var linters []string
if lintersText != "" && !strings.HasPrefix(lintersText, "all") {
lls := strings.Split(lintersText, ",")
linters = make([]string, 0, len(lls))
rangeStart := (pos.Column - 1) + len(commentMark) + len(leadingSpace) + len("nolint:")
for i, ll := range lls {
rangeEnd := rangeStart + len(ll)
if i < len(lls)-1 {
rangeEnd++ // include trailing comma
}
trimmedLinterName := strings.TrimSpace(ll)
if trimmedLinterName != "" {
linters = append(linters, trimmedLinterName)
}
rangeStart = rangeEnd
}
}
if (l.needs & NeedsSpecific) != 0 {
if len(linters) == 0 {
issue := &result.Issue{
FromLinter: LinterName,
Text: formatNotSpecific(comment.Text, directiveWithOptionalLeadingSpace),
Pos: pos,
}
issues = append(issues, goanalysis.NewIssue(issue, pass))
}
}
// when detecting unused directives, we send all the directives through and filter them out in the nolint processor
if (l.needs & NeedsUnused) != 0 {
removeNolintCompletely := []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: token.Pos(pos.Offset),
End: token.Pos(end.Offset),
NewText: nil,
}},
}}
if len(linters) == 0 {
issue := &result.Issue{
FromLinter: LinterName,
Text: formatUnusedCandidate(comment.Text, ""),
Pos: pos,
ExpectNoLint: true,
SuggestedFixes: removeNolintCompletely,
}
issues = append(issues, goanalysis.NewIssue(issue, pass))
} else {
for _, linter := range linters {
issue := &result.Issue{
FromLinter: LinterName,
Text: formatUnusedCandidate(comment.Text, linter),
Pos: pos,
ExpectNoLint: true,
ExpectedNoLintLinter: linter,
}
// only offer SuggestedFix if there is a single linter
// because of issues around commas and the possibility of all
// linters being removed
if len(linters) == 1 {
issue.SuggestedFixes = removeNolintCompletely
}
issues = append(issues, goanalysis.NewIssue(issue, pass))
}
}
}
if (l.needs&NeedsExplanation) != 0 && (explanation == "" || strings.TrimSpace(explanation) == commentMark) {
needsExplanation := len(linters) == 0 // if no linters are mentioned, we must have explanation
// otherwise, check if we are excluding all the mentioned linters
for _, ll := range linters {
if !l.excludeByLinter[ll] { // if a linter does require explanation
needsExplanation = true
break
}
}
if needsExplanation {
fullDirectiveWithoutExplanation := trailingBlankExplanation.ReplaceAllString(comment.Text, "")
issue := &result.Issue{
FromLinter: LinterName,
Text: formatNoExplanation(comment.Text, fullDirectiveWithoutExplanation),
Pos: pos,
}
issues = append(issues, goanalysis.NewIssue(issue, pass))
}
}
}
}
}
return issues, nil
}
================================================
FILE: pkg/golinters/nolintlint/internal/nolintlint_test.go
================================================
package internal
import (
"go/ast"
"go/parser"
"go/token"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/v2/pkg/result"
)
func TestLinter_Run(t *testing.T) {
testCases := []struct {
desc string
needs Needs
excludes []string
contents string
expected []*result.Issue
}{
{
desc: "when no explanation is provided",
needs: NeedsExplanation,
contents: `package bar
// example
//nolint
func foo() {
bad() //nolint
bad() //nolint //
bad() //nolint //
good() //nolint // this is ok
other() //nolintother
}
`,
expected: []*result.Issue{
{
FromLinter: "nolintlint",
Text: "directive `//nolint` should provide explanation such as `//nolint // this is why`",
Pos: token.Position{Filename: "testing.go", Offset: 24, Line: 4, Column: 1},
},
{
FromLinter: "nolintlint",
Text: "directive `//nolint` should provide explanation such as `//nolint // this is why`",
Pos: token.Position{Filename: "testing.go", Offset: 54, Line: 6, Column: 9},
},
{
FromLinter: "nolintlint",
Text: "directive `//nolint //` should provide explanation such as `//nolint // this is why`",
Pos: token.Position{Filename: "testing.go", Offset: 71, Line: 7, Column: 9},
},
{
FromLinter: "nolintlint",
Text: "directive `//nolint // ` should provide explanation such as `//nolint // this is why`",
Pos: token.Position{Filename: "testing.go", Offset: 91, Line: 8, Column: 9},
},
},
},
{
desc: "when multiple directives on multiple lines",
needs: NeedsExplanation,
contents: `package bar
// example
//nolint // this is ok
//nolint:dupl
func foo() {}
`,
expected: []*result.Issue{{
FromLinter: "nolintlint",
Text: "directive `//nolint:dupl` should provide explanation such as `//nolint:dupl // this is why`",
Pos: token.Position{Filename: "testing.go", Offset: 47, Line: 5, Column: 1},
}},
},
{
desc: "when no explanation is needed for a specific linter",
needs: NeedsExplanation,
excludes: []string{"lll"},
contents: `package bar
func foo() {
thisIsAReallyLongLine() //nolint:lll
}
`,
},
{
desc: "when no specific linter is mentioned",
needs: NeedsSpecific,
contents: `package bar
func foo() {
good() //nolint:my-linter
bad() //nolint
bad() //nolint // because
}
`,
expected: []*result.Issue{
{
FromLinter: "nolintlint",
Text: "directive `//nolint` should mention specific linter such as `//nolint:my-linter`",
Pos: token.Position{Filename: "testing.go", Offset: 62, Line: 5, Column: 9},
},
{
FromLinter: "nolintlint",
Text: "directive `//nolint // because` should mention specific linter such as `//nolint:my-linter`",
Pos: token.Position{Filename: "testing.go", Offset: 79, Line: 6, Column: 9},
},
},
},
{
desc: "when machine-readable style isn't used",
contents: `package bar
func foo() {
bad() // nolint
bad() // nolint
good() //nolint
}
`,
expected: []*result.Issue{
{
FromLinter: "nolintlint",
Text: "directive `// nolint` should be written without leading space as `//nolint`",
Pos: token.Position{Filename: "testing.go", Offset: 34, Line: 4, Column: 9},
SuggestedFixes: []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: 34,
End: 37,
NewText: []byte(commentMark),
}},
}},
},
{
FromLinter: "nolintlint",
Text: "directive `// nolint` should be written without leading space as `//nolint`",
Pos: token.Position{Filename: "testing.go", Offset: 52, Line: 5, Column: 9},
SuggestedFixes: []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
Pos: 52,
End: 57,
NewText: []byte(commentMark),
}},
}},
},
},
},
{
desc: "spaces are allowed in comma-separated list of linters",
contents: `package bar
func foo() {
good() //nolint:linter1,linter-two
bad() //nolint:linter1 linter2
good() //nolint: linter1,linter2
good() //nolint: linter1, linter2
}
`,
expected: []*result.Issue{{
FromLinter: "nolintlint",
Text: "directive `//nolint:linter1 linter2` should match `//nolint[:] [//