aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/fzipp
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2021-02-22 20:37:25 +0100
committerDmitry Vyukov <dvyukov@google.com>2021-02-22 21:02:12 +0100
commitfcc6d71be2c3ce7d9305c04fc2e87af554571bac (patch)
treeb01dbb3d1e2988e28ea158d2d543d603ec0b9569 /vendor/github.com/fzipp
parent8f23c528ad5a943b9ffec5dcaf332fd0f614006e (diff)
go.mod: update golangci-lint to v1.37
Diffstat (limited to 'vendor/github.com/fzipp')
-rw-r--r--vendor/github.com/fzipp/gocyclo/CHANGELOG.md38
-rw-r--r--vendor/github.com/fzipp/gocyclo/CONTRIBUTORS7
-rw-r--r--vendor/github.com/fzipp/gocyclo/LICENSE27
-rw-r--r--vendor/github.com/fzipp/gocyclo/README.md107
-rw-r--r--vendor/github.com/fzipp/gocyclo/analyze.go151
-rw-r--r--vendor/github.com/fzipp/gocyclo/complexity.go48
-rw-r--r--vendor/github.com/fzipp/gocyclo/directives.go39
-rw-r--r--vendor/github.com/fzipp/gocyclo/go.mod3
-rw-r--r--vendor/github.com/fzipp/gocyclo/stats.go73
9 files changed, 493 insertions, 0 deletions
diff --git a/vendor/github.com/fzipp/gocyclo/CHANGELOG.md b/vendor/github.com/fzipp/gocyclo/CHANGELOG.md
new file mode 100644
index 000000000..3959a62a5
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/CHANGELOG.md
@@ -0,0 +1,38 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [0.3.1]
+### Added
+- Test coverage
+
+### Fixed
+- Fix cyclomatic complexity for function literals (base complexity of 1 was missing)
+
+## [0.3.0] - 2020-10-17
+### Added
+- New `-avg-short` and `-total-short` options for printing average and total cyclomatic complexities without label
+- Export the `AnalyzeASTFile` function in package API
+- Doc comments for exported functions and types
+
+### Fixed
+- Ignore `default` cases
+
+## [0.2.0] - 2020-10-17
+### Added
+- Support for gocyclo as a package
+- Support for ignoring of individual functions via a new `gocyclo:ignore` directive
+- New `-total` option to compute total cyclomatic complexity
+- New `-ignore` option to ignore files matching a regular expression
+- Analysis of function literals at declaration level
+
+### Changed
+- Breaking: installation changed to `go get github.com/fzipp/gocyclo/cmd/gocyclo`
+
+## [0.1.0] - 2020-10-17
+
+### Added
+- `go.mod` file; beginning of versioning
+
diff --git a/vendor/github.com/fzipp/gocyclo/CONTRIBUTORS b/vendor/github.com/fzipp/gocyclo/CONTRIBUTORS
new file mode 100644
index 000000000..1c09f1a06
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/CONTRIBUTORS
@@ -0,0 +1,7 @@
+# Names should be added to this file like so:
+# Name <email address>
+
+# Please keep the list sorted.
+
+Frederik Zipp <fzipp@gmx.de>
+Harshavardhana <harsha@harshavardhana.net>
diff --git a/vendor/github.com/fzipp/gocyclo/LICENSE b/vendor/github.com/fzipp/gocyclo/LICENSE
new file mode 100644
index 000000000..45f88d6cb
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013 Frederik Zipp. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of the copyright owner nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/fzipp/gocyclo/README.md b/vendor/github.com/fzipp/gocyclo/README.md
new file mode 100644
index 000000000..f1056934c
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/README.md
@@ -0,0 +1,107 @@
+# gocyclo
+
+[![PkgGoDev](https://pkg.go.dev/badge/github.com/fzipp/gocyclo)](https://pkg.go.dev/github.com/fzipp/gocyclo)
+[![Go Report Card](https://goreportcard.com/badge/github.com/fzipp/gocyclo)](https://goreportcard.com/report/github.com/fzipp/gocyclo)
+
+Gocyclo calculates
+[cyclomatic complexities](https://en.wikipedia.org/wiki/Cyclomatic_complexity)
+of functions in Go source code.
+
+Cyclomatic complexity is a
+[code quality metric](https://en.wikipedia.org/wiki/Software_metric)
+which can be used to identify code that needs refactoring.
+It measures the number of linearly independent paths through a function's
+source code.
+
+The cyclomatic complexity of a function is calculated according to the
+following rules:
+
+```
+ 1 is the base complexity of a function
++1 for each 'if', 'for', 'case', '&&' or '||'
+```
+
+A function with a higher cyclomatic complexity requires more test cases to
+cover all possible paths and is potentially harder to understand. The
+complexity can be reduced by applying common refactoring techniques that lead
+to smaller functions.
+
+## Installation
+
+To install the `gocyclo` command, run
+
+```
+$ go get github.com/fzipp/gocyclo/cmd/gocyclo
+```
+
+and put the resulting binary in one of your PATH directories if
+`$GOPATH/bin` isn't already in your PATH.
+
+## Usage
+
+```
+Calculate cyclomatic complexities of Go functions.
+Usage:
+ gocyclo [flags] <Go file or directory> ...
+
+Flags:
+ -over N show functions with complexity > N only and
+ return exit code 1 if the set is non-empty
+ -top N show the top N most complex functions only
+ -avg, -avg-short show the average complexity over all functions;
+ the short option prints the value without a label
+ -total, -total-short show the total complexity for all functions;
+ the short option prints the value without a label
+ -ignore REGEX exclude files matching the given regular expression
+
+The output fields for each line are:
+<complexity> <package> <function> <file:line:column>
+```
+
+## Examples
+
+```
+$ gocyclo .
+$ gocyclo main.go
+$ gocyclo -top 10 src/
+$ gocyclo -over 25 docker
+$ gocyclo -avg .
+$ gocyclo -top 20 -ignore "_test|Godeps|vendor/" .
+$ gocyclo -over 3 -avg gocyclo/
+```
+
+Example output:
+
+```
+9 gocyclo (*complexityVisitor).Visit complexity.go:30:1
+8 main main cmd/gocyclo/main.go:53:1
+7 gocyclo (*fileAnalyzer).analyzeDecl analyze.go:96:1
+4 gocyclo Analyze analyze.go:24:1
+4 gocyclo parseDirectives directives.go:27:1
+4 gocyclo (Stats).SortAndFilter stats.go:52:1
+Average: 2.72
+```
+
+Note that the average is calculated over all analyzed functions,
+not just the printed ones.
+
+### Ignoring individual functions
+
+Individual functions can be ignored with a `gocyclo:ignore` directive:
+
+```
+//gocyclo:ignore
+func f1() {
+ // ...
+}
+
+//gocyclo:ignore
+var f2 = func() {
+ // ...
+}
+```
+
+## License
+
+This project is free and open source software licensed under the
+[BSD 3-Clause License](LICENSE).
diff --git a/vendor/github.com/fzipp/gocyclo/analyze.go b/vendor/github.com/fzipp/gocyclo/analyze.go
new file mode 100644
index 000000000..c053e83e6
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/analyze.go
@@ -0,0 +1,151 @@
+// Copyright 2020 Frederik Zipp. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocyclo
+
+import (
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "log"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+// Analyze calculates the cyclomatic complexities of the functions and methods
+// in the Go source code files in the given paths. If a path is a directory
+// all Go files under that directory are analyzed recursively.
+// Files with paths matching the 'ignore' regular expressions are skipped.
+// The 'ignore' parameter can be nil, meaning that no files are skipped.
+func Analyze(paths []string, ignore *regexp.Regexp) Stats {
+ var stats Stats
+ for _, path := range paths {
+ info, err := os.Stat(path)
+ if err != nil {
+ log.Printf("could not get file info for path %q: %s\n", path, err)
+ continue
+ }
+ if info.IsDir() {
+ stats = analyzeDir(path, ignore, stats)
+ } else {
+ stats = analyzeFile(path, ignore, stats)
+ }
+ }
+ return stats
+}
+
+func analyzeDir(dirname string, ignore *regexp.Regexp, stats Stats) Stats {
+ filepath.Walk(dirname, func(path string, info os.FileInfo, err error) error {
+ if err == nil && isGoFile(info) {
+ stats = analyzeFile(path, ignore, stats)
+ }
+ return err
+ })
+ return stats
+}
+
+func isGoFile(f os.FileInfo) bool {
+ return !f.IsDir() && strings.HasSuffix(f.Name(), ".go")
+}
+
+func analyzeFile(path string, ignore *regexp.Regexp, stats Stats) Stats {
+ if isIgnored(path, ignore) {
+ return stats
+ }
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
+ if err != nil {
+ log.Fatal(err)
+ }
+ return AnalyzeASTFile(f, fset, stats)
+}
+
+func isIgnored(path string, ignore *regexp.Regexp) bool {
+ return ignore != nil && ignore.MatchString(path)
+}
+
+// AnalyzeASTFile calculates the cyclomatic complexities of the functions
+// and methods in the abstract syntax tree (AST) of a parsed Go file and
+// appends the results to the given Stats slice.
+func AnalyzeASTFile(f *ast.File, fs *token.FileSet, s Stats) Stats {
+ analyzer := &fileAnalyzer{
+ file: f,
+ fileSet: fs,
+ stats: s,
+ }
+ return analyzer.analyze()
+}
+
+type fileAnalyzer struct {
+ file *ast.File
+ fileSet *token.FileSet
+ stats Stats
+}
+
+func (a *fileAnalyzer) analyze() Stats {
+ for _, decl := range a.file.Decls {
+ a.analyzeDecl(decl)
+ }
+ return a.stats
+}
+
+func (a *fileAnalyzer) analyzeDecl(d ast.Decl) {
+ switch decl := d.(type) {
+ case *ast.FuncDecl:
+ a.addStatIfNotIgnored(decl, funcName(decl), decl.Doc)
+ case *ast.GenDecl:
+ for _, spec := range decl.Specs {
+ valueSpec, ok := spec.(*ast.ValueSpec)
+ if !ok {
+ continue
+ }
+ for _, value := range valueSpec.Values {
+ funcLit, ok := value.(*ast.FuncLit)
+ if !ok {
+ continue
+ }
+ a.addStatIfNotIgnored(funcLit, valueSpec.Names[0].Name, decl.Doc)
+ }
+ }
+ }
+}
+
+func (a *fileAnalyzer) addStatIfNotIgnored(node ast.Node, funcName string, doc *ast.CommentGroup) {
+ if parseDirectives(doc).HasIgnore() {
+ return
+ }
+ a.stats = append(a.stats, Stat{
+ PkgName: a.file.Name.Name,
+ FuncName: funcName,
+ Complexity: Complexity(node),
+ Pos: a.fileSet.Position(node.Pos()),
+ })
+}
+
+// funcName returns the name representation of a function or method:
+// "(Type).Name" for methods or simply "Name" for functions.
+func funcName(fn *ast.FuncDecl) string {
+ if fn.Recv != nil {
+ if fn.Recv.NumFields() > 0 {
+ typ := fn.Recv.List[0].Type
+ return fmt.Sprintf("(%s).%s", recvString(typ), fn.Name)
+ }
+ }
+ return fn.Name.Name
+}
+
+// recvString returns a string representation of recv of the
+// form "T", "*T", or "BADRECV" (if not a proper receiver type).
+func recvString(recv ast.Expr) string {
+ switch t := recv.(type) {
+ case *ast.Ident:
+ return t.Name
+ case *ast.StarExpr:
+ return "*" + recvString(t.X)
+ }
+ return "BADRECV"
+}
diff --git a/vendor/github.com/fzipp/gocyclo/complexity.go b/vendor/github.com/fzipp/gocyclo/complexity.go
new file mode 100644
index 000000000..65f5077e8
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/complexity.go
@@ -0,0 +1,48 @@
+// Copyright 2020 Frederik Zipp. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gocyclo calculates the cyclomatic complexities of functions and
+// methods in Go source code.
+package gocyclo
+
+import (
+ "go/ast"
+ "go/token"
+)
+
+// Complexity calculates the cyclomatic complexity of a function.
+// The 'fn' node is either a *ast.FuncDecl or a *ast.FuncLit.
+func Complexity(fn ast.Node) int {
+ v := complexityVisitor{
+ complexity: 1,
+ }
+ ast.Walk(&v, fn)
+ return v.complexity
+}
+
+type complexityVisitor struct {
+ // complexity is the cyclomatic complexity
+ complexity int
+}
+
+// Visit implements the ast.Visitor interface.
+func (v *complexityVisitor) Visit(n ast.Node) ast.Visitor {
+ switch n := n.(type) {
+ case *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt:
+ v.complexity++
+ case *ast.CaseClause:
+ if n.List != nil { // ignore default case
+ v.complexity++
+ }
+ case *ast.CommClause:
+ if n.Comm != nil { // ignore default case
+ v.complexity++
+ }
+ case *ast.BinaryExpr:
+ if n.Op == token.LAND || n.Op == token.LOR {
+ v.complexity++
+ }
+ }
+ return v
+}
diff --git a/vendor/github.com/fzipp/gocyclo/directives.go b/vendor/github.com/fzipp/gocyclo/directives.go
new file mode 100644
index 000000000..b4ee3c448
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/directives.go
@@ -0,0 +1,39 @@
+// Copyright 2020 Frederik Zipp. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocyclo
+
+import (
+ "go/ast"
+ "strings"
+)
+
+type directives []string
+
+func (ds directives) HasIgnore() bool {
+ return ds.isPresent("ignore")
+}
+
+func (ds directives) isPresent(name string) bool {
+ for _, d := range ds {
+ if d == name {
+ return true
+ }
+ }
+ return false
+}
+
+func parseDirectives(doc *ast.CommentGroup) directives {
+ if doc == nil {
+ return directives{}
+ }
+ const prefix = "//gocyclo:"
+ var ds directives
+ for _, comment := range doc.List {
+ if strings.HasPrefix(comment.Text, prefix) {
+ ds = append(ds, strings.TrimSpace(strings.TrimPrefix(comment.Text, prefix)))
+ }
+ }
+ return ds
+}
diff --git a/vendor/github.com/fzipp/gocyclo/go.mod b/vendor/github.com/fzipp/gocyclo/go.mod
new file mode 100644
index 000000000..c80982786
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/go.mod
@@ -0,0 +1,3 @@
+module github.com/fzipp/gocyclo
+
+go 1.15
diff --git a/vendor/github.com/fzipp/gocyclo/stats.go b/vendor/github.com/fzipp/gocyclo/stats.go
new file mode 100644
index 000000000..90f5eefc2
--- /dev/null
+++ b/vendor/github.com/fzipp/gocyclo/stats.go
@@ -0,0 +1,73 @@
+// Copyright 2020 Frederik Zipp. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocyclo
+
+import (
+ "fmt"
+ "go/token"
+ "sort"
+)
+
+// Stat holds the cyclomatic complexity of a function, along with its package
+// and and function name and its position in the source code.
+type Stat struct {
+ PkgName string
+ FuncName string
+ Complexity int
+ Pos token.Position
+}
+
+// String formats the cyclomatic complexity information of a function in
+// the following format: "<complexity> <package> <function> <file:line:column>"
+func (s Stat) String() string {
+ return fmt.Sprintf("%d %s %s %s", s.Complexity, s.PkgName, s.FuncName, s.Pos)
+}
+
+// Stats hold the cyclomatic complexities of many functions.
+type Stats []Stat
+
+// AverageComplexity calculates the average cyclomatic complexity of the
+// cyclomatic complexities in s.
+func (s Stats) AverageComplexity() float64 {
+ return float64(s.TotalComplexity()) / float64(len(s))
+}
+
+// TotalComplexity calculates the total sum of all cyclomatic
+// complexities in s.
+func (s Stats) TotalComplexity() uint64 {
+ total := uint64(0)
+ for _, stat := range s {
+ total += uint64(stat.Complexity)
+ }
+ return total
+}
+
+// SortAndFilter sorts the cyclomatic complexities in s in descending order
+// and returns a slice of s limited to the 'top' N entries with a cyclomatic
+// complexity greater than 'over'. If 'top' is negative, i.e. -1, it does
+// not limit the result. If 'over' is <= 0 it does not limit the result either,
+// because a function has a base cyclomatic complexity of at least 1.
+func (s Stats) SortAndFilter(top, over int) Stats {
+ result := make(Stats, len(s))
+ copy(result, s)
+ sort.Sort(byComplexityDesc(result))
+ for i, stat := range result {
+ if i == top {
+ return result[:i]
+ }
+ if stat.Complexity <= over {
+ return result[:i]
+ }
+ }
+ return result
+}
+
+type byComplexityDesc Stats
+
+func (s byComplexityDesc) Len() int { return len(s) }
+func (s byComplexityDesc) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s byComplexityDesc) Less(i, j int) bool {
+ return s[i].Complexity >= s[j].Complexity
+}