Skip to content

Commit 3e52be7

Browse files
Add swaggo/swag formatter (#5749)
Co-authored-by: Fernandez Ludovic <[email protected]>
1 parent 5a945fd commit 3e52be7

File tree

17 files changed

+148
-5
lines changed

17 files changed

+148
-5
lines changed

.github/dependabot.yml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ updates:
1010
# Ignore forked linters because of their versioning issues.
1111
- dependency-name: "github.com/golangci/dupl"
1212
- dependency-name: "github.com/golangci/gofmt"
13+
- dependency-name: "github.com/golangci/swaggoswag"
1314
- dependency-name: "github.com/golangci/unconvert"
1415
- package-ecosystem: github-actions
1516
directory: "/"

.golangci.next.reference.yml

+1
Original file line numberDiff line numberDiff line change
@@ -3975,6 +3975,7 @@ formatters:
39753975
- gofumpt
39763976
- goimports
39773977
- golines
3978+
- swaggo
39783979

39793980
# Formatters settings.
39803981
settings:

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ require (
5151
github.com/golangci/misspell v0.6.0
5252
github.com/golangci/plugin-module-register v0.1.1
5353
github.com/golangci/revgrep v0.8.0
54+
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e
5455
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e
5556
github.com/gordonklaus/ineffassign v0.1.0
5657
github.com/gostaticanalysis/forcetypeassert v0.2.0

go.sum

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jsonschema/golangci.next.jsonschema.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,8 @@
837837
"gofmt",
838838
"gofumpt",
839839
"goimports",
840-
"golines"
840+
"golines",
841+
"swaggo"
841842
]
842843
},
843844
"settings": {

pkg/config/linters.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@ func (l *Linters) validateNoFormatters() error {
4949
}
5050

5151
func getAllFormatterNames() []string {
52-
return []string{"gci", "gofmt", "gofumpt", "goimports", "golines"}
52+
return []string{"gci", "gofmt", "gofumpt", "goimports", "golines", "swaggo"}
5353
}

pkg/goformatters/meta_formatter.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
1313
"github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
1414
"github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
15+
"github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo"
1516
"github.com/golangci/golangci-lint/v2/pkg/logutils"
1617
)
1718

@@ -41,6 +42,10 @@ func NewMetaFormatter(log logutils.Log, cfg *config.Formatters, runCfg *config.R
4142
m.formatters = append(m.formatters, goimports.New(&cfg.Settings.GoImports))
4243
}
4344

45+
if slices.Contains(cfg.Enable, swaggo.Name) {
46+
m.formatters = append(m.formatters, swaggo.New())
47+
}
48+
4449
// gci is a last because the only goal of gci is to handle imports.
4550
if slices.Contains(cfg.Enable, gci.Name) {
4651
formatter, err := gci.New(&cfg.Settings.Gci)
@@ -86,5 +91,5 @@ func (m *MetaFormatter) Format(filename string, src []byte) []byte {
8691
}
8792

8893
func IsFormatter(name string) bool {
89-
return slices.Contains([]string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name}, name)
94+
return slices.Contains([]string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name, swaggo.Name}, name)
9095
}

pkg/goformatters/swaggo/swaggo.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package swaggo
2+
3+
import "github.com/golangci/swaggoswag"
4+
5+
const Name = "swaggo"
6+
7+
type Formatter struct {
8+
formatter *swaggoswag.Formatter
9+
}
10+
11+
func New() *Formatter {
12+
return &Formatter{
13+
formatter: swaggoswag.NewFormatter(),
14+
}
15+
}
16+
17+
func (*Formatter) Name() string {
18+
return Name
19+
}
20+
21+
func (f *Formatter) Format(path string, src []byte) ([]byte, error) {
22+
return f.formatter.Format(path, src)
23+
}

pkg/golinters/swaggo/swaggo.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package swaggo
2+
3+
import (
4+
"golang.org/x/tools/go/analysis"
5+
6+
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
7+
"github.com/golangci/golangci-lint/v2/pkg/goformatters"
8+
"github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo"
9+
"github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
10+
)
11+
12+
const linterName = "swaggo"
13+
14+
func New() *goanalysis.Linter {
15+
a := goformatters.NewAnalyzer(
16+
internal.LinterLogger.Child(linterName),
17+
"Check if swaggo comments are formatted",
18+
swaggo.New(),
19+
)
20+
21+
return goanalysis.NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil).
22+
WithLoadMode(goanalysis.LoadModeSyntax)
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package swaggo
2+
3+
import (
4+
"testing"
5+
6+
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
7+
)
8+
9+
func TestFromTestdata(t *testing.T) {
10+
integration.RunTestdata(t)
11+
}
12+
13+
func TestFix(t *testing.T) {
14+
integration.RunFix(t)
15+
}
16+
17+
func TestFixPathPrefix(t *testing.T) {
18+
integration.RunFixPathPrefix(t)
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//golangcitest:config_path testdata/swaggo.yml
2+
//golangcitest:expected_exitcode 0
3+
package api
4+
5+
import "net/http"
6+
7+
// @Summary Add a new pet to the store
8+
// @Description get string by ID
9+
// @ID get-string-by-int
10+
// @Accept json
11+
// @Produce json
12+
// @Param some_id path int true "Some ID" Format(int64)
13+
// @Param some_id body web.Pet true "Some ID"
14+
// @Success 200 {string} string "ok"
15+
// @Failure 400 {object} web.APIError "We need ID!!"
16+
// @Failure 404 {object} web.APIError "Can not find ID"
17+
// @Router /testapi/get-string-by-int/{some_id} [get]
18+
func GetStringByInt(w http.ResponseWriter, r *http.Request) {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//golangcitest:config_path testdata/swaggo.yml
2+
//golangcitest:expected_exitcode 0
3+
package api
4+
5+
import "net/http"
6+
7+
// @Summary Add a new pet to the store
8+
// @Description get string by ID
9+
// @ID get-string-by-int
10+
// @Accept json
11+
// @Produce json
12+
// @Param some_id path int true "Some ID" Format(int64)
13+
// @Param some_id body web.Pet true "Some ID"
14+
// @Success 200 {string} string "ok"
15+
// @Failure 400 {object} web.APIError "We need ID!!"
16+
// @Failure 404 {object} web.APIError "Can not find ID"
17+
// @Router /testapi/get-string-by-int/{some_id} [get]
18+
func GetStringByInt(w http.ResponseWriter, r *http.Request) {}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//golangcitest:config_path testdata/swaggo.yml
2+
package api
3+
4+
import "net/http"
5+
6+
// want +1 "File is not properly formatted"
7+
// @Summary Add a new pet to the store
8+
// @Description get string by ID
9+
// @ID get-string-by-int
10+
// @Accept json
11+
// @Produce json
12+
// @Param some_id path int true "Some ID" Format(int64)
13+
// @Param some_id body web.Pet true "Some ID"
14+
// @Success 200 {string} string "ok"
15+
// @Failure 400 {object} web.APIError "We need ID!!"
16+
// @Failure 404 {object} web.APIError "Can not find ID"
17+
// @Router /testapi/get-string-by-int/{some_id} [get]
18+
func GetStringByInt(w http.ResponseWriter, r *http.Request) {}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
version: "2"
2+
3+
formatters:
4+
enable:
5+
- swaggo

pkg/lint/lintersdb/builder_linter.go

+6
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import (
9494
"github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck"
9595
"github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck"
9696
"github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck"
97+
"github.com/golangci/golangci-lint/v2/pkg/golinters/swaggo"
9798
"github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign"
9899
"github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle"
99100
"github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples"
@@ -581,6 +582,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
581582
WithAutoFix().
582583
WithURL("https://staticcheck.dev/"),
583584

585+
linter.NewConfig(swaggo.New()).
586+
WithSince("v2.2.0").
587+
WithAutoFix().
588+
WithURL("https://github.com/swaggo/swaggo"),
589+
584590
linter.NewConfig(tagalign.New(&cfg.Linters.Settings.TagAlign)).
585591
WithSince("v1.53.0").
586592
WithAutoFix().

pkg/result/processors/fixer.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
2323
"github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
2424
"github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
25+
"github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo"
2526
"github.com/golangci/golangci-lint/v2/pkg/logutils"
2627
"github.com/golangci/golangci-lint/v2/pkg/result"
2728
"github.com/golangci/golangci-lint/v2/pkg/timeutils"
@@ -79,7 +80,7 @@ func (p Fixer) process(issues []result.Issue) ([]result.Issue, error) {
7980
// filenames / linters / edits
8081
editsByLinter := make(map[string]map[string][]diff.Edit)
8182

82-
formatters := []string{gofumpt.Name, goimports.Name, gofmt.Name, gci.Name, golines.Name}
83+
formatters := []string{gofumpt.Name, goimports.Name, gofmt.Name, gci.Name, golines.Name, swaggo.Name}
8384

8485
var notFixableIssues []result.Issue
8586

pkg/result/processors/max_per_file_from_linter.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
88
"github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
99
"github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
10+
"github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo"
1011
"github.com/golangci/golangci-lint/v2/pkg/result"
1112
)
1213

@@ -24,7 +25,7 @@ func NewMaxPerFileFromLinter(cfg *config.Config) *MaxPerFileFromLinter {
2425
if !cfg.Issues.NeedFix {
2526
// if we don't fix we do this limiting to not annoy user;
2627
// otherwise we need to fix all issues in the file at once
27-
for _, f := range []string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name} {
28+
for _, f := range []string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name, swaggo.Name} {
2829
maxPerFileFromLinterConfig[f] = 1
2930
}
3031
}

0 commit comments

Comments
 (0)