diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go
index 6c533d2e4878..7e8e4ad1ba51 100644
--- a/pkg/lint/lintersdb/builder_linter.go
+++ b/pkg/lint/lintersdb/builder_linter.go
@@ -450,7 +450,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
linter.NewConfig(misspell.New(&cfg.Linters.Settings.Misspell)).
WithSince("v1.8.0").
WithAutoFix().
- WithURL("https://github.com/client9/misspell"),
+ WithURL("https://github.com/golangci/misspell"),
linter.NewConfig(musttag.New(&cfg.Linters.Settings.MustTag)).
WithSince("v1.51.0").
diff --git a/scripts/website/expand_templates/thanks.go b/scripts/website/expand_templates/thanks.go
index c3b8c8daee72..66ee8511c6e8 100644
--- a/scripts/website/expand_templates/thanks.go
+++ b/scripts/website/expand_templates/thanks.go
@@ -3,6 +3,7 @@ package main
import (
"fmt"
"maps"
+ "regexp"
"slices"
"strings"
@@ -11,6 +12,11 @@ import (
"github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
)
+const (
+ hostGitHub = "github"
+ hostGitLab = "gitlab"
+)
+
type authorDetails struct {
Linters []string
Profile string
@@ -35,29 +41,29 @@ func getThanksList() string {
continue
}
- linterURL := extractLinterURL(lc)
+ info := extractInfo(lc)
- if author := extractAuthor(linterURL, "https://github.com/"); author != "" && author != "golangci" {
- if _, ok := addedAuthors[author]; ok {
- addedAuthors[author].Linters = append(addedAuthors[author].Linters, lc.Name())
+ switch {
+ case info.FromGitHub():
+ if _, ok := addedAuthors[info.Author]; ok {
+ addedAuthors[info.Author].Linters = append(addedAuthors[info.Author].Linters, lc.Name())
} else {
- addedAuthors[author] = &authorDetails{
+ addedAuthors[info.Author] = &authorDetails{
Linters: []string{lc.Name()},
- Profile: fmt.Sprintf("[%[1]s](https://github.com/sponsors/%[1]s)", author),
- Avatar: fmt.Sprintf(`
`, author),
+ Profile: fmt.Sprintf("[%[1]s](https://github.com/sponsors/%[1]s)", info.Author),
+ Avatar: fmt.Sprintf(`
`, info.Author),
}
}
- } else if author := extractAuthor(linterURL, "https://gitlab.com/"); author != "" {
- if _, ok := addedAuthors[author]; ok {
- addedAuthors[author].Linters = append(addedAuthors[author].Linters, lc.Name())
+
+ case info.FromGitLab():
+ if _, ok := addedAuthors[info.Author]; ok {
+ addedAuthors[info.Author].Linters = append(addedAuthors[info.Author].Linters, lc.Name())
} else {
- addedAuthors[author] = &authorDetails{
+ addedAuthors[info.Author] = &authorDetails{
Linters: []string{lc.Name()},
- Profile: fmt.Sprintf("[%[1]s](https://gitlab.com/%[1]s)", author),
+ Profile: fmt.Sprintf("[%[1]s](https://gitlab.com/%[1]s)", info.Author),
}
}
- } else {
- continue
}
}
@@ -78,31 +84,65 @@ func getThanksList() string {
return strings.Join(lines, "\n")
}
-func extractLinterURL(lc *linter.Config) string {
+type authorInfo struct {
+ Author string
+ Host string
+}
+
+func extractInfo(lc *linter.Config) authorInfo {
+ exp := regexp.MustCompile(`https://(github|gitlab)\.com/([^/]+)/.*`)
+
switch lc.Name() {
case "staticcheck":
- return "https://github.com/dominikh/go-tools"
+ return authorInfo{Author: "dominikh", Host: hostGitHub}
- case "depguard":
- return "https://github.com/dixonwille/depguard"
+ case "misspell":
+ return authorInfo{Author: "client9", Host: hostGitHub}
default:
- if strings.HasPrefix(lc.OriginalURL, "https://github.com/gostaticanalysis/") {
- return "https://github.com/tenntenn/gostaticanalysis"
+ if strings.HasPrefix(lc.OriginalURL, "https://pkg.go.dev/") {
+ return authorInfo{Author: "golang", Host: hostGitHub}
}
- if strings.HasPrefix(lc.OriginalURL, "https://github.com/go-simpler/") {
- return "https://github.com/tmzane/go-simpler"
+ if !exp.MatchString(lc.OriginalURL) {
+ return authorInfo{}
+ }
+
+ submatch := exp.FindAllStringSubmatch(lc.OriginalURL, -1)
+
+ info := authorInfo{
+ Author: submatch[0][2],
+ Host: submatch[0][1],
}
- return lc.OriginalURL
+ switch info.Author {
+ case "gostaticanalysis":
+ info.Author = "tenntenn"
+
+ case "go-simpler":
+ info.Author = "tmzane"
+
+ case "curioswitch":
+ info.Author = "chokoswitch"
+
+ case "GaijinEntertainment":
+ info.Author = "xobotyi"
+
+ case "OpenPeeDeeP":
+ info.Author = "dixonwille"
+
+ case "golangci":
+ return authorInfo{}
+ }
+
+ return info
}
}
-func extractAuthor(originalURL, prefix string) string {
- if !strings.HasPrefix(originalURL, prefix) {
- return ""
- }
+func (i authorInfo) FromGitHub() bool {
+ return i.Host == hostGitHub
+}
- return strings.SplitN(strings.TrimPrefix(originalURL, prefix), "/", 2)[0]
+func (i authorInfo) FromGitLab() bool {
+ return i.Host == hostGitLab
}
diff --git a/scripts/website/expand_templates/thanks_test.go b/scripts/website/expand_templates/thanks_test.go
new file mode 100644
index 000000000000..6af152336e99
--- /dev/null
+++ b/scripts/website/expand_templates/thanks_test.go
@@ -0,0 +1,142 @@
+package main
+
+import (
+ "context"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+)
+
+type FakeLinter struct {
+ name string
+}
+
+func (*FakeLinter) Run(_ context.Context, _ *linter.Context) ([]result.Issue, error) {
+ return nil, nil
+}
+
+func (f *FakeLinter) Name() string {
+ return f.name
+}
+
+func (*FakeLinter) Desc() string {
+ return "fake linter"
+}
+
+func Test_extractInfo(t *testing.T) {
+ testCases := []struct {
+ desc string
+ lc *linter.Config
+ expected authorInfo
+ }{
+ {
+ desc: "from GitHub",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://github.com/owner/linter",
+ },
+ expected: authorInfo{Author: "owner", Host: "github"},
+ },
+ {
+ desc: "from GitLab",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://gitlab.com/owner/linter",
+ },
+ expected: authorInfo{Author: "owner", Host: "gitlab"},
+ },
+ {
+ desc: "staticcheck",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "staticcheck"},
+ OriginalURL: "https://github.com/owner/linter",
+ },
+ expected: authorInfo{Author: "dominikh", Host: "github"},
+ },
+ {
+ desc: "gostaticanalysis",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://github.com/gostaticanalysis/linter",
+ },
+ expected: authorInfo{Author: "tenntenn", Host: "github"},
+ },
+ {
+ desc: "go-simpler",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://github.com/go-simpler/linter",
+ },
+ expected: authorInfo{Author: "tmzane", Host: "github"},
+ },
+ {
+ desc: "curioswitch",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://github.com/curioswitch/linter",
+ },
+ expected: authorInfo{Author: "chokoswitch", Host: "github"},
+ },
+ {
+ desc: "GaijinEntertainment",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://github.com/GaijinEntertainment/linter",
+ },
+ expected: authorInfo{Author: "xobotyi", Host: "github"},
+ },
+ {
+ desc: "OpenPeeDeeP",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://github.com/OpenPeeDeeP/linter",
+ },
+ expected: authorInfo{Author: "dixonwille", Host: "github"},
+ },
+ {
+ desc: "misspell",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "misspell"},
+ OriginalURL: "https://github.com/myorg/linter",
+ },
+ expected: authorInfo{Author: "client9", Host: "github"},
+ },
+ {
+ desc: "pkg.go.dev",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://pkg.go.dev/linter",
+ },
+ expected: authorInfo{Author: "golang", Host: "github"},
+ },
+ {
+ desc: "golangci",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://github.com/golangci/linter",
+ },
+ expected: authorInfo{},
+ },
+ {
+ desc: "invalid",
+ lc: &linter.Config{
+ Linter: &FakeLinter{name: "fake"},
+ OriginalURL: "https://example.com/linter",
+ },
+ expected: authorInfo{},
+ },
+ }
+
+ for _, test := range testCases {
+ t.Run(test.desc, func(t *testing.T) {
+ t.Parallel()
+
+ info := extractInfo(test.lc)
+
+ assert.Equal(t, test.expected, info)
+ })
+ }
+}