Skip to content

A Go static analysis tool that computes cognitive complexity scores for Go source code. Unlike cyclomatic complexity, cognitive complexity measures how difficult code is to understand by humans, taking into account nesting depth and control flow interruptions. Measures cognitive complexity of source code.

License

Notifications You must be signed in to change notification settings

BaseMax/go-cogscore

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-cogscore

A Go static analysis tool that computes cognitive complexity scores for Go source code. Unlike cyclomatic complexity, cognitive complexity measures how difficult code is to understand by humans, taking into account nesting depth and control flow interruptions.

Features

  • đź§  Cognitive Complexity Analysis: Measures code understandability, not just paths
  • 📊 Multiple Output Formats: Text, detailed, JSON, and CI-friendly formats
  • 🎯 Nesting Detection: Identifies deeply nested logic with penalty scoring
  • 🔍 Readability Risk Assessment: Categorizes functions by risk levels
  • 🚀 CI Integration: Exit codes and key-value output for automated pipelines
  • 📝 Annotated Reports: Line-by-line breakdown of complexity contributors
  • đź”§ Flexible Filtering: Filter results by minimum/maximum complexity scores

Installation

go install github.com/BaseMax/go-cogscore/cmd/go-cogscore@latest

Or build from source:

git clone https://github.com/BaseMax/go-cogscore
cd go-cogscore
go build -o go-cogscore ./cmd/go-cogscore

Usage

Basic Analysis

Analyze current directory:

go-cogscore

Analyze specific files or directories:

go-cogscore ./pkg ./cmd
go-cogscore main.go utils.go

Output Formats

Simple text report (default):

go-cogscore -format text

Detailed report with line-by-line breakdown:

go-cogscore -format detailed

JSON output for programmatic consumption:

go-cogscore -format json > complexity.json

CI-friendly format with exit codes:

go-cogscore -format ci

Filtering Results

Show only high-complexity functions (score > 15):

go-cogscore -min 15

Show only moderate complexity (score between 5 and 10):

go-cogscore -min 5 -max 10

Understanding Cognitive Complexity

Cognitive complexity differs from cyclomatic complexity by focusing on how hard code is to understand:

Scoring Rules

  1. Base Increment (+1): Control flow structures like if, for, switch, select
  2. Nesting Penalty (+n): Each level of nesting adds to the score
  3. Logical Operators (+1): Each && and || in conditions
  4. Jump Statements (+1): goto and labeled break/continue

Examples

Simple function (Score: 0):

func add(a, b int) int {
    return a + b
}

Single if statement (Score: 1):

func max(a, b int) int {
    if a > b {  // +1
        return a
    }
    return b
}

Nested conditions (Score: 3):

func process(x, y int) {
    if x > 0 {        // +1
        if y > 0 {    // +2 (1 base + 1 nesting)
            println("both positive")
        }
    }
}

Complex logic (Score: 6):

func analyze(items []int) int {
    sum := 0
    for _, item := range items {    // +1
        if item > 0 {               // +2 (nesting level 1)
            if item < 100 {         // +3 (nesting level 2)
                sum += item
            }
        }
    }
    return sum
}

Risk Levels

Functions are categorized by cognitive complexity score:

Score Risk Level Recommendation
1-5 LOW Simple, easy to understand
6-10 MODERATE Slightly complex, acceptable
11-15 HIGH Complex, consider refactoring
16-20 VERY HIGH Very complex, should refactor
21+ CRITICAL Extremely complex, must refactor

CI Integration

Exit Codes

When using -format ci, the tool exits with:

  • 0: OK (no high-risk functions)
  • 1: WARNING (functions with score 16-20)
  • 2: CRITICAL (functions with score 21+)

GitHub Actions Example

name: Code Complexity Check

on: [push, pull_request]

jobs:
  complexity:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.21'
      
      - name: Install go-cogscore
        run: go install github.com/BaseMax/go-cogscore/cmd/go-cogscore@latest
      
      - name: Check cognitive complexity
        run: |
          go-cogscore -format ci
          go-cogscore -format detailed -min 15

GitLab CI Example

complexity-check:
  stage: test
  image: golang:1.21
  script:
    - go install github.com/BaseMax/go-cogscore/cmd/go-cogscore@latest
    - go-cogscore -format ci
    - go-cogscore -format json > complexity.json
  artifacts:
    reports:
      complexity: complexity.json

Output Examples

Text Format

Cognitive Complexity Report
===========================

File: example.go (Total: 12)
  processData (line 10): 8 [MODERATE]
  validateInput (line 25): 4 [LOW]

Summary
-------
Total Files: 1
Total Functions: 2
Total Score: 12
Average Score: 6.00
Highest Score: 8 (processData in example.go)

Detailed Format

Detailed Cognitive Complexity Report
====================================

File: example.go
----------------

Function: processData (line 10)
  Cognitive Complexity: 8 [MODERATE]
  Complexity Details:
    Line 11: +1 for if statement
    Line 12: +2 for if statement (nesting: 1)
    Line 15: +2 for loop (nesting: 1)
    Line 16: +3 for if statement (nesting: 2)

JSON Format

{
  "Files": [
    {
      "Filename": "example.go",
      "Functions": [
        {
          "Name": "processData",
          "Score": 8,
          "Line": 10,
          "Column": 1,
          "Nesting": 0,
          "Details": [
            {
              "Line": 11,
              "Column": 2,
              "Reason": "if statement",
              "Increment": 1,
              "Nesting": 0
            }
          ]
        }
      ],
      "TotalScore": 8
    }
  ],
  "Summary": {
    "TotalFiles": 1,
    "TotalFunctions": 1,
    "TotalScore": 8,
    "AverageScore": 8.0
  }
}

CI Format

cognitive_complexity_total=12
cognitive_complexity_average=6.00
cognitive_complexity_highest=8
functions_high_risk=0
functions_very_high_risk=0
status=OK

Library Usage

You can also use go-cogscore as a library in your Go programs:

package main

import (
    "fmt"
    "os"
    
    "github.com/BaseMax/go-cogscore"
)

func main() {
    // Analyze a single file
    result, err := cogscore.AnalyzeFile("myfile.go")
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("Total complexity: %d\n", result.TotalScore)
    for _, fn := range result.Functions {
        fmt.Printf("%s: %d\n", fn.Name, fn.Score)
    }
    
    // Or analyze multiple files
    analyzer := cogscore.NewAnalyzer(cogscore.AnalyzerOptions{
        Paths: []string{"./pkg", "./cmd"},
        MinScore: 10,
    })
    
    report, err := analyzer.Analyze()
    if err != nil {
        panic(err)
    }
    
    report.WriteReport(os.Stdout, cogscore.FormatDetailed)
}

Why Cognitive Complexity?

Cyclomatic complexity counts the number of linearly independent paths through code, but this doesn't always correlate with understandability. Cognitive complexity addresses this by:

  1. Ignoring "shortcut" structures that don't increase understandability (like else)
  2. Penalizing nesting because nested code is harder to understand
  3. Recognizing that breaks in control flow make code harder to follow

This results in scores that better reflect actual code readability.

Future Enhancements

  • Support for analyzing other languages (JavaScript, Python, etc.)
  • Integration with popular linters (golangci-lint)
  • HTML report generation with syntax highlighting
  • Trend analysis over time
  • Configurable thresholds and rules

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

License

This project is licensed under the GPL-3.0 License - see the LICENSE file for details.

References

Author

Developed by BaseMax

About

A Go static analysis tool that computes cognitive complexity scores for Go source code. Unlike cyclomatic complexity, cognitive complexity measures how difficult code is to understand by humans, taking into account nesting depth and control flow interruptions. Measures cognitive complexity of source code.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages