diff --git a/README.md b/README.md index ae67a4c00cb2..af3d6712f297 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,7 @@ godox: Tool for detection of FIXME, TODO and other comment keywords [fast: true, gofmt: Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true, auto-fix: true] goimports: Goimports does everything that gofmt does. Additionally it checks unused imports [fast: true, auto-fix: true] golint: Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: true, auto-fix: false] +gomnd: checks whether magic number is used [fast: true, auto-fix: false] gosec (gas): Inspects source code for security problems [fast: true, auto-fix: false] interfacer: Linter that suggests narrower interface types [fast: true, auto-fix: false] lll: Reports long lines [fast: true, auto-fix: false] @@ -480,6 +481,7 @@ golangci-lint help linters - [funlen](https://github.com/ultraware/funlen) - Tool for detection of long functions - [whitespace](https://github.com/ultraware/whitespace) - Tool for detection of leading and trailing whitespace - [wsl](https://github.com/bombsimon/wsl) - Whitespace Linter - Forces you to use empty lines! +- [gomnd](https://github.com/tommy-muehle/go-mnd) - checks whether magic number is used ## Configuration @@ -1165,6 +1167,7 @@ Thanks to developers and authors of used linters: - [matoous](https://github.com/matoous) - [ultraware](https://github.com/ultraware) - [bombsimon](https://github.com/bombsimon) +- [tommy-muehle](https://github.com/tommy-muehle) ## Changelog diff --git a/go.mod b/go.mod index 180b09af9534..ea08ac608435 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.4.0 github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e + github.com/tommy-muehle/go-mnd v0.0.0-20190903201840-c93e405da530 github.com/ultraware/funlen v0.0.2 github.com/ultraware/whitespace v0.0.4 github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517 diff --git a/go.sum b/go.sum index aa0a9f87b7a8..731bf59d4190 100644 --- a/go.sum +++ b/go.sum @@ -232,6 +232,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tommy-muehle/go-mnd v0.0.0-20190903201840-c93e405da530 h1:uUctDnVK0uevT4yglJXAXDG74EkQvGdu6L1pSoZx+T4= +github.com/tommy-muehle/go-mnd v0.0.0-20190903201840-c93e405da530/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo= diff --git a/pkg/golinters/gomnd.go b/pkg/golinters/gomnd.go new file mode 100644 index 000000000000..6aa277539255 --- /dev/null +++ b/pkg/golinters/gomnd.go @@ -0,0 +1,21 @@ +package golinters + +import ( + magic_numbers "github.com/tommy-muehle/go-mnd" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +func NewGomnd() *goanalysis.Linter { + analyzers := []*analysis.Analyzer{ + magic_numbers.Analyzer, + } + + return goanalysis.NewLinter( + "gomnd", + "checks whether magic number is used", + analyzers, + nil, + ).WithLoadMode(goanalysis.LoadModeSyntax) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index f2cd2bd57ce0..b0aab4c6d3ab 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -208,6 +208,9 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { linter.NewConfig(golinters.NewWSL()). WithPresets(linter.PresetStyle). WithURL("https://github.com/bombsimon/wsl"), + linter.NewConfig(golinters.NewGomnd()). + WithPresets(linter.PresetStyle). + WithURL("https://github.com/tommy-muehle/go-mnd"), } isLocalRun := os.Getenv("GOLANGCI_COM_RUN") == "" diff --git a/test/testdata/gomnd.go b/test/testdata/gomnd.go new file mode 100644 index 000000000000..298b9bded10d --- /dev/null +++ b/test/testdata/gomnd.go @@ -0,0 +1,36 @@ +//args: -Egomnd +package testdata + +import ( + "log" + "net/http" + "time" +) + +func UseMagicNumber() { + c := &http.Client{ + Timeout: 1 * time.Second, // ERROR : "Magic number: 1, in detected" + } + + res, err := c.Get("http://www.google.com") + if err != nil { + log.Fatal(err) + } + if res.StatusCode != 200 { // ERROR : "Magic number: 200, in detected" + log.Println("Something went wrong") + } +} + +func UseNoMagicNumber() { + c := &http.Client{ + Timeout: time.Second, + } + + res, err := c.Get("http://www.google.com") + if err != nil { + log.Fatal(err) + } + if res.StatusCode != http.StatusOK { + log.Println("Something went wrong") + } +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/.editorconfig b/vendor/github.com/tommy-muehle/go-mnd/.editorconfig new file mode 100644 index 000000000000..316b8cae02e2 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/vendor/github.com/tommy-muehle/go-mnd/.gitignore b/vendor/github.com/tommy-muehle/go-mnd/.gitignore new file mode 100644 index 000000000000..edd9d60a7a9a --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/.gitignore @@ -0,0 +1,2 @@ +build/ +dist/ diff --git a/vendor/github.com/tommy-muehle/go-mnd/.goreleaser.yml b/vendor/github.com/tommy-muehle/go-mnd/.goreleaser.yml new file mode 100644 index 000000000000..8185cf48e67d --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/.goreleaser.yml @@ -0,0 +1,28 @@ +builds: + - + main: ./cmd/mnd/main.go + binary: mnd + goos: + - windows + - darwin + - linux + goarch: + - amd64 + ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.buildTime={{.Date}}`. + +archive: + format: tar.gz + format_overrides: + - goos: windows + format: zip + +brew: + name: mnd + github: + owner: tommy-muehle + name: homebrew-tap + folder: Formula + homepage: https://github.com/tommy-muehle/go-mnd + description: Magic number detector for Go + test: | + system "#{bin}/mnd --version" diff --git a/vendor/github.com/tommy-muehle/go-mnd/.travis.yml b/vendor/github.com/tommy-muehle/go-mnd/.travis.yml new file mode 100644 index 000000000000..1f9e88e2203f --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/.travis.yml @@ -0,0 +1,8 @@ +language: go + +go: + - 1.12.x + - tip + +script: + - go test -v ./... diff --git a/vendor/github.com/tommy-muehle/go-mnd/LICENSE b/vendor/github.com/tommy-muehle/go-mnd/LICENSE new file mode 100644 index 000000000000..8825fad20c90 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019 Tommy Muehle + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/tommy-muehle/go-mnd/README.md b/vendor/github.com/tommy-muehle/go-mnd/README.md new file mode 100644 index 000000000000..3d6f32afa95b --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/README.md @@ -0,0 +1,97 @@ +# go-mnd - Magic number detector for Golang + +A vet analyzer to detect magic numbers. + +> **What is a magic number?** +> A magic number is a numeric literal that is not defined as a constant, but which may change, and therefore can be hard to update. It's considered a bad programming practice to use numbers directly in any source code without an explanation. It makes programs harder to read, understand, and maintain. + +## Project status + +[![Build Status](https://travis-ci.org/tommy-muehle/go-mnd.svg?branch=master)](https://travis-ci.org/tommy-muehle/go-mnd) +[![Go Report Card](https://goreportcard.com/badge/github.com/tommy-muehle/go-mnd)](https://goreportcard.com/report/github.com/tommy-muehle/go-mnd) + +## Install + +This analyzer requires Golang in version >= 1.12 because it's depends on the **go/analysis** API. + +``` +go get github.com/tommy-muehle/go-mnd/cmd/mnd +``` + +To install with [Homebrew](https://brew.sh/), run: + +``` +brew tap tommy-muehle/tap && brew install tommy-muehle/tap/mnd +``` + +On Windows download the [latest release](https://github.com/tommy-muehle/go-mnd/releases). + +## Usage + +[![asciicast](https://asciinema.org/a/231021.svg)](https://asciinema.org/a/231021) + +``` +go vet -vettool $(which mnd) ./... +``` + +or directly + +``` +mnd ./... +``` + +The ```-checks``` option let's you define a comma separated list of checks. + +## Checks + +By default this detector analyses arguments, assigns, cases, conditions, operations and return statements. + +* argument + +``` +t := http.StatusText(200) +``` + +* assign + +``` +c := &http.Client{ + Timeout: 5 * time.Second, +} +``` + +* case + +``` +switch x { + case 3: +} +``` + +* condition + +``` +if x > 7 { +} +``` + +* operation + +``` +var x, y int +y = 10 * x +``` + +* return + +``` +return 3 +``` + +## Notices + +By default the number 0 is excluded! + +## License + +The MIT License (MIT). Please see [LICENSE](LICENSE) for more information. diff --git a/vendor/github.com/tommy-muehle/go-mnd/analyzer.go b/vendor/github.com/tommy-muehle/go-mnd/analyzer.go new file mode 100644 index 000000000000..4acc42960e44 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/analyzer.go @@ -0,0 +1,71 @@ +package magic_numbers + +import ( + "flag" + "go/ast" + + "github.com/tommy-muehle/go-mnd/checks" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/ast/inspector" +) + +const Doc = `magic number detector` + +var Analyzer = &analysis.Analyzer{ + Name: "mnd", + Doc: Doc, + Run: run, + Flags: options(), + Requires: []*analysis.Analyzer{inspect.Analyzer}, + RunDespiteErrors: true, +} + +type Checker interface { + NodeFilter() []ast.Node + Check(n ast.Node) +} + +func options() flag.FlagSet { + options := flag.NewFlagSet("", flag.ExitOnError) + options.String("checks", "", "comma separated list of checks") + + return *options +} + +func run(pass *analysis.Pass) (interface{}, error) { + config := WithOptions( + WithCustomChecks(pass.Analyzer.Flags.Lookup("checks").Value.String()), + ) + + var checker []Checker + if config.IsCheckEnabled(checks.ArgumentCheck) { + checker = append(checker, checks.NewArgumentAnalyzer(pass)) + } + if config.IsCheckEnabled(checks.CaseCheck) { + checker = append(checker, checks.NewCaseAnalyzer(pass)) + } + if config.IsCheckEnabled(checks.ConditionCheck) { + checker = append(checker, checks.NewConditionAnalyzer(pass)) + } + if config.IsCheckEnabled(checks.OperationCheck) { + checker = append(checker, checks.NewOperationAnalyzer(pass)) + } + if config.IsCheckEnabled(checks.ReturnCheck) { + checker = append(checker, checks.NewReturnAnalyzer(pass)) + } + if config.IsCheckEnabled(checks.AssignCheck) { + checker = append(checker, checks.NewAssignAnalyzer(pass)) + } + + i := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + + for _, c := range checker { + i.Preorder(c.NodeFilter(), func(node ast.Node) { + c.Check(node) + }) + } + + return nil, nil +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/checks/argument.go b/vendor/github.com/tommy-muehle/go-mnd/checks/argument.go new file mode 100644 index 000000000000..8ee2d243dd76 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/checks/argument.go @@ -0,0 +1,98 @@ +package checks + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" +) + +const ArgumentCheck = "argument" + +// Known excludes for the argument check. +var argumentExcludes = map[string]string{ + // package: function + "time": "Date", // https://golang.org/pkg/time/#Date +} + +type ArgumentAnalyzer struct { + pass *analysis.Pass +} + +func NewArgumentAnalyzer(pass *analysis.Pass) *ArgumentAnalyzer { + return &ArgumentAnalyzer{ + pass: pass, + } +} + +func (a *ArgumentAnalyzer) NodeFilter() []ast.Node { + return []ast.Node{ + (*ast.CallExpr)(nil), + } +} + +func (a *ArgumentAnalyzer) Check(n ast.Node) { + expr, ok := n.(*ast.CallExpr) + if !ok { + return + } + + // Don't check if package and function combination is excluded + if s, ok := expr.Fun.(*ast.SelectorExpr); ok && a.isExcluded(s) { + return + } + + for i, arg := range expr.Args { + switch x := arg.(type) { + case *ast.BasicLit: + if !isMagicNumber(x) { + continue + } + // If it's a magic number and has no previous element, report it + if i == 0 { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, ArgumentCheck) + } else { + // Otherwise check the previous element type + switch expr.Args[i-1].(type) { + case *ast.ChanType: + // When it's not a simple buffered channel, report it + if x.Value != "1" { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, ArgumentCheck) + } + } + } + case *ast.BinaryExpr: + a.checkBinaryExpr(x) + } + } +} + +func (a *ArgumentAnalyzer) isExcluded(expr *ast.SelectorExpr) bool { + var p string + + switch x := expr.X.(type) { + case *ast.Ident: + p = x.Name + } + + if v, ok := argumentExcludes[p]; ok && v == expr.Sel.Name { + return true + } + + return false +} + +func (a *ArgumentAnalyzer) checkBinaryExpr(expr *ast.BinaryExpr) { + switch x := expr.X.(type) { + case *ast.BasicLit: + if isMagicNumber(x) { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, ArgumentCheck) + } + } + + switch y := expr.Y.(type) { + case *ast.BasicLit: + if isMagicNumber(y) { + a.pass.Reportf(y.Pos(), reportMsg, y.Value, ArgumentCheck) + } + } +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/checks/assign.go b/vendor/github.com/tommy-muehle/go-mnd/checks/assign.go new file mode 100644 index 000000000000..9f21d499d105 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/checks/assign.go @@ -0,0 +1,57 @@ +package checks + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" +) + +const AssignCheck = "assign" + +type AssignAnalyzer struct { + pass *analysis.Pass +} + +func NewAssignAnalyzer(pass *analysis.Pass) *AssignAnalyzer { + return &AssignAnalyzer{ + pass: pass, + } +} + +func (a *AssignAnalyzer) NodeFilter() []ast.Node { + return []ast.Node{ + (*ast.KeyValueExpr)(nil), + } +} + +func (a *AssignAnalyzer) Check(n ast.Node) { + expr, ok := n.(*ast.KeyValueExpr) + if !ok { + return + } + + switch x := expr.Value.(type) { + case *ast.BasicLit: + if isMagicNumber(x) { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, AssignCheck) + } + case *ast.BinaryExpr: + a.checkBinaryExpr(x) + } +} + +func (a *AssignAnalyzer) checkBinaryExpr(expr *ast.BinaryExpr) { + switch x := expr.X.(type) { + case *ast.BasicLit: + if isMagicNumber(x) { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, AssignCheck) + } + } + + switch y := expr.Y.(type) { + case *ast.BasicLit: + if isMagicNumber(y) { + a.pass.Reportf(y.Pos(), reportMsg, y.Value, AssignCheck) + } + } +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/checks/case.go b/vendor/github.com/tommy-muehle/go-mnd/checks/case.go new file mode 100644 index 000000000000..ac6041ebefce --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/checks/case.go @@ -0,0 +1,59 @@ +package checks + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" +) + +const CaseCheck = "case" + +type CaseAnalyzer struct { + pass *analysis.Pass +} + +func NewCaseAnalyzer(pass *analysis.Pass) *CaseAnalyzer { + return &CaseAnalyzer{ + pass: pass, + } +} + +func (a *CaseAnalyzer) NodeFilter() []ast.Node { + return []ast.Node{ + (*ast.CaseClause)(nil), + } +} + +func (a *CaseAnalyzer) Check(n ast.Node) { + caseClause, ok := n.(*ast.CaseClause) + if !ok { + return + } + + for _, c := range caseClause.List { + switch x := c.(type) { + case *ast.BasicLit: + if isMagicNumber(x) { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, CaseCheck) + } + case *ast.BinaryExpr: + a.checkBinaryExpr(x) + } + } +} + +func (a *CaseAnalyzer) checkBinaryExpr(expr *ast.BinaryExpr) { + switch x := expr.X.(type) { + case *ast.BasicLit: + if isMagicNumber(x) { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, CaseCheck) + } + } + + switch y := expr.Y.(type) { + case *ast.BasicLit: + if isMagicNumber(y) { + a.pass.Reportf(y.Pos(), reportMsg, y.Value, CaseCheck) + } + } +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/checks/checks.go b/vendor/github.com/tommy-muehle/go-mnd/checks/checks.go new file mode 100644 index 000000000000..0ee00e3c0b28 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/checks/checks.go @@ -0,0 +1,12 @@ +package checks + +import ( + "go/ast" + "go/token" +) + +const reportMsg = "Magic number: %v, in <%s> detected" + +func isMagicNumber(l *ast.BasicLit) bool { + return (l.Kind == token.FLOAT || l.Kind == token.INT) && l.Value != "0" +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/checks/condition.go b/vendor/github.com/tommy-muehle/go-mnd/checks/condition.go new file mode 100644 index 000000000000..c98035a50e78 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/checks/condition.go @@ -0,0 +1,46 @@ +package checks + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" +) + +const ConditionCheck = "condition" + +type ConditionAnalyzer struct { + pass *analysis.Pass +} + +func NewConditionAnalyzer(pass *analysis.Pass) *ConditionAnalyzer { + return &ConditionAnalyzer{ + pass: pass, + } +} + +func (a *ConditionAnalyzer) NodeFilter() []ast.Node { + return []ast.Node{ + (*ast.IfStmt)(nil), + } +} + +func (a *ConditionAnalyzer) Check(n ast.Node) { + expr, ok := n.(*ast.IfStmt).Cond.(*ast.BinaryExpr) + if !ok { + return + } + + switch x := expr.X.(type) { + case *ast.BasicLit: + if isMagicNumber(x) { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, ConditionCheck) + } + } + + switch y := expr.Y.(type) { + case *ast.BasicLit: + if isMagicNumber(y) { + a.pass.Reportf(y.Pos(), reportMsg, y.Value, ConditionCheck) + } + } +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/checks/operation.go b/vendor/github.com/tommy-muehle/go-mnd/checks/operation.go new file mode 100644 index 000000000000..5317f9967995 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/checks/operation.go @@ -0,0 +1,64 @@ +package checks + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" +) + +const OperationCheck = "operation" + +type OperationAnalyzer struct { + pass *analysis.Pass +} + +func NewOperationAnalyzer(pass *analysis.Pass) *OperationAnalyzer { + return &OperationAnalyzer{ + pass: pass, + } +} + +func (a *OperationAnalyzer) NodeFilter() []ast.Node { + return []ast.Node{ + (*ast.AssignStmt)(nil), + } +} + +func (a *OperationAnalyzer) Check(n ast.Node) { + stmt, ok := n.(*ast.AssignStmt) + if !ok { + return + } + + for _, expr := range stmt.Rhs { + switch x := expr.(type) { + case *ast.BinaryExpr: + switch xExpr := x.X.(type) { + case *ast.BinaryExpr: + a.checkBinaryExpr(xExpr) + } + switch yExpr := x.Y.(type) { + case *ast.BinaryExpr: + a.checkBinaryExpr(yExpr) + } + + a.checkBinaryExpr(x) + } + } +} + +func (a *OperationAnalyzer) checkBinaryExpr(expr *ast.BinaryExpr) { + switch x := expr.X.(type) { + case *ast.BasicLit: + if isMagicNumber(x) { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, OperationCheck) + } + } + + switch y := expr.Y.(type) { + case *ast.BasicLit: + if isMagicNumber(y) { + a.pass.Reportf(y.Pos(), reportMsg, y.Value, OperationCheck) + } + } +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/checks/return.go b/vendor/github.com/tommy-muehle/go-mnd/checks/return.go new file mode 100644 index 000000000000..c30ee0d6274d --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/checks/return.go @@ -0,0 +1,41 @@ +package checks + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" +) + +const ReturnCheck = "return" + +type ReturnAnalyzer struct { + pass *analysis.Pass +} + +func NewReturnAnalyzer(pass *analysis.Pass) *ReturnAnalyzer { + return &ReturnAnalyzer{ + pass: pass, + } +} + +func (a *ReturnAnalyzer) NodeFilter() []ast.Node { + return []ast.Node{ + (*ast.ReturnStmt)(nil), + } +} + +func (a *ReturnAnalyzer) Check(n ast.Node) { + stmt, ok := n.(*ast.ReturnStmt) + if !ok { + return + } + + for _, expr := range stmt.Results { + switch x := expr.(type) { + case *ast.BasicLit: + if isMagicNumber(x) { + a.pass.Reportf(x.Pos(), reportMsg, x.Value, ReturnCheck) + } + } + } +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/config.go b/vendor/github.com/tommy-muehle/go-mnd/config.go new file mode 100644 index 000000000000..a2d86d1e4027 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/config.go @@ -0,0 +1,58 @@ +package magic_numbers + +import ( + "strings" + + "github.com/tommy-muehle/go-mnd/checks" +) + +var knownChecks = map[string]bool{ + checks.ArgumentCheck: true, + checks.CaseCheck: true, + checks.ConditionCheck: true, + checks.OperationCheck: true, + checks.ReturnCheck: true, + checks.AssignCheck: true, +} + +type Config struct { + Checks map[string]bool +} + +type Option func(config *Config) + +func DefaultConfig() *Config { + return &Config{ + Checks: knownChecks, + } +} + +func WithOptions(options ...Option) *Config { + c := DefaultConfig() + for _, option := range options { + option(c) + } + return c +} + +func WithCustomChecks(checks string) Option { + return func(config *Config) { + config.Checks = knownChecks + + if checks == "" { + return + } + + for name, _ := range knownChecks { + config.Checks[name] = false + } + + for _, name := range strings.Split(checks, ",") { + config.Checks[name] = true + } + } +} + +func (c *Config) IsCheckEnabled(name string) bool { + return c.Checks[name] +} diff --git a/vendor/github.com/tommy-muehle/go-mnd/go.mod b/vendor/github.com/tommy-muehle/go-mnd/go.mod new file mode 100644 index 000000000000..5119a7cc13c6 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/go.mod @@ -0,0 +1,11 @@ +module github.com/tommy-muehle/go-mnd + +go 1.12 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/stretchr/objx v0.1.1 // indirect + github.com/stretchr/testify v1.3.0 + golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect + golang.org/x/tools v0.0.0-20190221204921-83362c3779f5 +) diff --git a/vendor/github.com/tommy-muehle/go-mnd/go.sum b/vendor/github.com/tommy-muehle/go-mnd/go.sum new file mode 100644 index 000000000000..bdc021ab2d54 --- /dev/null +++ b/vendor/github.com/tommy-muehle/go-mnd/go.sum @@ -0,0 +1,18 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190221204921-83362c3779f5 h1:ev5exjGDsOo0NPTB0qdCcE53BfWl1IICJlhgXgfT9fM= +golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/vendor/modules.txt b/vendor/modules.txt index 765a0903f604..3e2de1f96d6a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -170,6 +170,9 @@ github.com/stretchr/testify/mock github.com/stretchr/testify/require # github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e github.com/timakin/bodyclose/passes/bodyclose +# github.com/tommy-muehle/go-mnd v0.0.0-20190903201840-c93e405da530 +github.com/tommy-muehle/go-mnd +github.com/tommy-muehle/go-mnd/checks # github.com/ultraware/funlen v0.0.2 github.com/ultraware/funlen # github.com/ultraware/whitespace v0.0.4