A comprehensive static analysis tool for Clojure code, inspired by PHPMetrics. Calculates important code quality metrics to help with development and maintenance of Clojure projects.
- Complete static analysis based on clj-kondo
- Multiple quality metrics including cyclomatic complexity, Halstead metrics, and maintainability index
- Structured JSON output for easy integration with other tools
- Simple command-line interface
- Recursive directory analysis
- Detailed per-file reports and system summary
- n1: Number of unique operators
- n2: Number of unique operands
- N1: Total number of operators
- N2: Total number of operands
- Vocabulary (n): n1 + n2
- Length (N): N1 + N2
- Volume: N * logβ(n)
- Difficulty: (n1/2) * (N2/n2)
- Effort: Difficulty * Volume
Measures the number of linearly independent paths through the code. Counts decision points such as:
- Conditionals:
if,when,cond,case - Loops:
loop,while,doseq,for - Exception handling:
try/catch - Logical operators:
and,or
Composite metric that indicates how easy it is to maintain the code:
- MI = 171 - 5.2 * ln(Halstead Volume) - 0.23 * (Cyclomatic Complexity) - 16.2 * ln(Lines of Code)
- Includes bonus based on comment density
- Scale from 0-100 (higher is better)
- Total lines: All lines in the file
- Physical lines: Non-empty lines
- Logical lines: Lines with actual code (excluding comments)
- Comment lines: Lines containing only comments
- Comment density: Percentage of lines with comments
- Leiningen 2.0 or higher
- Java 8 or higher
git clone https://github.com/your-username/clojure-metrics.git
cd clojure-metricslein depslein run -- -p src/lein run -- -p src/core.cljlein run -- -hlein uberjar
java -jar target/uberjar/clojure-metrics-*-standalone.jar -p src/The tool produces a comprehensive JSON structure with system summary and individual file metrics:
{
"system-summary": {
"total-files": 5,
"length": {
"cloc": 250,
"loc": 200,
"lloc": 180,
"comment-density": 20.0
},
"halstead": {
"n1": 25,
"n2": 45,
"volume": 1250.5,
"difficulty": 12.5,
"effort": 15631.25
},
"cyclomatic-complexity": 45,
"average-cyclomatic-complexity": 9.0,
"maintainability": {
"index": 75.2,
"classification": "good",
"recommendations": ["Consider refactoring functions with high complexity"]
}
},
"files": [...]
}- 1-10: Simple, low risk
- 11-20: Moderate, medium risk
- 21-50: Complex, high risk
- >50: Very complex, very high risk
- 85-100: Very high maintainability (excellent)
- 70-85: High maintainability (good)
- 50-70: Moderate maintainability
- 25-50: Low maintainability (poor)
- 0-25: Very low maintainability (critical)
lein testlein test clojure-metrics.unit.logic.halstead-testlein cljfmt checksrc/
βββ clojure_metrics/
β βββ core.clj # Main entry point
β βββ controller/
β β βββ file_analyzer.clj # Analysis controller
β βββ logic/ # Metrics calculation logic
β β βββ cyclomatic.clj
β β βββ halstead.clj
β β βββ loc.clj
β β βββ maintainability.clj
β βββ components/
β βββ konjo_analysis.clj # clj-kondo integration
test/
βββ clojure_metrics/
β βββ unit/ # Unit tests
β βββ integration/ # Integration tests
β βββ resources/ # Test fixture files
Contributions are welcome! To contribute:
- Fork the project
- Create a feature branch (
git checkout -b feature/new-feature) - Commit your changes (
git commit -am 'Add new feature') - Push to the branch (
git push origin feature/new-feature) - Open a Pull Request
- Keep code well documented
- Add tests for new features
- Follow Clojure code conventions
- Update documentation when necessary
Found a bug? Please open an issue with:
- Detailed problem description
- Steps to reproduce
- Clojure and Java version
- Sample code (if applicable)
- Support for incremental analysis
- HTML reports
- CI/CD integration
- Additional metrics (coupling, cohesion)
- Interactive web dashboard
- Editor plugins (VS Code, IntelliJ)
- Cyclomatic Complexity
- Halstead Complexity Measures
- Maintainability Index
- clj-kondo - Static analysis tool for Clojure
This project is licensed under the Eclipse Public License 2.0 - see the LICENSE file for details.
- clj-kondo for excellent syntactic analysis
- PHPMetrics for inspiration
- Clojure community for feedback and support
Built with β€οΈ for the Clojure community