misspell: add mode option (#4275)

This commit is contained in:
Ludovic Fernandez 2023-12-22 16:09:23 +01:00 committed by GitHub
parent 95bc7a8546
commit d99c02cde0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 12 deletions

View File

@ -1333,6 +1333,11 @@ linters-settings:
# Default: [] # Default: []
ignore-words: ignore-words:
- someword - someword
# Mode of the analysis:
# - default: checks all the file content.
# - restricted: checks only comments.
# Default: ""
mode: restricted
musttag: musttag:
# A set of custom functions to check in addition to the builtin ones. # A set of custom functions to check in addition to the builtin ones.

View File

@ -659,8 +659,9 @@ type MalignedSettings struct {
} }
type MisspellSettings struct { type MisspellSettings struct {
Mode string `mapstructure:"mode"`
Locale string Locale string
// TODO(ldez): v2 the options must be renamed to `IgnoredRules`. // TODO(ldez): v2 the option must be renamed to `IgnoredRules`.
IgnoreWords []string `mapstructure:"ignore-words"` IgnoreWords []string `mapstructure:"ignore-words"`
} }

View File

@ -29,7 +29,7 @@ func NewMisspell(settings *config.MisspellSettings) *goanalysis.Linter {
return goanalysis.NewLinter( return goanalysis.NewLinter(
misspellName, misspellName,
"Finds commonly misspelled English words in comments", "Finds commonly misspelled English words",
[]*analysis.Analyzer{analyzer}, []*analysis.Analyzer{analyzer},
nil, nil,
).WithContextSetter(func(lintCtx *linter.Context) { ).WithContextSetter(func(lintCtx *linter.Context) {
@ -40,7 +40,7 @@ func NewMisspell(settings *config.MisspellSettings) *goanalysis.Linter {
return nil, ruleErr return nil, ruleErr
} }
issues, err := runMisspell(lintCtx, pass, replacer) issues, err := runMisspell(lintCtx, pass, replacer, settings.Mode)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -60,15 +60,16 @@ func NewMisspell(settings *config.MisspellSettings) *goanalysis.Linter {
}).WithLoadMode(goanalysis.LoadModeSyntax) }).WithLoadMode(goanalysis.LoadModeSyntax)
} }
func runMisspell(lintCtx *linter.Context, pass *analysis.Pass, replacer *misspell.Replacer) ([]goanalysis.Issue, error) { func runMisspell(lintCtx *linter.Context, pass *analysis.Pass, replacer *misspell.Replacer, mode string) ([]goanalysis.Issue, error) {
fileNames := getFileNames(pass) fileNames := getFileNames(pass)
var issues []goanalysis.Issue var issues []goanalysis.Issue
for _, filename := range fileNames { for _, filename := range fileNames {
lintIssues, err := runMisspellOnFile(lintCtx, filename, replacer) lintIssues, err := runMisspellOnFile(lintCtx, filename, replacer, mode)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for i := range lintIssues { for i := range lintIssues {
issues = append(issues, goanalysis.NewIssue(&lintIssues[i], pass)) issues = append(issues, goanalysis.NewIssue(&lintIssues[i], pass))
} }
@ -104,25 +105,36 @@ func createMisspellReplacer(settings *config.MisspellSettings) (*misspell.Replac
return replacer, nil return replacer, nil
} }
func runMisspellOnFile(lintCtx *linter.Context, filename string, replacer *misspell.Replacer) ([]result.Issue, error) { func runMisspellOnFile(lintCtx *linter.Context, filename string, replacer *misspell.Replacer, mode string) ([]result.Issue, error) {
var res []result.Issue
fileContent, err := lintCtx.FileCache.GetFileBytes(filename) fileContent, err := lintCtx.FileCache.GetFileBytes(filename)
if err != nil { if err != nil {
return nil, fmt.Errorf("can't get file %s contents: %s", filename, err) return nil, fmt.Errorf("can't get file %s contents: %s", filename, err)
} }
// use r.Replace, not r.ReplaceGo because r.ReplaceGo doesn't find // `r.ReplaceGo` doesn't find issues inside strings: it searches only inside comments.
// issues inside strings: it searches only inside comments. r.Replace // `r.Replace` searches all words: it treats input as a plain text.
// searches all words: it treats input as a plain text. A standalone misspell // The standalone misspell tool uses `r.Replace` by default.
// tool uses r.Replace by default. var replace func(input string) (string, []misspell.Diff)
_, diffs := replacer.Replace(string(fileContent)) switch strings.ToLower(mode) {
case "restricted":
replace = replacer.ReplaceGo
default:
replace = replacer.Replace
}
_, diffs := replace(string(fileContent))
var res []result.Issue
for _, diff := range diffs { for _, diff := range diffs {
text := fmt.Sprintf("`%s` is a misspelling of `%s`", diff.Original, diff.Corrected) text := fmt.Sprintf("`%s` is a misspelling of `%s`", diff.Original, diff.Corrected)
pos := token.Position{ pos := token.Position{
Filename: filename, Filename: filename,
Line: diff.Line, Line: diff.Line,
Column: diff.Column + 1, Column: diff.Column + 1,
} }
replacement := &result.Replacement{ replacement := &result.Replacement{
Inline: &result.InlineFix{ Inline: &result.InlineFix{
StartCol: diff.Column, StartCol: diff.Column,