misspell: add extra-words (#4401)

This commit is contained in:
Ludovic Fernandez 2024-02-20 12:59:49 +01:00 committed by GitHub
parent 64492b5e59
commit e6720b809f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 163 additions and 2 deletions

View File

@ -1361,9 +1361,20 @@ linters-settings:
# 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-words:
- 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.

View File

@ -663,12 +663,18 @@ type MalignedSettings struct {
}
type MisspellSettings struct {
Mode string `mapstructure:"mode"`
Locale string
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"`

View File

@ -5,6 +5,7 @@ import (
"go/token"
"strings"
"sync"
"unicode"
"github.com/golangci/misspell"
"golang.org/x/tools/go/analysis"
@ -95,6 +96,11 @@ func createMisspellReplacer(settings *config.MisspellSettings) (*misspell.Replac
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.IgnoreWords) != 0 {
replacer.RemoveRule(settings.IgnoreWords)
}
@ -153,3 +159,30 @@ func runMisspellOnFile(lintCtx *linter.Context, filename string, replacer *missp
return res, 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
}

View File

@ -0,0 +1,94 @@
package golinters
import (
"testing"
"github.com/golangci/misspell"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/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, replacer.Replacements, expected)
}
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 {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
replacer := &misspell.Replacer{}
err := appendExtraWords(replacer, test.extraWords)
require.EqualError(t, err, test.expected)
})
}
}

View File

@ -0,0 +1,7 @@
linters-settings:
misspell:
extra-words:
- typo: "iff"
correction: "if"
- typo: "cancelation"
correction: "cancellation"

10
test/testdata/misspell_custom.go vendored Normal file
View File

@ -0,0 +1,10 @@
//golangcitest:args -Emisspell
//golangcitest:config_path testdata/configs/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\\`"