Calculate cyclomatic complexities of functions in Go source code.

gocyclo

PkgGoDev Build Status Go Report Card

Gocyclo calculates cyclomatic complexities of functions in Go source code.

Cyclomatic complexity is a code quality 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 install github.com/fzipp/gocyclo/cmd/gocyclo@latest

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.

Comments
  • Fix cyclomatic complexity

    Fix cyclomatic complexity

    https://en.wikipedia.org/wiki/Cyclomatic_complexity has the following definition

    The cyclomatic complexity of a section of source code is the number of linearly independent paths within it

    The current version of the code does not count linearly independent code paths. Instead it counts branch points. This is different. For example, cyclomatic complexity of

    if a {
      if b {
      } else {
      }
    } else {
    }
    

    and

    if a {
    } else {
    }
    if b {
    } else {
    }
    

    must be different, but current implementation would return same value.

    This PR rewrites the computation algorithm.

  • Don't recurse into directories.

    Don't recurse into directories.

    For editor/IDE tooling, recursing by default can be very very slow. I think, as with many other tools, that in conjunction with find -type d all use cases are satisfied.

  • Add a flag to skip test files

    Add a flag to skip test files

    This PR adds a flag to allow a user to easily skip test files during analysis for cases when the critical component is the code under test and not the tests themselves.

  • Implement -ignore

    Implement -ignore

    This PR implements the possibility to ignore files that match the given regular expression. Fixes #9, #4 (generic approach).

    Example:

    $ gocyclo -ignore "yacc|\.pb\.|Godeps" .
    
  • Change rules of cyclomatic complexity calculation

    Change rules of cyclomatic complexity calculation

    Hello, @fzipp.

    I think highly nested construction should not give the same amount of points as the first-level one. Flat code is less complex than nested, isn't it? For illustration, here is a code fragment that has complexity of 11:

    package zzz
    
    func smth(obj interface{}) {
        switch obj.(type) {
        case int:
            ProcessInt(obj)
        case int8:
            // ..
        case int16:
        case int32:
        case int64:
        case uint:
        case uint8:
        case uint16:
        case uint32:
        case uint64:
        }
    }
    

    Pretty simple and straight-forward function, isn't it? Now here is another one that is "less complex" (level is 10):

    package xxx
    
    func smth(i int) {
        if i < 1 {
            if i < 2 {
                if i < 3 {
                    if i < 4 {
                        if i < 5 {
                            if i < 6 {
                            } else {
                            }
                        } else {
                        }
                    } else {
                        if i < 5 {
                        } else {
                        }
                    }
                } else {
                    if i < 4 {
                        if i < 5 {
                        } else {
                        }
                    } else {
                    }
                }
            } else {
            }
        } else {
        }
    }
    

    For me, personally, this doesn't look like a less complex function. What do you think?

    My opinion is complexity should grow geometrically with every level of nesting. But requirements for flat code may be loosed up.

  • Skip individual functions

    Skip individual functions

    Background: https://github.com/alecthomas/gometalinter/issues/238

    In short, when gocyclo is executed automatically (for ex. by gometalinter in CI) and it output is used to decide to pass or to fail automatic build we need more control than just single -over N value applied to all packages in current project.

    Please add a feature to either completely skip gocyclo on per-function basis, or overwrite value of -over N argument on per-function basis. For example, check how another tool use annotations: https://github.com/GoASTScanner/gas#annotating-code

  • Add flag to skip tests

    Add flag to skip tests

    Add a flag which will exclude testing code from the generated report.

    I think it is useful to be able to optionally exclude tests from the report. I am suggesting this be a flag and optional since the exclusion or inclusion of test source code is dependant on the developer(s) or project maintainer(s) and this would give flexibility to whatever they decide.

  • Include variable functions

    Include variable functions

    I noticed that functions declared as variables are not included. It would be nice if they were. We use variable functions a lot for testability and mocking.

  • Do not analyze files ignored by go tool

    Do not analyze files ignored by go tool

    According to https://golang.org/cmd/go/: directory and file names that begin with "." or "_" are ignored by the go tool, as are directories named "testdata".

    Fixes #6

  • Ignore the vendor folder by default

    Ignore the vendor folder by default

    We are using this project for Fyne, but we need to remove the vendor folder (https://github.com/fyne-io/fyne/blob/7229e889d49c81a83b0b7e09400837f67f6ddad5/.github/workflows/static_analysis.yml#L21) to ignore picking up things in packages that we do not maintain. It would be great if gocyclo could do like many other Go tools and simple ignore looking in the vendor folder.

  • Provide a switch to better fit golang

    Provide a switch to better fit golang

    Not just an issue, but it would be nice to have a switch to avoid counting constructs clearly related to mere error checking and returning, for example IF block with less that 3/4 lines testing just err != nil could be not counted in complexity. ES: if err != nil { log....... return nil,err // or return fmt.Errorf("sfsdfsdf %w", err) }

  • Proposal: Add option to ignore error checking if statements that return only an error

    Proposal: Add option to ignore error checking if statements that return only an error

    While technically correct, in my opinion if err != nil checks don't really add complexity to a function from the programmers' standpoint. It would be nice to have an option to ignore these statements in functions.

  • How to ignore local function?

    How to ignore local function?

    I usually use local functions to split my main function to multiple part and group related functions together. However, gocyclo always report the complexity of my main function is high (e.g: 20) while it looks lower if we remove the local functions.

    Can we have an option to exclude the local functions from calculation?

  • Add a flag to mark exit status

    Add a flag to mark exit status

    Can we have a CLI parameter to let gocyclo exit with non-zero value in case there are files meet -over criteria?

    I'm thinking of using gocyclo in CI job, instead of pipe output to a file, then check if the file is empty or not to determine offending files, it will be great to have an option mentioned above.

  • Improve documentation

    Improve documentation

    It is a nice to have to provide a wiki with academic definitions (as described in #10) and provide some examples of usage (with code and expected results)

  • function literals not separately counted

    function literals not separately counted

    It would be nice if function literals were assigned a complexity separate from the function declaration they were nested inside. This will require giving the nested function literals pseudo-names. E.g., the second function literal nested inside func Foo, might given pseudo name like "Foo.funcLit#2". It might also require using a map[string]stat rather than a []stat and indexing the map with a concatenation of package path with the function name.

Source code editor in pure Go.
Source code editor in pure Go.

Editor Source code editor in pure Go. About This is a simple but advanced source code editor As the editor is being developed, the rules of how the UI

Dec 25, 2022
Grab is a tool that downloads source code repositories into a convenient directory layout created from the repo's URL's domain and path

Grab is a tool that downloads source code repositories into a convenient directory layout created from the repo's URL's domain and path. It supports Git, Mercurial (hg), Subversion, and Bazaar repositories.

Jun 2, 2022
Source code of a YouTube tutorial about writing terminal applications with Golang

Bubble Tea Demo 00 Source code of a YouTube tutorial about writing terminal applications with Golang by using Bubble Tea. Contains a simple counter ap

Nov 10, 2022
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go

Sloc Cloc and Code (scc) A tool similar to cloc, sloccount and tokei. For counting physical the lines of code, blank lines, comment lines, and physica

Jan 8, 2023
AI-powered code snippet generator using ChatGPT. Generate code in various languages based on natural language descriptions!

SnipForge - AI-Powered Code Snippet Generator SnipForge is a powerful command-line interface (CLI) tool that utilizes OpenAI's GPT technology to gener

May 5, 2023
Demonstrating how you can take an action to your intrusions detected by Falco using OpenFaaS functions
Demonstrating how you can take an action to your intrusions detected by Falco using OpenFaaS functions

Kubernetes Response Engine powered by OpenFaaS Although Falco can be used to detect any intrusion attempts and sends alerts to channels according to t

Aug 22, 2022
webify - Turn functions and commands into web services
webify - Turn functions and commands into web services

webify is a very basic CGI server which forwards all requests to a single script. A design goal is to be as zero-config as possible.

Dec 22, 2022
This repository contains utility functions that do not make sense in other packages.

Installation go get github.com/IQ-tech/go-utils Executing code before process exits AtInterruption receives a function that will be called once befor

Dec 9, 2021
Package osargs provides functions to parse command line arguments

osargs About Package osargs provides functions to parse command line arguments. It is published on https://github.com/vbsw/osargs and https://gitlab.c

May 8, 2022
A CLI tool for working with CloudWatch logs. It performs functions that I need at work.

CloudWatch Logs Utility A simple utility for working with CloudWatch Logs. AWS should probably build this themselves, but since they won't, I am here

Dec 31, 2021
UltiTuner: a small helper tool to configure functions for Ultimaker S-Line printers

UltiTuner UltiTuner is a small helper tool to configure functions for Ultimaker

Apr 25, 2022
List of serverless functions for AWS S3. Easy deploy with Vercel CLI

List of serverless functions for AWS S3. Easy deploy with Vercel CLI

Jan 22, 2022
Extensible Go terminal spinner with advanced functions with 82 built-in spinners
Extensible Go terminal spinner with advanced functions with 82 built-in spinners

Features Start/Stop Customizable character sets (spinners) Custom spinner color, background Custom spinner text Restarting and reversing the spinner P

Aug 19, 2022
An open-source GitLab command line tool bringing GitLab's cool features to your command line
An open-source GitLab command line tool bringing GitLab's cool features to your command line

GLab is an open source GitLab CLI tool bringing GitLab to your terminal next to where you are already working with git and your code without switching

Dec 30, 2022
Upterm is an open-source solution for sharing terminal sessions instantly over the public internet via secure tunnels.
Upterm is an open-source solution for sharing terminal sessions instantly over the public internet via secure tunnels.

Upterm is an open-source solution for sharing terminal sessions instantly over the public internet via secure tunnels.

Jan 8, 2023
Teller - the open-source universal secret manager for developers
 Teller - the open-source universal secret manager for developers

A secrets management tool for developers built in Go - never leave your command line for secrets.

Jan 8, 2023
a Go language free and open-source document for learning from zero level

Go document a GO language free and open-source document for learning from zero level Please publish and collaborate OPEN-SOURCE Sections About go lang

Jan 8, 2023
bryant's go note and source

These are my notes from when I taught myself Golang. It includes the basic syntax of go language, basic operators, function operations, packages, inte

Oct 17, 2022
Wishbox - Wishlist using netbox as inventory source

Wishbox Generate a wishlist directory based on your netbox inventory. How does i

Nov 6, 2022