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(`%[1]s`, author), + Profile: fmt.Sprintf("[%[1]s](https://github.com/sponsors/%[1]s)", info.Author), + Avatar: fmt.Sprintf(`%[1]s`, 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) + }) + } +}