Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Build Status

Fund me on Gittip

Simple cyclomatic complexity analysis for Go programs.


This program doesn't construct the full graph to calculate complexity; it just does the simple count of the decision points.


go get

(and make sure your $GOPATH is in your $PATH)


usage: cyclo [flags] [path ...]
  -max-complexity=0: max complexity

If no flags are specified, it just finds every function definition in the specified file(s) and displays its cyclomatic complexity:

$ cyclo cyclo.go
cyclo.go:22:1:  main    1
cyclo.go:27:1:  usage   1
cyclo.go:33:1:  cycloMain       7
cyclo.go:64:1:  getComplexity   2
cyclo.go:70:1:  process 2
cyclo.go:89:1:  processFile     11
cyclo.go:130:1: visitFile       4
cyclo.go:140:1: walkDir 1
cyclo.go:144:1: report  1
cyclo.go:149:1: isGoFile        2

The --max-complexity flag will filter the results so that only functions with higher complexity are reported. It will also set the error-code to a non-zero value if any functions trip it. This makes it suitable for use in a git commit hook, for example.

$ cyclo --max-complexity=10 cyclo.go
cyclo.go:89:1:  processFile     11

The skeleton of the code was ripped off from go fmt (steal from the best), so it should behave very similarly as far as how it globs filenames, traverses directories, and so on.


I haven't yet figured out how to only count return statements that aren't the last statement in the function, so functions with an explicit return at the end currently return 1 higher than they should.


I have not really thought deeply yet about how go or defer statements should be counted towards complexity. Anyone with good ideas, let me know.

For now, I've made function literals count as a decision point towards complexity. I'm not sure if that's right. Eg,

myMap(mySlice, func (v int) {
    // do something with v

My thinking is that often when you are using a function literal, it's for that type of situation. Ie, "call this on some value later zero or more times" and should be equivalent to a conditional or loop from a complexity standpoint. Again, I'm open to arguments against this line of reasoning.

The Python tool that inspired this has the ability to generate a graph of the complexity map in dot format. That's cool, but I have never found it useful for anything other than novelty, so I probably won't bother implementing a similar feature here. If someone else is interested in that, I'm happy to take a patch though.




cyclomatic complexity analyzer for Go programs






No releases published


No packages published