turbulence 1.2.4 → 1.4.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 (37) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +51 -0
  3. data/CHANGELOG.md +227 -0
  4. data/Gemfile.lock +47 -24
  5. data/LICENSE.txt +7 -0
  6. data/README.md +100 -31
  7. data/bin/bule +1 -1
  8. data/docs/scatter-plot.png +0 -0
  9. data/docs/treemap.png +0 -0
  10. data/lib/turbulence/calculators/churn.rb +3 -1
  11. data/lib/turbulence/calculators/complexity.rb +4 -16
  12. data/lib/turbulence/cli_parser.rb +12 -1
  13. data/lib/turbulence/command_line_interface.rb +28 -3
  14. data/lib/turbulence/configuration.rb +10 -6
  15. data/lib/turbulence/generators/scatterplot.rb +10 -4
  16. data/lib/turbulence/generators/treemap.rb +14 -10
  17. data/lib/turbulence/scm/git.rb +1 -1
  18. data/lib/turbulence/version.rb +1 -1
  19. data/lib/turbulence.rb +1 -1
  20. data/spec/turbulence/calculators/churn_spec.rb +50 -62
  21. data/spec/turbulence/calculators/complexity_spec.rb +2 -5
  22. data/spec/turbulence/cli_parser_spec.rb +16 -6
  23. data/spec/turbulence/command_line_interface_spec.rb +59 -7
  24. data/spec/turbulence/configuration_spec.rb +11 -5
  25. data/spec/turbulence/generators/scatter_plot_spec.rb +49 -44
  26. data/spec/turbulence/generators/treemap_spec.rb +7 -7
  27. data/spec/turbulence/scm/git_spec.rb +7 -6
  28. data/spec/turbulence/scm/perforce_spec.rb +44 -40
  29. data/spec/turbulence/turbulence_spec.rb +4 -4
  30. data/template/highcharts-heatmap.js +23 -0
  31. data/template/highcharts-treemap.js +11 -0
  32. data/template/highcharts.js +28 -162
  33. data/template/treemap.html +121 -27
  34. data/template/turbulence.html +34 -12
  35. data/turbulence.gemspec +13 -9
  36. metadata +61 -29
  37. data/.travis.yml +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1491a1041aa988c3e1b1ba0a9c285b85f61dd2fe
4
- data.tar.gz: 52fc99ed010da6d2b62aaf794cb8ccfe42bf9079
2
+ SHA256:
3
+ metadata.gz: a4609ac63b60c3001386fdaa357bf0509eaeba83ef7f4d619ebd2988b185adad
4
+ data.tar.gz: cee8c714b82bc110628f9b4dd9bd4cb77e698cfaf645491dfc1e0a65814fdaec
5
5
  SHA512:
6
- metadata.gz: da0688c4eac40019c589daa4df804aa29f71906b7706b92cf1b0237930ebb5324c547fd631a93cc28918c323a20ca5f8feae055bd4b6a5c552cce6f7088610fb
7
- data.tar.gz: df3db44e2fad25424ee559ff82648a41f625bfdb90acbad83835af9f9d814d76757457183f199f014b248957c050bda4318104fb4c252b2b622b5a66856b6830
6
+ metadata.gz: 57c942825c289ad779f0c38b46daf09d064f1ef91a66d8dad86115492295c29e1e15a8c41a0da50c1bb45dd5f5224219280a74968fcbb1d501c57124dd1addcf
7
+ data.tar.gz: ddc95058bb0482944b777c1293fe3dcea9c79accee2de809105d1ca2f49510f0b6f94f6e82568a0e57cbd4b5057dea735f7ed56ef790b4661dcfc135d9fa3196
@@ -0,0 +1,51 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ ruby-version:
17
+ - '3.0'
18
+ - '3.1'
19
+ - '3.2'
20
+ - '3.3'
21
+ - 'head'
22
+
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+
26
+ - name: Remove Gemfile.lock for fresh resolution
27
+ run: rm -f Gemfile.lock
28
+
29
+ - name: Set up Ruby ${{ matrix.ruby-version }}
30
+ uses: ruby/setup-ruby@v1
31
+ with:
32
+ ruby-version: ${{ matrix.ruby-version }}
33
+ bundler-cache: true
34
+
35
+ - name: Run tests
36
+ run: bundle exec rspec
37
+
38
+ lint:
39
+ runs-on: ubuntu-latest
40
+
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+
44
+ - name: Set up Ruby
45
+ uses: ruby/setup-ruby@v1
46
+ with:
47
+ ruby-version: '3.3'
48
+ bundler-cache: true
49
+
50
+ - name: Check gemspec
51
+ run: gem build turbulence.gemspec
data/CHANGELOG.md ADDED
@@ -0,0 +1,227 @@
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
+ ## [Unreleased]
9
+
10
+ ## [1.4.0] - 2026-07-08
11
+
12
+ ### Added
13
+ - `--json` flag to output raw metrics as JSON to stdout for scripting and CI integration ([#68])
14
+ - Legend and usage tips to treemap view explaining size=churn, color=complexity ([#64])
15
+ - Title and usage tips to scatter plot view ([#65])
16
+
17
+ ### Changed
18
+ - Update Highcharts from v2.1.3 to v13.0.0, fixing tooltip detection at chart edges ([#65])
19
+ - Replace Google Charts with Highcharts for treemap visualization, removing CDN dependency ([#66])
20
+
21
+ ### Fixed
22
+ - Scatter plot tooltips now work reliably for all data points, including edge cases ([#65])
23
+
24
+ ## [1.3.0] - 2026-06-13
25
+
26
+ ### Added
27
+ - `--output DIR` option to specify custom output directory for reports ([#39])
28
+ - `--no-open` flag to skip automatic browser launch, useful for CI/headless environments ([#42])
29
+ - GitHub Actions CI testing Ruby 3.0, 3.1, 3.2, 3.3, and head ([#52])
30
+ - CI status badge and RubyGems version badge in README ([#52])
31
+ - LICENSE.txt file (MIT License)
32
+ - Screenshots of scatter plot and treemap visualizations in README ([#58])
33
+
34
+ ### Changed
35
+ - **Ruby 3.0+ / Ruby 4.0 compatibility** ([#50])
36
+ - Update minimum Ruby version to 3.0
37
+ - Add `racc` as runtime dependency (removed from stdlib in Ruby 3.3+)
38
+ - Remove obsolete `Ruby19Parser`/`Flog19` workaround classes
39
+ - Remove unused `ostruct` require
40
+ - Fix git repo detection with case-insensitive regex
41
+ - Update RSpec from 2.x to 3.x and modernize all specs ([#50])
42
+ - Modernize README with table format, examples, and requirements ([#56])
43
+ - Drop defunct `rubyforge_project` property from gemspec ([#46])
44
+ - Update referenced URL in gemspec description ([#44])
45
+ - Use symbols instead of class names as metrics_hash keys ([#34])
46
+
47
+ ### Removed
48
+ - Travis CI configuration (replaced by GitHub Actions) ([#56])
49
+
50
+ ### Fixed
51
+ - Fix typo: "cummulative" → "cumulative" ([#54])
52
+
53
+ ## [1.2.4] - 2014-10-15
54
+
55
+ ### Fixed
56
+ - Fix missing stats bug where metrics hash keys were inconsistent ([#33])
57
+ - Fix missing file bug by creating Calculator::Churn instance to access config ([#32])
58
+
59
+ ### Changed
60
+ - Major refactoring to extract configuration into dedicated class ([#27])
61
+ - Use instances instead of classes for calculators
62
+ - Move CLI option parsing to separate file
63
+ - Improved code organization and reduced complexity
64
+
65
+ ## [1.2.3] - 2014-09-22
66
+
67
+ ### Fixed
68
+ - Revert autogenerated bin changes that caused "stack level too deep" errors for many users ([#30], [#29])
69
+
70
+ ## [1.2.2] - 2014-09-18
71
+
72
+ ### Fixed
73
+ - Fix leaky specs by stubbing ENV settings ([#26])
74
+ - Remove deprecation notices
75
+
76
+ ### Changed
77
+ - Update RSpec dependency
78
+ - Inject output to CLI for cleaner spec output ([#24])
79
+
80
+ ## [1.2.0] - 2014-03-15
81
+
82
+ ### Fixed
83
+ - Fix file opening on Windows by using `file:///` protocol ([#21])
84
+
85
+ ### Added
86
+ - Treemap visualization option (`--treemap` flag) ([#18])
87
+ - Generator classes for scatter plot and treemap visualizations
88
+
89
+ ### Changed
90
+ - Move scatter plot code into dedicated generator class
91
+ - Update flog and launchy gem versions
92
+
93
+ ## [1.1.0] - 2013-08-20
94
+
95
+ ### Fixed
96
+ - Fix parsing of Ruby 1.9 style hashes ([#14])
97
+ - Fix syntax errors under Ruby 1.8.7-352 ([#16])
98
+
99
+ ### Added
100
+ - Additional standard Rails folders for file filtering
101
+ - Support for both Ruby 1.8 and 1.9 syntax
102
+
103
+ ### Changed
104
+ - Update gem dependencies
105
+
106
+ ## [1.0.0] - 2013-03-10
107
+
108
+ ### Added
109
+ - Perforce SCM support with `--scm p4` option ([#11])
110
+ - `--exclude` feature to filter out files matching a pattern ([#13])
111
+ - Commit range option (`--churn-range`) for analyzing specific ranges
112
+ - Mean churn calculation option (`--churn-mean`)
113
+
114
+ ### Changed
115
+ - Extract Git-specific code to separate SCM class
116
+ - Use .gemspec for gem dependencies
117
+ - Upgrade to latest Launchy
118
+ - Allow use of more recent json gems ([#12])
119
+
120
+ ### Fixed
121
+ - Reduced code complexity through refactoring
122
+
123
+ ## [0.0.9] - 2012-11-15
124
+
125
+ ### Changed
126
+ - Refactored metrics loop and output display
127
+ - Move complexity calculation into Calculator::Complexity
128
+ - Move churn work into Calculators::Churn
129
+ - Created CLI class for better organization
130
+
131
+ ### Fixed
132
+ - Bug in churn calculation
133
+ - Filter files to Rails directories
134
+
135
+ ## [0.0.8] - 2012-10-20
136
+
137
+ ### Added
138
+ - Name mangler for anonymization of file names
139
+ - Command line options support
140
+
141
+ ### Changed
142
+ - Lines changed instead of commits for churn metric
143
+ - Total flog score instead of average
144
+ - General code cleanup and refactoring
145
+
146
+ ## [0.0.6] - 2012-09-15
147
+
148
+ ### Added
149
+ - Filename to graph tooltip
150
+ - Churn and complexity to tooltip
151
+
152
+ ### Fixed
153
+ - Exclude nonexistent files from analysis
154
+
155
+ ## [0.0.5] - 2012-08-20
156
+
157
+ ### Added
158
+ - Highcharts integration for visualization
159
+ - Separate series by directory (up to two levels)
160
+
161
+ ### Changed
162
+ - Renamed project from "chuggle" to "turbulence"
163
+
164
+ ## [0.0.4] - 2012-07-15
165
+
166
+ ### Added
167
+ - Basic graphing functionality
168
+ - Gemfile and gemspec
169
+
170
+ ## [0.0.3] - 2012-06-20
171
+
172
+ ### Added
173
+ - Initial working version
174
+ - Churn and flog scoring
175
+ - Basic command line interface
176
+
177
+ ## [0.0.2] - 2012-06-10
178
+
179
+ ### Added
180
+ - Initial gem structure
181
+ - README with basic documentation
182
+
183
+ [Unreleased]: https://github.com/chad/turbulence/compare/1.4.0...HEAD
184
+ [1.4.0]: https://github.com/chad/turbulence/compare/1.3.0...1.4.0
185
+ [1.3.0]: https://github.com/chad/turbulence/compare/1.2.4...1.3.0
186
+ [1.2.4]: https://github.com/chad/turbulence/compare/1.2.3...1.2.4
187
+ [1.2.3]: https://github.com/chad/turbulence/compare/1.2.2...1.2.3
188
+ [1.2.2]: https://github.com/chad/turbulence/compare/1.2.0...1.2.2
189
+ [1.2.0]: https://github.com/chad/turbulence/compare/1.1.0...1.2.0
190
+ [1.1.0]: https://github.com/chad/turbulence/compare/v1.0.0...1.1.0
191
+ [1.0.0]: https://github.com/chad/turbulence/compare/0.0.9...v1.0.0
192
+ [0.0.9]: https://github.com/chad/turbulence/compare/0.0.8...0.0.9
193
+ [0.0.8]: https://github.com/chad/turbulence/compare/0.0.6...0.0.8
194
+ [0.0.6]: https://github.com/chad/turbulence/compare/0.0.5...0.0.6
195
+ [0.0.5]: https://github.com/chad/turbulence/compare/0.0.4...0.0.5
196
+ [0.0.4]: https://github.com/chad/turbulence/compare/0.0.3...0.0.4
197
+ [0.0.3]: https://github.com/chad/turbulence/compare/0.0.2...0.0.3
198
+ [0.0.2]: https://github.com/chad/turbulence/releases/tag/0.0.2
199
+
200
+ [#68]: https://github.com/chad/turbulence/pull/68
201
+ [#66]: https://github.com/chad/turbulence/pull/66
202
+ [#65]: https://github.com/chad/turbulence/pull/65
203
+ [#64]: https://github.com/chad/turbulence/pull/64
204
+ [#58]: https://github.com/chad/turbulence/pull/58
205
+ [#56]: https://github.com/chad/turbulence/pull/56
206
+ [#54]: https://github.com/chad/turbulence/pull/54
207
+ [#52]: https://github.com/chad/turbulence/pull/52
208
+ [#50]: https://github.com/chad/turbulence/pull/50
209
+ [#46]: https://github.com/chad/turbulence/pull/46
210
+ [#44]: https://github.com/chad/turbulence/pull/44
211
+ [#42]: https://github.com/chad/turbulence/issues/42
212
+ [#39]: https://github.com/chad/turbulence/issues/39
213
+ [#34]: https://github.com/chad/turbulence/pull/34
214
+ [#33]: https://github.com/chad/turbulence/pull/33
215
+ [#32]: https://github.com/chad/turbulence/pull/32
216
+ [#30]: https://github.com/chad/turbulence/pull/30
217
+ [#29]: https://github.com/chad/turbulence/issues/29
218
+ [#27]: https://github.com/chad/turbulence/pull/27
219
+ [#26]: https://github.com/chad/turbulence/pull/26
220
+ [#24]: https://github.com/chad/turbulence/pull/24
221
+ [#21]: https://github.com/chad/turbulence/pull/21
222
+ [#18]: https://github.com/chad/turbulence/pull/18
223
+ [#16]: https://github.com/chad/turbulence/pull/16
224
+ [#14]: https://github.com/chad/turbulence/pull/14
225
+ [#13]: https://github.com/chad/turbulence/pull/13
226
+ [#12]: https://github.com/chad/turbulence/pull/12
227
+ [#11]: https://github.com/chad/turbulence/pull/11
data/Gemfile.lock CHANGED
@@ -1,39 +1,62 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- turbulence (1.2.4)
5
- flog (~> 4.1)
6
- json (>= 1.4.6)
4
+ turbulence (1.4.0)
5
+ flog (>= 4.1)
6
+ json
7
7
  launchy (>= 2.0.0)
8
+ racc
8
9
 
9
10
  GEM
10
11
  remote: http://rubygems.org/
11
12
  specs:
12
- addressable (2.3.6)
13
- diff-lcs (1.2.5)
14
- flog (4.2.1)
15
- ruby_parser (~> 3.1, > 3.1.0)
16
- sexp_processor (~> 4.4)
17
- json (1.8.1)
18
- launchy (2.4.2)
19
- addressable (~> 2.3)
20
- rake (10.1.0)
21
- rspec (2.14.1)
22
- rspec-core (~> 2.14.0)
23
- rspec-expectations (~> 2.14.0)
24
- rspec-mocks (~> 2.14.0)
25
- rspec-core (2.14.7)
26
- rspec-expectations (2.14.4)
27
- diff-lcs (>= 1.1.3, < 2.0)
28
- rspec-mocks (2.14.4)
29
- ruby_parser (3.6.1)
30
- sexp_processor (~> 4.1)
31
- sexp_processor (4.4.3)
13
+ addressable (2.9.0)
14
+ public_suffix (>= 2.0.2, < 8.0)
15
+ childprocess (5.1.0)
16
+ logger (~> 1.5)
17
+ diff-lcs (1.6.2)
18
+ flog (4.9.4)
19
+ path_expander (~> 2.0)
20
+ prism (~> 1.7)
21
+ sexp_processor (~> 4.8)
22
+ json (2.19.9)
23
+ launchy (3.1.1)
24
+ addressable (~> 2.8)
25
+ childprocess (~> 5.0)
26
+ logger (~> 1.6)
27
+ logger (1.7.0)
28
+ path_expander (2.0.1)
29
+ prism (1.9.0)
30
+ public_suffix (7.0.5)
31
+ racc (1.8.1)
32
+ rake (13.4.2)
33
+ rspec (3.13.2)
34
+ rspec-core (~> 3.13.0)
35
+ rspec-expectations (~> 3.13.0)
36
+ rspec-mocks (~> 3.13.0)
37
+ rspec-core (3.13.6)
38
+ rspec-support (~> 3.13.0)
39
+ rspec-expectations (3.13.5)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.13.0)
42
+ rspec-its (2.0.0)
43
+ rspec-core (>= 3.13.0)
44
+ rspec-expectations (>= 3.13.0)
45
+ rspec-mocks (3.13.8)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.13.0)
48
+ rspec-support (3.13.7)
49
+ sexp_processor (4.17.5)
32
50
 
33
51
  PLATFORMS
52
+ arm64-darwin-25
34
53
  ruby
35
54
 
36
55
  DEPENDENCIES
37
56
  rake
38
- rspec (~> 2.14.0)
57
+ rspec (~> 3.0)
58
+ rspec-its
39
59
  turbulence!
60
+
61
+ BUNDLED WITH
62
+ 4.0.13
data/LICENSE.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2012-2026 Kerri Miller, Chad Fowler
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,48 +1,117 @@
1
- Hopefully-meaningful Metrics
2
- ============================
1
+ # Turbulence
3
2
 
4
- Based on Michael Feathers' [recent work](http://www.stickyminds.com/sitewide.asp?Function=edetail&ObjectType=COL&ObjectId=16679&tth=DYN&tt=siteemail&iDyn=2) in project churn and complexity.
3
+ [![CI](https://github.com/chad/turbulence/actions/workflows/ci.yml/badge.svg)](https://github.com/chad/turbulence/actions/workflows/ci.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/turbulence.svg)](https://badge.fury.io/rb/turbulence)
5
5
 
6
- Here is how to read the graph (extracted from the above article):
6
+ Turbulence visualizes churn vs complexity for your Ruby codebase, helping you identify files that are both highly complex and frequently changed - prime candidates for refactoring.
7
7
 
8
- * The upper right quadrant is particularly important.
9
- These files have a high degree of complexity, and they change quite frequently.
10
- There are a number of reasons why this can happen.
11
- The one to look out for, though, is something I call runaway conditionals.
12
- Sometimes a class becomes so complex that refactoring seems too difficult.
13
- Developers hack if-then-elses into if-then-elses, and the rat’s nest grows. These classes are particularly ripe for a refactoring investment.
8
+ Based on Michael Feathers' work on [getting empirical about refactoring](https://www.stickyminds.com/article/getting-empirical-about-refactoring).
14
9
 
15
- * The lower left quadrant. is the healthy closure region.
16
- Abstractions here have low complexity and don't change much.
10
+ ## Screenshots
17
11
 
18
- * The upper left is what I call the cowboy region. This is complex code that sprang from someone's head and didn't seem to grow incrementally.
12
+ ### Scatter Plot (default)
19
13
 
20
- * The bottom right is very interesting. I call it the fertile ground.
21
- It can consist of files that are somewhat configurational, but often there are also files that act as incubators for new abstractions.
22
- People add code, it grows, and then they factor outward, extracting new classes. The files churn frequently, but their complexity remains low.
14
+ ![Scatter Plot](docs/scatter-plot.png)
23
15
 
16
+ ### Treemap
24
17
 
25
- Installation
26
- ------------
18
+ ![Treemap](docs/treemap.png)
27
19
 
28
- $ gem install turbulence
20
+ ## How to Read the Graph
21
+
22
+ The scatter plot places each file according to its **churn** (x-axis) and **complexity** (y-axis):
23
+
24
+ | Quadrant | Location | What it means |
25
+ |----------|----------|---------------|
26
+ | **Danger Zone** | Upper right | High complexity + high churn. These files change often and are hard to work with. Prime refactoring candidates! |
27
+ | **Healthy Closure** | Lower left | Low complexity + low churn. Stable, well-factored code. Leave it alone. |
28
+ | **Cowboy Code** | Upper left | High complexity + low churn. Complex code that sprang from someone's head fully formed. May need attention if it starts changing. |
29
+ | **Fertile Ground** | Lower right | Low complexity + high churn. Often configuration or incubators for new abstractions. Code grows here, then gets extracted. |
30
+
31
+ ## Requirements
32
+
33
+ - Ruby 3.0 or later
34
+ - Git or Perforce
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ gem install turbulence
40
+ ```
41
+
42
+ ## Usage
29
43
 
30
- Usage
31
- -----
32
44
  In your project directory, run:
33
45
 
34
- $ bule
46
+ ```bash
47
+ bule
48
+ ```
49
+
50
+ This generates and opens `turbulence/turbulence.html` with an interactive scatter plot.
51
+
52
+ ### Options
53
+
54
+ ```bash
55
+ bule [options] [directory]
56
+
57
+ Options:
58
+ --scm p4|git SCM to use (default: git)
59
+ --churn-range A..B Commit range to compute file churn
60
+ --churn-mean Calculate mean churn instead of cumulative
61
+ --exclude PATTERN Exclude files matching pattern
62
+ --treemap Output treemap graph instead of scatter plot
63
+ --no-open Skip opening the report in a browser
64
+ --output DIR Output directory for reports (default: ./turbulence)
65
+ ```
66
+
67
+ ### Examples
68
+
69
+ ```bash
70
+ # Analyze current directory
71
+ bule
72
+
73
+ # Analyze a specific directory
74
+ bule path/to/project
75
+
76
+ # Use Perforce instead of Git
77
+ bule --scm p4
78
+
79
+ # Analyze only recent changes
80
+ bule --churn-range HEAD~100..HEAD
81
+
82
+ # Generate report without opening browser (useful for CI)
83
+ bule --no-open
84
+
85
+ # Output to a custom directory
86
+ bule --output spec/reports/turbulence
87
+
88
+ # Exclude test files
89
+ bule --exclude spec
90
+ ```
91
+
92
+ ### Perforce Support
93
+
94
+ For Perforce, set the `P4CLIENT` environment variable to your client workspace name:
95
+
96
+ ```bash
97
+ export P4CLIENT=my-workspace
98
+ bule --scm p4
99
+ ```
100
+
101
+ ## Privacy Warning
102
+
103
+ Turbulence generates a JavaScript file containing your file paths and names. If these are sensitive, be careful where you put the generated files and who you share them with.
104
+
105
+ ## Contributing
35
106
 
36
- and it will generate (and open) turbulence/turbulence.html
107
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/chad/turbulence).
37
108
 
38
- Supported SCM systems
39
- ---------------------
40
- Currently, bule defaults to using git. If you are using Perforce, call it like so:
109
+ ## License
41
110
 
42
- $ bule --scm p4
111
+ [MIT License](LICENSE.txt)
43
112
 
44
- You need to have an environment variable P4CLIENT set to the name of your client workspace.
113
+ ## Authors
45
114
 
46
- WARNING
47
- -------
48
- When you run bule, it creates a JavaScript file which contains your file paths and names. If those are sensitive, be careful where you put these generated files and who you share them with.
115
+ - [Chad Fowler](https://github.com/chad)
116
+ - [Michael Feathers](https://github.com/michaelfeathers)
117
+ - [Corey Haines](https://github.com/coreyhaines)
data/bin/bule CHANGED
@@ -11,4 +11,4 @@ unless Turbulence::ChecksEnvironment.scm_repo?(Dir.pwd)
11
11
  end
12
12
 
13
13
  cli.generate_bundle
14
- cli.open_bundle
14
+ cli.open_bundle unless cli.no_open
Binary file
data/docs/treemap.png ADDED
Binary file
@@ -5,9 +5,11 @@ class Turbulence
5
5
  class Churn
6
6
  RUBY_FILE_EXTENSION = ".rb"
7
7
 
8
- attr_reader :config
8
+ attr_reader :config, :type
9
+
9
10
  def initialize(config = nil)
10
11
  @config = config || Turbulence.config
12
+ @type = :churn
11
13
  end
12
14
 
13
15
  extend Forwardable
@@ -1,30 +1,18 @@
1
1
  require 'stringio'
2
2
  require 'flog'
3
3
 
4
- class Ruby19Parser < RubyParser
5
- def process(ruby, file)
6
- ruby.gsub!(/(\w+):\s+/, '"\1" =>')
7
- super(ruby, file)
8
- end
9
- end unless defined?(:Ruby19Parser)
10
-
11
- class Flog19 < Flog
12
- def initialize option = {}
13
- super(option)
14
- @parser = Ruby19Parser.new
15
- end
16
- end
17
-
18
4
  class Turbulence
19
5
  module Calculators
20
6
  class Complexity
21
- attr_reader :config
7
+ attr_reader :config, :type
8
+
22
9
  def initialize(config = nil)
23
10
  @config = config || Turbulence.config
11
+ @type = :complexity
24
12
  end
25
13
 
26
14
  def flogger
27
- @flogger ||= Flog19.new(:continue => true)
15
+ @flogger ||= Flog.new(continue: true)
28
16
  end
29
17
 
30
18
  def for_these_files(files)
@@ -19,7 +19,7 @@ class Turbulence
19
19
  config.commit_range = s
20
20
  end
21
21
 
22
- opts.on('--churn-mean', 'calculate mean churn instead of cummulative') do
22
+ opts.on('--churn-mean', 'calculate mean churn instead of cumulative') do
23
23
  config.compute_mean = true
24
24
  end
25
25
 
@@ -31,6 +31,17 @@ class Turbulence
31
31
  config.graph_type = "treemap"
32
32
  end
33
33
 
34
+ opts.on('--no-open', 'skip opening the report in a browser') do
35
+ config.no_open = true
36
+ end
37
+
38
+ opts.on('--output DIR', String, 'output directory for reports (default: ./turbulence)') do |dir|
39
+ config.output_dir = dir
40
+ end
41
+
42
+ opts.on('--json', 'output raw metrics as JSON to stdout') do
43
+ config.json_output = true
44
+ end
34
45
 
35
46
  opts.on_tail("-h", "--help", "Show this message") do
36
47
  puts opts