gocognit

repository·master·Indexed 19 days ago

https://github.com/uudashr/gocognit

A tool and library for calculating the cognitive complexity of Go functions and methods. It provides a human-centric metric that penalizes nesting and specific control structures more heavily than traditional cyclomatic complexity. It includes a CLI for analyzing files and directories, a Go package for programmatic analysis, and a standard golang.org/x/tools/go/analysis Analyzer for integration into linting tools or go vet.

Tokens
2.2K
Snippets
12
Records
16
Agent score
59%

What's inside gocognit

  1. Understand how cognitive complexity is calculated

    master

    Cognitive complexity measures how intuitively hard code is to understand. Unlike cyclomatic complexity, it penalizes nesting and specific control structures more heavily.

    Increments

    An increment is added for each of the following:

    1. if, else if, else
    2. switch, select
    3. for
    4. goto LABEL, break LABEL, continue LABEL
    5. Sequence of binary logical operators
    6. Each method in a recursion cycle

    Nesting

    Certain structures increase the nesting level, which in turn increases the weight of subsequent increments:

    • Nesting level increases for: if, else if, else, switch, select, for, and function literals/lambdas.
    • Nesting increments apply to: if, switch, select, and for structures based on their depth.
  2. Use the gocognit CLI to analyze Go code

    master

    The gocognit tool calculates the cognitive complexity of functions and methods in Go source code. You can pass Go files or directories as arguments.

    Common Usage Examples

    • Analyze the current directory: gocognit .
    • Analyze a specific file: gocognit main.go
    • Show the top 10 most complex functions: gocognit -top 10 src/
    • Show only functions with complexity greater than 25: gocognit -over 25 docker (returns exit code 1 if matches are found)
    • Show the average complexity: gocognit -avg .
    • Ignore files matching a regex: gocognit -ignore "_test|testdata" .
    gocognit -top 10 src/
  3. Install the gocognit CLI

    master

    You can install the gocognit command-line tool using either go install or go get.

    go install github.com/uudashr/gocognit/cmd/gocognit@latest

    or

    go get github.com/uudashr/gocognit/cmd/gocognit
    go install github.com/uudashr/gocognit/cmd/gocognit@latest
  4. Ignore specific functions using comments

    master

    You can instruct gocognit to skip specific functions by adding the //gocognit:ignore directive immediately above the function definition.

    //gocognit:ignore
    func IgnoreMe() {
        // ...
    }
    //gocognit:ignore
    func IgnoreMe() {
        // ...
    }
  5. Use the gocognit package to calculate cognitive complexity

    master
    The gocognit package provides an Analyzer and other utilities designed to calculate the cognitive complexity of functions. Cognitive complexity is a metric used to measure how difficult a piece of code is to understand, providing an alternative to traditional cyclomatic complexity by accounting for nesting and structural patterns.
  6. Use the gocognit CLI to calculate cognitive complexity

    master

    The gocognit command-line tool calculates the cognitive complexity of Go functions and methods within specified files or directories. It can output results in a custom text format or as JSON, and supports filtering by complexity thresholds or top results.

    Basic Usage:

    gocognit [<flag> ...] <Go file or directory> ...
    gocognit <Go file or directory>
  7. Get detailed complexity diagnostics

    master

    To understand exactly how a specific complexity score was calculated, use the -d flag. When combined with -json, it provides a detailed breakdown of every increment and nesting level encountered during analysis.

    gocognit -json -d .
    gocognit -json -d .
  8. Customize gocognit output format with templates

    master

    You can use the -f flag to provide a Go template for text output. The template is passed a Stat struct.

    Available fields in the Stat struct:

    • PkgName (string): The package name.
    • FuncName (string): The function name.
    • Complexity (int): The calculated cognitive complexity.
    • Pos (token.Position): The position of the function.
    • Diagnostics ([]Diagnostic): A list of diagnostic details.

    Available fields in the Diagnostic struct:

    • Inc (string): The increment value.
    • Nesting (int): The nesting level.
    • Text (string): Description of the complexity increment.
    • Pos (DiagnosticPosition): The position of the diagnostic.

    Available fields in the DiagnosticPosition struct:

    • Offset (int)
    • Line (int)
    • Column (int)

    Default format: {{.Complexity}} {{.PkgName}} {{.FuncName}} {{.Pos}} which produces output like: <complexity> <package> <function> <file:row:column>

  9. Reference the gocognit CLI flags

    master

    The following flags are available for the gocognit command:

    FlagDescription
    -over NShow functions with complexity > N only and return exit code 1 if the output is non-empty
    -top NShow the top N most complex functions only
    -avgShow the average complexity over all functions, not depending on whether -over or -top are set
    -testIndicates whether test files should be included
    -jsonEncode the output as JSON
    -dEnable diagnostic output
    -f formatString the format to use (default "{{.Complexity}} {{.PkgName}} {{.FuncName}} {{.Pos}}" )
    -ignore exprIgnore files matching the given regexp
    gocognit [<flag> ...] <Go file or directory> ...
  10. Generate complexity statistics for an entire file

    master

    To analyze all functions within a Go file, use ComplexityStats or ComplexityStatsWithDiagnostic. These functions iterate through the file's declarations, respect the //gocognit:ignore directive, and return a slice of Stat objects.

    • ComplexityStats(f, fset, stats): Returns statistics without detailed diagnostics.
    • ComplexityStatsWithDiagnostic(f, fset, stats, enableDiagnostics): Returns statistics including detailed Diagnostic information for each function.
    // stats is an existing slice of gocognit.Stat to append to
    fileStats := gocognit.ComplexityStats(astFile, fileSet, stats)