ruby-maat 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.commitlintrc.json +44 -0
- data/.mailmap +3 -0
- data/.overcommit.yml +77 -0
- data/.release-please-config.json +33 -0
- data/.release-please-manifest.json +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +48 -0
- data/CHANGELOG.md +46 -0
- data/CI_CD_SETUP.md +180 -0
- data/CLAUDE.md +130 -0
- data/Dockerfile +40 -0
- data/README.md +444 -0
- data/README_RUBY.md +300 -0
- data/RELEASE_PLEASE_SETUP.md +198 -0
- data/RUBY_MAAT.md +227 -0
- data/Rakefile +12 -0
- data/doc/imgs/abs_churn_sample.png +0 -0
- data/doc/imgs/code_age_sample.png +0 -0
- data/doc/imgs/coupling_sample.png +0 -0
- data/doc/imgs/crime_cover.jpg +0 -0
- data/doc/imgs/tree_map_sample.png +0 -0
- data/doc/intro.md +3 -0
- data/exe/ruby-maat +6 -0
- data/lib/ruby_maat/analysis/authors.rb +47 -0
- data/lib/ruby_maat/analysis/base_analysis.rb +70 -0
- data/lib/ruby_maat/analysis/churn.rb +255 -0
- data/lib/ruby_maat/analysis/code_age.rb +53 -0
- data/lib/ruby_maat/analysis/commit_messages.rb +58 -0
- data/lib/ruby_maat/analysis/communication.rb +56 -0
- data/lib/ruby_maat/analysis/effort.rb +150 -0
- data/lib/ruby_maat/analysis/entities.rb +40 -0
- data/lib/ruby_maat/analysis/identity.rb +12 -0
- data/lib/ruby_maat/analysis/logical_coupling.rb +134 -0
- data/lib/ruby_maat/analysis/sum_of_coupling.rb +43 -0
- data/lib/ruby_maat/analysis/summary.rb +43 -0
- data/lib/ruby_maat/app.rb +143 -0
- data/lib/ruby_maat/change_record.rb +47 -0
- data/lib/ruby_maat/cli.rb +187 -0
- data/lib/ruby_maat/dataset.rb +205 -0
- data/lib/ruby_maat/groupers/layer_grouper.rb +67 -0
- data/lib/ruby_maat/groupers/team_mapper.rb +51 -0
- data/lib/ruby_maat/groupers/time_grouper.rb +70 -0
- data/lib/ruby_maat/output/csv_output.rb +65 -0
- data/lib/ruby_maat/parsers/base_parser.rb +63 -0
- data/lib/ruby_maat/parsers/git2_parser.rb +72 -0
- data/lib/ruby_maat/parsers/git_parser.rb +66 -0
- data/lib/ruby_maat/parsers/mercurial_parser.rb +64 -0
- data/lib/ruby_maat/parsers/perforce_parser.rb +77 -0
- data/lib/ruby_maat/parsers/svn_parser.rb +76 -0
- data/lib/ruby_maat/parsers/tfs_parser.rb +103 -0
- data/lib/ruby_maat/version.rb +5 -0
- data/lib/ruby_maat.rb +44 -0
- metadata +143 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: eb9765769289bffda3972bb5e38c0f447c57266d811e29751b08c4c4b2dfe7c1
|
4
|
+
data.tar.gz: d3f8a816d384207f2f47dc03b7d1d912ab073a874ba7e3c8508882bf367c058b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bb422d1872d9ee5016c08ada681798cb4113ee00dc6a33d357157a5fee4e3c7e319a9ac90ed9e43da6cde80a9136f373642b8e4a467ff3f6ee0326e4b9bac62c
|
7
|
+
data.tar.gz: c343edcaafdaeaca4b348dcc4b643e1bd69000034c3a7be4f7d14345755626eb7d7227276b3f4495ccf1d87891857ffb360735938bace0ccfe643ea0f0d82b4d
|
data/.commitlintrc.json
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
{
|
2
|
+
"extends": ["@commitlint/config-conventional"],
|
3
|
+
"rules": {
|
4
|
+
"type-enum": [
|
5
|
+
2,
|
6
|
+
"always",
|
7
|
+
[
|
8
|
+
"feat",
|
9
|
+
"fix",
|
10
|
+
"docs",
|
11
|
+
"style",
|
12
|
+
"refactor",
|
13
|
+
"perf",
|
14
|
+
"test",
|
15
|
+
"chore",
|
16
|
+
"ci",
|
17
|
+
"deps"
|
18
|
+
]
|
19
|
+
],
|
20
|
+
"scope-enum": [
|
21
|
+
2,
|
22
|
+
"always",
|
23
|
+
[
|
24
|
+
"analysis",
|
25
|
+
"parser",
|
26
|
+
"output",
|
27
|
+
"cli",
|
28
|
+
"dataset",
|
29
|
+
"grouper",
|
30
|
+
"core",
|
31
|
+
"deps",
|
32
|
+
"ci"
|
33
|
+
]
|
34
|
+
],
|
35
|
+
"scope-empty": [0, "never"],
|
36
|
+
"subject-case": [1, "always", "lower-case"],
|
37
|
+
"subject-empty": [1, "never"],
|
38
|
+
"subject-full-stop": [2, "never", "."],
|
39
|
+
"type-case": [1, "always", "lower-case"],
|
40
|
+
"type-empty": [1, "never"],
|
41
|
+
"header-max-length": [1, "always", 100],
|
42
|
+
"body-max-line-length": [1, "always", 100]
|
43
|
+
}
|
44
|
+
}
|
data/.mailmap
ADDED
data/.overcommit.yml
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Ruby Maat Overcommit Configuration
|
2
|
+
# See https://github.com/sds/overcommit for documentation
|
3
|
+
|
4
|
+
# Verify signatures of committed configuration
|
5
|
+
verify_signatures: false
|
6
|
+
|
7
|
+
# Gemfile and Gemfile.lock consistency check
|
8
|
+
gemfile: true
|
9
|
+
|
10
|
+
PreCommit:
|
11
|
+
# General file checks
|
12
|
+
TrailingWhitespace:
|
13
|
+
enabled: true
|
14
|
+
exclude:
|
15
|
+
- '**/*.md' # Markdown may intentionally have trailing spaces
|
16
|
+
|
17
|
+
EndOfFile:
|
18
|
+
enabled: true
|
19
|
+
|
20
|
+
YamlSyntax:
|
21
|
+
enabled: true
|
22
|
+
|
23
|
+
JsonSyntax:
|
24
|
+
enabled: true
|
25
|
+
|
26
|
+
# Ruby-specific checks
|
27
|
+
RuboCop:
|
28
|
+
enabled: true
|
29
|
+
command: ['bundle', 'exec', 'rubocop']
|
30
|
+
flags: ['--format', 'emacs', '--force-exclusion', '--display-cop-names']
|
31
|
+
on_warn: fail
|
32
|
+
|
33
|
+
# Use StandardRB instead of separate RuboCop config
|
34
|
+
StandardRb:
|
35
|
+
enabled: true
|
36
|
+
command: ['bundle', 'exec', 'standardrb']
|
37
|
+
flags: ['--no-fix']
|
38
|
+
on_warn: fail
|
39
|
+
|
40
|
+
# Run tests before committing
|
41
|
+
RSpec:
|
42
|
+
enabled: true
|
43
|
+
command: ['bundle', 'exec', 'rspec']
|
44
|
+
flags: ['--format', 'progress']
|
45
|
+
on_warn: fail
|
46
|
+
|
47
|
+
# Check for merge conflict markers
|
48
|
+
MergeConflicts:
|
49
|
+
enabled: true
|
50
|
+
|
51
|
+
# Check for large files (>500KB)
|
52
|
+
FileSize:
|
53
|
+
enabled: true
|
54
|
+
size_limit_bytes: 512000
|
55
|
+
|
56
|
+
CommitMsg:
|
57
|
+
# Validate conventional commit format using Ruby script
|
58
|
+
ConventionalCommit:
|
59
|
+
enabled: true
|
60
|
+
command: ['bin/validate-commit-msg']
|
61
|
+
flags: []
|
62
|
+
on_warn: warn
|
63
|
+
|
64
|
+
PostCommit:
|
65
|
+
# Optional: Show a success message
|
66
|
+
MessageDisplay:
|
67
|
+
enabled: false
|
68
|
+
|
69
|
+
PostMerge:
|
70
|
+
# Bundle install if Gemfile changes
|
71
|
+
BundleInstall:
|
72
|
+
enabled: true
|
73
|
+
|
74
|
+
PostRewrite:
|
75
|
+
# Bundle install if Gemfile changes during rebase
|
76
|
+
BundleInstall:
|
77
|
+
enabled: true
|
@@ -0,0 +1,33 @@
|
|
1
|
+
{
|
2
|
+
"packages": {
|
3
|
+
".": {
|
4
|
+
"release-type": "ruby",
|
5
|
+
"package-name": "ruby-maat",
|
6
|
+
"bump-minor-pre-major": true,
|
7
|
+
"bump-patch-for-minor-pre-major": true,
|
8
|
+
"draft": false,
|
9
|
+
"prerelease": false,
|
10
|
+
"version-file": "lib/ruby_maat/version.rb",
|
11
|
+
"changelog-sections": [
|
12
|
+
{"type": "feat", "section": "Features"},
|
13
|
+
{"type": "feature", "section": "Features"},
|
14
|
+
{"type": "fix", "section": "Bug Fixes"},
|
15
|
+
{"type": "perf", "section": "Performance Improvements"},
|
16
|
+
{"type": "deps", "section": "Dependencies"},
|
17
|
+
{"type": "ci", "section": "CI/CD"},
|
18
|
+
{"type": "docs", "section": "Documentation"},
|
19
|
+
{"type": "refactor", "section": "Refactoring", "hidden": false},
|
20
|
+
{"type": "test", "section": "Tests", "hidden": false},
|
21
|
+
{"type": "chore", "section": "Miscellaneous", "hidden": false},
|
22
|
+
{"type": "style", "section": "Code Style", "hidden": false}
|
23
|
+
],
|
24
|
+
"extra-files": [
|
25
|
+
{
|
26
|
+
"type": "generic",
|
27
|
+
"path": "ruby-maat.gemspec",
|
28
|
+
"glob": "spec.version = \"*\""
|
29
|
+
}
|
30
|
+
]
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# Inherit StandardRB configuration
|
2
|
+
inherit_gem:
|
3
|
+
standard: config/base.yml
|
4
|
+
|
5
|
+
plugins:
|
6
|
+
- rubocop-rake
|
7
|
+
- rubocop-rspec
|
8
|
+
|
9
|
+
AllCops:
|
10
|
+
TargetRubyVersion: 3.2
|
11
|
+
NewCops: enable
|
12
|
+
|
13
|
+
# Project-specific overrides
|
14
|
+
Metrics/MethodLength:
|
15
|
+
Max: 30
|
16
|
+
|
17
|
+
Metrics/ClassLength:
|
18
|
+
Max: 150
|
19
|
+
|
20
|
+
Metrics/ModuleLength:
|
21
|
+
Max: 150
|
22
|
+
|
23
|
+
Metrics/AbcSize:
|
24
|
+
Max: 20
|
25
|
+
|
26
|
+
Metrics/CyclomaticComplexity:
|
27
|
+
Max: 10
|
28
|
+
|
29
|
+
Metrics/PerceivedComplexity:
|
30
|
+
Max: 10
|
31
|
+
|
32
|
+
Style/Documentation:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
Metrics/BlockLength:
|
36
|
+
Exclude:
|
37
|
+
- "spec/**/*"
|
38
|
+
- "*.gemspec"
|
39
|
+
|
40
|
+
# RSpec-specific configurations
|
41
|
+
RSpec/ExampleLength:
|
42
|
+
Max: 30
|
43
|
+
|
44
|
+
RSpec/MultipleExpectations:
|
45
|
+
Max: 25
|
46
|
+
|
47
|
+
RSpec/NestedGroups:
|
48
|
+
Max: 5
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [1.0.0] - 2024-08-15
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Initial Ruby port of Code Maat
|
13
|
+
- Support for all VCS parsers: Git, Git2, SVN, Mercurial, Perforce, TFS
|
14
|
+
- Complete analysis suite:
|
15
|
+
- Authors analysis
|
16
|
+
- Entities analysis
|
17
|
+
- Logical coupling analysis
|
18
|
+
- Sum of coupling analysis
|
19
|
+
- Code churn analysis (absolute, by author, by entity, ownership)
|
20
|
+
- Effort analysis (by revisions, main developer, fragmentation)
|
21
|
+
- Communication analysis
|
22
|
+
- Code age analysis
|
23
|
+
- Commit messages analysis
|
24
|
+
- Summary analysis
|
25
|
+
- Data grouping capabilities:
|
26
|
+
- Layer grouping (architectural boundaries)
|
27
|
+
- Temporal grouping (time-based aggregation)
|
28
|
+
- Team mapping (author-to-team mapping)
|
29
|
+
- Command-line interface with full backward compatibility
|
30
|
+
- CSV output format
|
31
|
+
- Comprehensive RSpec test suite
|
32
|
+
- Ruby 3.2+ support
|
33
|
+
- Rover DataFrame integration for statistical computing
|
34
|
+
|
35
|
+
### Changed
|
36
|
+
|
37
|
+
- Ported from Clojure to Ruby while maintaining API compatibility
|
38
|
+
- Replaced Incanter with Rover DataFrame for statistical operations
|
39
|
+
- Converted from functional to object-oriented architecture
|
40
|
+
|
41
|
+
### Technical Notes
|
42
|
+
|
43
|
+
- Drop-in replacement for original Code Maat
|
44
|
+
- Identical command-line arguments and CSV output format
|
45
|
+
- Improved memory efficiency through Ruby's garbage collection
|
46
|
+
- Enhanced error handling and validation
|
data/CI_CD_SETUP.md
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
# CI/CD Setup Documentation
|
2
|
+
|
3
|
+
This document describes the GitHub Actions CI/CD pipeline for the Ruby Maat project.
|
4
|
+
|
5
|
+
## Workflows
|
6
|
+
|
7
|
+
### 1. CI Workflow (`.github/workflows/ci.yml`)
|
8
|
+
|
9
|
+
Runs on every push and pull request to main/master branches.
|
10
|
+
|
11
|
+
#### Jobs
|
12
|
+
|
13
|
+
- **Test**: Runs RSpec tests across multiple Ruby versions (3.2, 3.3, 3.4) and operating systems (Ubuntu, macOS, Windows)
|
14
|
+
- **Lint**: Runs RuboCop and StandardRB linting
|
15
|
+
- **Security**: Runs Bundler Audit for security vulnerabilities
|
16
|
+
- **Integration**: Tests CLI functionality with sample data
|
17
|
+
- **Build**: Builds the gem and uploads it as an artifact
|
18
|
+
|
19
|
+
#### Matrix Testing
|
20
|
+
|
21
|
+
- Ruby versions: 3.2, 3.3, 3.4
|
22
|
+
- Operating systems: Ubuntu (all versions), macOS (all versions), Windows (Ruby 3.3 only)
|
23
|
+
|
24
|
+
### 2. Release Please Workflow (`.github/workflows/publish.yml`)
|
25
|
+
|
26
|
+
Runs on every push to main/master branches and uses conventional commits to automate releases.
|
27
|
+
|
28
|
+
#### How it works
|
29
|
+
|
30
|
+
1. **Release Please** analyzes conventional commits since the last release
|
31
|
+
2. **Creates Release PRs** when releasable changes are detected
|
32
|
+
3. **Merging a Release PR** triggers the actual release:
|
33
|
+
- Updates version in `lib/ruby_maat/version.rb` and `ruby-maat.gemspec`
|
34
|
+
- Generates/updates `CHANGELOG.md` automatically
|
35
|
+
- Creates a GitHub release with the changelog
|
36
|
+
- Runs full test suite and linting
|
37
|
+
- Publishes gem to RubyGems.org
|
38
|
+
- Uploads gem artifact to the release
|
39
|
+
|
40
|
+
## Required Secrets
|
41
|
+
|
42
|
+
To enable automatic publishing to RubyGems, add these secrets to your GitHub repository:
|
43
|
+
|
44
|
+
### RubyGems API Key
|
45
|
+
|
46
|
+
1. Get your API key from [RubyGems.org](https://rubygems.org/profile/edit)
|
47
|
+
2. Add it as a repository secret named `RUBYGEMS_API_KEY`
|
48
|
+
|
49
|
+
### GitHub Token
|
50
|
+
|
51
|
+
- `GITHUB_TOKEN` is automatically provided by GitHub Actions
|
52
|
+
|
53
|
+
## Environment Setup
|
54
|
+
|
55
|
+
The publish workflow uses a GitHub Environment named `rubygems` for additional security. To set this up:
|
56
|
+
|
57
|
+
1. Go to your repository Settings → Environments
|
58
|
+
2. Create an environment named `rubygems`
|
59
|
+
3. Add protection rules (recommended):
|
60
|
+
- Required reviewers
|
61
|
+
- Deployment branches (limit to main/master)
|
62
|
+
|
63
|
+
## Dependabot
|
64
|
+
|
65
|
+
Dependabot is configured to:
|
66
|
+
|
67
|
+
- Check for Ruby gem updates weekly (Sundays at 09:00)
|
68
|
+
- Check for GitHub Actions updates weekly
|
69
|
+
- Create PRs with appropriate labels and assignees
|
70
|
+
|
71
|
+
## Coverage Reporting
|
72
|
+
|
73
|
+
SimpleCov is configured to:
|
74
|
+
|
75
|
+
- Generate coverage reports for all test runs
|
76
|
+
- Group coverage by component (Analyses, Parsers, Output)
|
77
|
+
- Require minimum 50% coverage (adjustable in `spec/spec_helper.rb`)
|
78
|
+
- Upload coverage to Codecov (when CODECOV_TOKEN is set)
|
79
|
+
|
80
|
+
## Security Scanning
|
81
|
+
|
82
|
+
The CI pipeline includes:
|
83
|
+
|
84
|
+
- Bundler Audit for dependency vulnerabilities
|
85
|
+
- RuboCop security cops
|
86
|
+
- Dependabot security updates
|
87
|
+
|
88
|
+
## Local Development
|
89
|
+
|
90
|
+
To run the same checks locally:
|
91
|
+
|
92
|
+
```bash
|
93
|
+
# Install dependencies
|
94
|
+
bundle install
|
95
|
+
|
96
|
+
# Run tests with coverage
|
97
|
+
bundle exec rspec
|
98
|
+
|
99
|
+
# Run linting
|
100
|
+
bundle exec rubocop
|
101
|
+
bundle exec standardrb
|
102
|
+
|
103
|
+
# Run security audit
|
104
|
+
bundle exec bundler-audit
|
105
|
+
|
106
|
+
# Build gem
|
107
|
+
gem build ruby-maat.gemspec
|
108
|
+
```
|
109
|
+
|
110
|
+
## Triggering a Release
|
111
|
+
|
112
|
+
Release Please uses **conventional commits** to automatically determine version bumps and generate changelogs:
|
113
|
+
|
114
|
+
### Conventional Commit Format
|
115
|
+
|
116
|
+
```
|
117
|
+
<type>(<scope>): <description>
|
118
|
+
|
119
|
+
[optional body]
|
120
|
+
|
121
|
+
[optional footer(s)]
|
122
|
+
```
|
123
|
+
|
124
|
+
### Commit Types
|
125
|
+
|
126
|
+
- `feat:` - New features (triggers minor version bump)
|
127
|
+
- `fix:` - Bug fixes (triggers patch version bump)
|
128
|
+
- `feat!:` or `BREAKING CHANGE:` - Breaking changes (triggers major version bump)
|
129
|
+
- `docs:`, `style:`, `refactor:`, `test:`, `chore:`, `ci:`, `deps:` - No version bump
|
130
|
+
|
131
|
+
### Release Process
|
132
|
+
|
133
|
+
1. **Make commits** using conventional commit format
|
134
|
+
2. **Push to main/master** - Release Please analyzes commits
|
135
|
+
3. **Review Release PR** - Automatically created when releasable changes exist
|
136
|
+
4. **Merge Release PR** - Triggers automatic release and publication
|
137
|
+
|
138
|
+
### Example Commits
|
139
|
+
|
140
|
+
```bash
|
141
|
+
git commit -m "feat(analysis): add new coupling algorithm"
|
142
|
+
git commit -m "fix(parser): handle empty git logs correctly"
|
143
|
+
git commit -m "docs: update CLI usage examples"
|
144
|
+
git commit -m "feat!: change CLI argument format" # breaking change
|
145
|
+
```
|
146
|
+
|
147
|
+
### Set up commit message template
|
148
|
+
|
149
|
+
```bash
|
150
|
+
git config commit.template .gitmessage
|
151
|
+
```
|
152
|
+
|
153
|
+
## Troubleshooting
|
154
|
+
|
155
|
+
### Gem Push Fails
|
156
|
+
|
157
|
+
- Verify `RUBYGEMS_API_KEY` secret is set correctly
|
158
|
+
- Ensure you have push permissions to the gem on RubyGems.org
|
159
|
+
- Check that the gem version hasn't been published already
|
160
|
+
|
161
|
+
### Test Failures
|
162
|
+
|
163
|
+
- Check the CI logs for specific failure reasons
|
164
|
+
- Ensure all dependencies are properly specified
|
165
|
+
- Test matrix may reveal OS or Ruby version specific issues
|
166
|
+
|
167
|
+
### Coverage Too Low
|
168
|
+
|
169
|
+
- Add tests for uncovered code
|
170
|
+
- Adjust minimum coverage threshold in `spec/spec_helper.rb` if needed
|
171
|
+
- Check coverage report in the `coverage/` directory after running tests
|
172
|
+
|
173
|
+
## Badge Status
|
174
|
+
|
175
|
+
Add these badges to your README to show CI status:
|
176
|
+
|
177
|
+
```markdown
|
178
|
+

|
179
|
+

|
180
|
+
```
|
data/CLAUDE.md
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
# CLAUDE.md
|
2
|
+
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
4
|
+
|
5
|
+
## Project Overview
|
6
|
+
|
7
|
+
Code Maat is a command-line tool for mining and analyzing data from version control systems (VCS). It extracts insights about code evolution, developer patterns, logical coupling, and code quality metrics from Git, SVN, Mercurial, Perforce, and TFS repositories.
|
8
|
+
|
9
|
+
## Build and Development Commands
|
10
|
+
|
11
|
+
### Building the Project
|
12
|
+
|
13
|
+
```bash
|
14
|
+
# Build standalone JAR (primary method)
|
15
|
+
lein uberjar
|
16
|
+
|
17
|
+
# Run directly via Leiningen (for development)
|
18
|
+
lein run -l logfile.log -c <vcs>
|
19
|
+
|
20
|
+
# Build Docker image
|
21
|
+
docker build -t code-maat-app .
|
22
|
+
|
23
|
+
# Run tests
|
24
|
+
lein test
|
25
|
+
```
|
26
|
+
|
27
|
+
### Running Code Maat
|
28
|
+
|
29
|
+
```bash
|
30
|
+
# Using standalone JAR
|
31
|
+
java -jar code-maat-1.0.5-SNAPSHOT-standalone.jar -l logfile.log -c <vcs>
|
32
|
+
|
33
|
+
# Using Docker
|
34
|
+
docker run -v /host/path:/data -it code-maat-app -l /data/logfile.log -c <vcs>
|
35
|
+
|
36
|
+
# Show help and all available analyses
|
37
|
+
java -jar code-maat-1.0.5-SNAPSHOT-standalone.jar -h
|
38
|
+
```
|
39
|
+
|
40
|
+
### Memory Configuration
|
41
|
+
|
42
|
+
Code Maat is memory-intensive. The project.clj includes these JVM options:
|
43
|
+
|
44
|
+
- `-Xmx4g` (4GB heap)
|
45
|
+
- `-Djava.awt.headless=true` (suppress AWT frames)
|
46
|
+
- `-Xss512M` (512MB stack size)
|
47
|
+
|
48
|
+
## Architecture Overview
|
49
|
+
|
50
|
+
### Core Components
|
51
|
+
|
52
|
+
1. **Command Line Interface** (`src/code_maat/cmd_line.clj`)
|
53
|
+
- Entry point and argument parsing
|
54
|
+
- Uses clojure.tools.cli for option handling
|
55
|
+
|
56
|
+
2. **Application Core** (`src/code_maat/app/app.clj`)
|
57
|
+
- Main orchestration logic following pipeline pattern:
|
58
|
+
- Input → Parsers → Layer Mapping → Incanter Datasets → Analysis → Output
|
59
|
+
- Contains registry of all supported analyses
|
60
|
+
- Handles VCS parser selection and error recovery
|
61
|
+
|
62
|
+
3. **VCS Parsers** (`src/code_maat/parsers/`)
|
63
|
+
- Modular parsers for different VCS systems
|
64
|
+
- `git2.clj` - preferred Git parser (faster, more tolerant)
|
65
|
+
- `git.clj` - legacy Git parser (maintained for backward compatibility)
|
66
|
+
- `svn.clj`, `mercurial.clj`, `perforce.clj`, `tfs.clj` - other VCS support
|
67
|
+
|
68
|
+
4. **Analysis Modules** (`src/code_maat/analysis/`)
|
69
|
+
- Independent analysis implementations
|
70
|
+
- Each returns Incanter datasets
|
71
|
+
- Key analyses: authors, coupling, churn, code-age, communication, effort
|
72
|
+
|
73
|
+
5. **Data Processing** (`src/code_maat/app/`)
|
74
|
+
- `grouper.clj` - maps files to architectural layers
|
75
|
+
- `time_based_grouper.clj` - temporal aggregation
|
76
|
+
- `team_mapper.clj` - maps authors to teams
|
77
|
+
|
78
|
+
6. **Output** (`src/code_maat/output/`)
|
79
|
+
- CSV output formatting
|
80
|
+
- Filtering and row limiting
|
81
|
+
|
82
|
+
### Supported Analyses
|
83
|
+
|
84
|
+
Available via the `-a` parameter (see `supported-analysis` map in `app.clj:55`):
|
85
|
+
|
86
|
+
- `authors` - developer count per module
|
87
|
+
- `coupling` - logical coupling between modules
|
88
|
+
- `revisions` - revision count per entity
|
89
|
+
- `churn` - code churn metrics (abs-churn, author-churn, entity-churn)
|
90
|
+
- `age` - code age analysis
|
91
|
+
- `communication` - developer communication patterns
|
92
|
+
- `summary` - project overview statistics
|
93
|
+
- `effort` - developer effort distribution
|
94
|
+
|
95
|
+
### Data Flow
|
96
|
+
|
97
|
+
1. Parse VCS log files into modification records
|
98
|
+
2. Optional aggregation by architectural boundaries (grouping files)
|
99
|
+
3. Optional temporal aggregation (group commits by time period)
|
100
|
+
4. Optional team mapping (map individual authors to teams)
|
101
|
+
5. Convert to Incanter dataset
|
102
|
+
6. Run analysis
|
103
|
+
7. Output results as CSV
|
104
|
+
|
105
|
+
### Key Dependencies
|
106
|
+
|
107
|
+
- Clojure 1.8.0
|
108
|
+
- Incanter (statistical computing)
|
109
|
+
- clojure.tools.cli (command line parsing)
|
110
|
+
- clj-time (date/time handling)
|
111
|
+
- instaparse (parsing DSL)
|
112
|
+
|
113
|
+
## Testing
|
114
|
+
|
115
|
+
Tests are located in `test/code_maat/` and follow the source structure. Key test categories:
|
116
|
+
|
117
|
+
- Unit tests for individual analysis modules
|
118
|
+
- End-to-end scenario tests with sample VCS data
|
119
|
+
- Parser tests for different VCS formats
|
120
|
+
|
121
|
+
Run all tests with `lein test`.
|
122
|
+
|
123
|
+
## Development Notes
|
124
|
+
|
125
|
+
- The codebase follows functional programming principles
|
126
|
+
- All analysis modules are independent and composable
|
127
|
+
- Parsers return sequences of maps representing modifications
|
128
|
+
- Heavy use of Incanter for dataset operations
|
129
|
+
- Error handling with recovery points for user-friendly messages
|
130
|
+
- Memory usage can be high for large repositories - consider date filtering
|
data/Dockerfile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
FROM ruby:3.3-alpine
|
2
|
+
|
3
|
+
VOLUME /data
|
4
|
+
LABEL description="Ruby Maat - A Ruby port of Code Maat for mining VCS data"
|
5
|
+
|
6
|
+
ARG dest=/usr/src/ruby-maat
|
7
|
+
|
8
|
+
# Install build dependencies
|
9
|
+
RUN apk add --no-cache \
|
10
|
+
build-base \
|
11
|
+
git
|
12
|
+
|
13
|
+
# Set working directory
|
14
|
+
RUN mkdir -p $dest
|
15
|
+
WORKDIR $dest
|
16
|
+
|
17
|
+
# Copy gem files first for better caching
|
18
|
+
COPY ruby-maat.gemspec Gemfile Gemfile.lock $dest/
|
19
|
+
COPY lib/ruby_maat/version.rb $dest/lib/ruby_maat/
|
20
|
+
|
21
|
+
# Install dependencies
|
22
|
+
RUN bundle install --deployment --without development test
|
23
|
+
|
24
|
+
# Copy the rest of the application
|
25
|
+
COPY . $dest
|
26
|
+
|
27
|
+
# Build and install the gem
|
28
|
+
RUN gem build ruby-maat.gemspec && \
|
29
|
+
gem install ruby-maat-*.gem && \
|
30
|
+
rm -rf $dest
|
31
|
+
|
32
|
+
# Create a non-root user
|
33
|
+
RUN adduser -D -s /bin/sh ruby-maat
|
34
|
+
USER ruby-maat
|
35
|
+
|
36
|
+
# Set working directory to /data for user convenience
|
37
|
+
WORKDIR /data
|
38
|
+
|
39
|
+
ENTRYPOINT ["ruby-maat"]
|
40
|
+
CMD ["--help"]
|