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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.commitlintrc.json +44 -0
  3. data/.mailmap +3 -0
  4. data/.overcommit.yml +77 -0
  5. data/.release-please-config.json +33 -0
  6. data/.release-please-manifest.json +3 -0
  7. data/.rspec +3 -0
  8. data/.rubocop.yml +48 -0
  9. data/CHANGELOG.md +46 -0
  10. data/CI_CD_SETUP.md +180 -0
  11. data/CLAUDE.md +130 -0
  12. data/Dockerfile +40 -0
  13. data/README.md +444 -0
  14. data/README_RUBY.md +300 -0
  15. data/RELEASE_PLEASE_SETUP.md +198 -0
  16. data/RUBY_MAAT.md +227 -0
  17. data/Rakefile +12 -0
  18. data/doc/imgs/abs_churn_sample.png +0 -0
  19. data/doc/imgs/code_age_sample.png +0 -0
  20. data/doc/imgs/coupling_sample.png +0 -0
  21. data/doc/imgs/crime_cover.jpg +0 -0
  22. data/doc/imgs/tree_map_sample.png +0 -0
  23. data/doc/intro.md +3 -0
  24. data/exe/ruby-maat +6 -0
  25. data/lib/ruby_maat/analysis/authors.rb +47 -0
  26. data/lib/ruby_maat/analysis/base_analysis.rb +70 -0
  27. data/lib/ruby_maat/analysis/churn.rb +255 -0
  28. data/lib/ruby_maat/analysis/code_age.rb +53 -0
  29. data/lib/ruby_maat/analysis/commit_messages.rb +58 -0
  30. data/lib/ruby_maat/analysis/communication.rb +56 -0
  31. data/lib/ruby_maat/analysis/effort.rb +150 -0
  32. data/lib/ruby_maat/analysis/entities.rb +40 -0
  33. data/lib/ruby_maat/analysis/identity.rb +12 -0
  34. data/lib/ruby_maat/analysis/logical_coupling.rb +134 -0
  35. data/lib/ruby_maat/analysis/sum_of_coupling.rb +43 -0
  36. data/lib/ruby_maat/analysis/summary.rb +43 -0
  37. data/lib/ruby_maat/app.rb +143 -0
  38. data/lib/ruby_maat/change_record.rb +47 -0
  39. data/lib/ruby_maat/cli.rb +187 -0
  40. data/lib/ruby_maat/dataset.rb +205 -0
  41. data/lib/ruby_maat/groupers/layer_grouper.rb +67 -0
  42. data/lib/ruby_maat/groupers/team_mapper.rb +51 -0
  43. data/lib/ruby_maat/groupers/time_grouper.rb +70 -0
  44. data/lib/ruby_maat/output/csv_output.rb +65 -0
  45. data/lib/ruby_maat/parsers/base_parser.rb +63 -0
  46. data/lib/ruby_maat/parsers/git2_parser.rb +72 -0
  47. data/lib/ruby_maat/parsers/git_parser.rb +66 -0
  48. data/lib/ruby_maat/parsers/mercurial_parser.rb +64 -0
  49. data/lib/ruby_maat/parsers/perforce_parser.rb +77 -0
  50. data/lib/ruby_maat/parsers/svn_parser.rb +76 -0
  51. data/lib/ruby_maat/parsers/tfs_parser.rb +103 -0
  52. data/lib/ruby_maat/version.rb +5 -0
  53. data/lib/ruby_maat.rb +44 -0
  54. 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
@@ -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
@@ -0,0 +1,3 @@
1
+ Adam Tornhill <adam@adamtornhill.com> Adam Petersen <adam@adampetersen.se>
2
+ robertc <robert@logicalchaos.org> LogicalChaos <robert@logicalchaos.org>
3
+ Adam Tornhill <adam@adamtornhill.com> Adam Petersen Tornhill <adam@adampetersen.se>
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
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "1.0.0"
3
+ }
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --color
3
+ --format documentation
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
+ ![CI](https://github.com/viamin/ruby-maat/workflows/CI/badge.svg)
179
+ ![Gem Version](https://badge.fury.io/rb/ruby-maat.svg)
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"]