churn 0.0.20 → 0.0.21
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.
- data/Gemfile.lock +45 -0
- data/README.md +147 -0
- data/VERSION +1 -1
- data/bin/churn +8 -2
- data/churn.gemspec +4 -22
- data/lib/churn/churn_calculator.rb +18 -15
- data/lib/tasks/churn_tasks.rb +5 -1
- data/test/unit/churn_calculator_test.rb +21 -7
- metadata +16 -88
- data/README.rdoc +0 -123
data/Gemfile.lock
CHANGED
@@ -1,8 +1,53 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
churn (0.0.20)
|
5
|
+
chronic (>= 0.2.3)
|
6
|
+
churn
|
7
|
+
hirb
|
8
|
+
json_pure
|
9
|
+
main
|
10
|
+
ruby_parser (~> 2.3)
|
11
|
+
sexp_processor (~> 3.0)
|
12
|
+
|
1
13
|
GEM
|
2
14
|
remote: http://rubygems.org/
|
3
15
|
specs:
|
16
|
+
arrayfields (4.7.4)
|
17
|
+
chronic (0.7.0)
|
18
|
+
fattr (2.2.1)
|
19
|
+
git (1.2.5)
|
20
|
+
hirb (0.7.0)
|
21
|
+
jeweler (1.8.4)
|
22
|
+
bundler (~> 1.0)
|
23
|
+
git (>= 1.2.5)
|
24
|
+
rake
|
25
|
+
rdoc
|
26
|
+
json (1.7.5)
|
27
|
+
json_pure (1.7.5)
|
28
|
+
main (5.1.0)
|
29
|
+
arrayfields (>= 4.7.4)
|
30
|
+
chronic (>= 0.6.2)
|
31
|
+
fattr (>= 2.2.0)
|
32
|
+
map (>= 5.1.0)
|
33
|
+
map (6.2.0)
|
34
|
+
mocha (0.9.12)
|
35
|
+
rake (0.9.2.2)
|
36
|
+
rdoc (3.12)
|
37
|
+
json (~> 1.4)
|
38
|
+
ruby_parser (2.3.1)
|
39
|
+
sexp_processor (~> 3.0)
|
40
|
+
sexp_processor (3.2.0)
|
41
|
+
shoulda (2.11.3)
|
42
|
+
test-construct (1.2.0)
|
4
43
|
|
5
44
|
PLATFORMS
|
6
45
|
ruby
|
7
46
|
|
8
47
|
DEPENDENCIES
|
48
|
+
churn!
|
49
|
+
jeweler
|
50
|
+
mocha (~> 0.9.5)
|
51
|
+
rake
|
52
|
+
shoulda
|
53
|
+
test-construct
|
data/README.md
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
__churn__
|
2
|
+
|
3
|
+
A Project to give the churn file, class, and method for a project for a given checkin. Over time the tool adds up the history of chruns to give the number of times a file, class, or method is changing during the life of a project.
|
4
|
+
Churn for files is immediate, but classes and methods requires buildings up a history using churn between revisions. The history is stored in ./tmp
|
5
|
+
|
6
|
+
Currently has full Git, Mercurial (hg), and Bazaar (bzr) support, and partial SVN support (supports only file level churn currently)
|
7
|
+
|
8
|
+
Authors:
|
9
|
+
|
10
|
+
* danmayer
|
11
|
+
* ajwalters
|
12
|
+
* cldwalker
|
13
|
+
* absurdhero
|
14
|
+
|
15
|
+
__Churn Usage__
|
16
|
+
Install with `gem install churn` or for bundler add to your Gemfile `gem 'churn'`
|
17
|
+
|
18
|
+
* rake:
|
19
|
+
* add `require 'churn'` to Rakefile
|
20
|
+
* then run`rake churn` or `bundle exec rake churn`
|
21
|
+
* use environment variables to control churn defaults
|
22
|
+
|
23
|
+
ENV['CHURN_MINIMUM_CHURN_COUNT']
|
24
|
+
ENV['CHURN_START_DATE']
|
25
|
+
ENV['CHURN_IGNORE_FILES']
|
26
|
+
|
27
|
+
* CLI:
|
28
|
+
* on command line run `churn` or `bundle exec churn`
|
29
|
+
* need help run `churn -h` to get additional information
|
30
|
+
* run the executable passing in options to override defaults
|
31
|
+
|
32
|
+
churn -i "churn.gemspec, Gemfile" #ignore files
|
33
|
+
churn -y #output yaml format opposed to text
|
34
|
+
churn -c 10 #set minimum churn count on a file to 10
|
35
|
+
churn -c 5 -y -i "Gemfile" #mix and match
|
36
|
+
|
37
|
+
|
38
|
+
__Example Output__
|
39
|
+
|
40
|
+
**********************************************************************
|
41
|
+
* Revision Changes
|
42
|
+
**********************************************************************
|
43
|
+
Files:
|
44
|
+
+-------------------------------+
|
45
|
+
| file |
|
46
|
+
+-------------------------------+
|
47
|
+
| Rakefile |
|
48
|
+
| lib/churn/churn_calculator.rb |
|
49
|
+
+-------------------------------+
|
50
|
+
|
51
|
+
Classes:
|
52
|
+
+-------------------------------+-----------------+
|
53
|
+
| file | klass |
|
54
|
+
+-------------------------------+-----------------+
|
55
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator |
|
56
|
+
+-------------------------------+-----------------+
|
57
|
+
|
58
|
+
Methods:
|
59
|
+
+-------------------------------+----------------- +-------------------------------+
|
60
|
+
| file | klass | method |
|
61
|
+
+-------------------------------+-----------------+-------------------------------+
|
62
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#filters |
|
63
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#display_array |
|
64
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#to_s |
|
65
|
+
+-------------------------------+-----------------+-------------------------------+
|
66
|
+
|
67
|
+
**********************************************************************
|
68
|
+
* Project Churn
|
69
|
+
**********************************************************************
|
70
|
+
Files:
|
71
|
+
+------------------------------------+---------------+
|
72
|
+
| file_path | times_changed |
|
73
|
+
+------------------------------------+---------------+
|
74
|
+
| lib/churn/churn_calculator.rb | 14 |
|
75
|
+
| README.rdoc | 7 |
|
76
|
+
| lib/tasks/churn_tasks.rb | 6 |
|
77
|
+
| Rakefile | 6 |
|
78
|
+
| lib/churn/git_analyzer.rb | 4 |
|
79
|
+
| VERSION | 4 |
|
80
|
+
| test/test_helper.rb | 4 |
|
81
|
+
| test/unit/churn_calculator_test.rb | 3 |
|
82
|
+
| test/churn_test.rb | 3 |
|
83
|
+
+------------------------------------+---------------+
|
84
|
+
|
85
|
+
Classes:
|
86
|
+
+-------------------------------+-----------------+---------------+
|
87
|
+
| file | klass | times_changed |
|
88
|
+
+-------------------------------+-----------------+---------------+
|
89
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | 1 |
|
90
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | 1 |
|
91
|
+
+-------------------------------+-----------------+---------------+
|
92
|
+
|
93
|
+
Methods:
|
94
|
+
+-------------------------------+-----------------+-----------------------------------------+---------------+
|
95
|
+
| file | klass | method | times_changed |
|
96
|
+
+-------------------------------+-----------------+-----------------------------------------+---------------+
|
97
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#to_s | 1 |
|
98
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#display_array | 1 |
|
99
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#calculate_revision_data | 1 |
|
100
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#filters | 1 |
|
101
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#initialize | 1 |
|
102
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#filters | 1 |
|
103
|
+
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#to_s | 1 |
|
104
|
+
+-------------------------------+-----------------+-----------------------------------------+---------------+
|
105
|
+
|
106
|
+
__Options__
|
107
|
+
|
108
|
+
[~/projects/churn] churn -h
|
109
|
+
NAME
|
110
|
+
churn
|
111
|
+
|
112
|
+
SYNOPSIS
|
113
|
+
churn [options]+
|
114
|
+
|
115
|
+
PARAMETERS
|
116
|
+
--minimum_churn_count=minimum_churn_count, -c (0 ~>
|
117
|
+
int(minimum_churn_count=3))
|
118
|
+
--yaml, -y
|
119
|
+
--ignore_files=[ignore_files], -i (0 ~> string(ignore_files=))
|
120
|
+
--help, -h
|
121
|
+
|
122
|
+
__TODO:__
|
123
|
+
|
124
|
+
* SVN only supports file, add full SVN support
|
125
|
+
* support bazaar, cvs, and darcs
|
126
|
+
* make storage directory configurable instead of using tmp
|
127
|
+
* allow passing in directories to churn, directories to ignore
|
128
|
+
* add a filter that allows for other files besides. *.rb
|
129
|
+
* ignore files pattern, so you can ignore things like vendor/, lib/, or docs/
|
130
|
+
* finish adding better documenation using YARD
|
131
|
+
* rake task for building manpage (currently manually run ronn -b1 README.rdoc)
|
132
|
+
* don't output methods and classes on a commit that has none detected (css and view only commits, etc)
|
133
|
+
|
134
|
+
__Notes on Patches/Pull Requests__
|
135
|
+
|
136
|
+
* Fork the project.
|
137
|
+
* Make your feature addition or bug fix.
|
138
|
+
* Add tests for it. This is important so I don't break it in a
|
139
|
+
future version unintentionally.
|
140
|
+
* Commit, do not mess with rakefile, version, or history.
|
141
|
+
(if you want to have your own version, that is fine but
|
142
|
+
bump version in a commit by itself I can ignore when I pull)
|
143
|
+
* Send me a pull request. Bonus points for topic branches.
|
144
|
+
|
145
|
+
__Copyright__
|
146
|
+
|
147
|
+
Copyright (c) 2012 Dan Mayer. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.21
|
data/bin/churn
CHANGED
@@ -15,9 +15,15 @@ Main do
|
|
15
15
|
default false
|
16
16
|
end
|
17
17
|
|
18
|
+
option('ignore_files', 'i') do
|
19
|
+
cast :string
|
20
|
+
argument :optional
|
21
|
+
default ''
|
22
|
+
end
|
23
|
+
|
18
24
|
def report_churn(output_string)
|
19
25
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'churn', 'churn_calculator')
|
20
|
-
result = Churn::ChurnCalculator.new({:minimum_churn_count => params['minimum_churn_count'].value}).report(output_string)
|
26
|
+
result = Churn::ChurnCalculator.new({:minimum_churn_count => params['minimum_churn_count'].value, :ignore_files => params['ignore_files'].value}).report(output_string)
|
21
27
|
unless output_string
|
22
28
|
result = YAML::dump(result)
|
23
29
|
end
|
@@ -29,4 +35,4 @@ Main do
|
|
29
35
|
puts report
|
30
36
|
end
|
31
37
|
|
32
|
-
end
|
38
|
+
end
|
data/churn.gemspec
CHANGED
@@ -5,24 +5,24 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "churn"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.21"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Dan Mayer"]
|
12
|
-
s.date = "2012-09-
|
12
|
+
s.date = "2012-09-14"
|
13
13
|
s.description = "High method and class churn has been shown to have increased bug and error rates. This gem helps you know what is changing a lot so you can do additional testing, code review, or refactoring to try to tame the volatile code. "
|
14
14
|
s.email = "dan@mayerdan.com"
|
15
15
|
s.executables = ["churn"]
|
16
16
|
s.extra_rdoc_files = [
|
17
17
|
"LICENSE",
|
18
|
-
"README.
|
18
|
+
"README.md"
|
19
19
|
]
|
20
20
|
s.files = [
|
21
21
|
".document",
|
22
22
|
"Gemfile",
|
23
23
|
"Gemfile.lock",
|
24
24
|
"LICENSE",
|
25
|
-
"README.
|
25
|
+
"README.md",
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"bin/churn",
|
@@ -58,12 +58,6 @@ Gem::Specification.new do |s|
|
|
58
58
|
s.specification_version = 3
|
59
59
|
|
60
60
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
61
|
-
s.add_runtime_dependency(%q<churn>, [">= 0"])
|
62
|
-
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
63
|
-
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
64
|
-
s.add_development_dependency(%q<test-construct>, [">= 0"])
|
65
|
-
s.add_development_dependency(%q<rake>, [">= 0"])
|
66
|
-
s.add_development_dependency(%q<mocha>, ["~> 0.9.5"])
|
67
61
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
68
62
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
69
63
|
s.add_development_dependency(%q<test-construct>, [">= 0"])
|
@@ -76,12 +70,6 @@ Gem::Specification.new do |s|
|
|
76
70
|
s.add_runtime_dependency(%q<ruby_parser>, ["~> 2.3"])
|
77
71
|
s.add_runtime_dependency(%q<hirb>, [">= 0"])
|
78
72
|
else
|
79
|
-
s.add_dependency(%q<churn>, [">= 0"])
|
80
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
81
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
82
|
-
s.add_dependency(%q<test-construct>, [">= 0"])
|
83
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
84
|
-
s.add_dependency(%q<mocha>, ["~> 0.9.5"])
|
85
73
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
86
74
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
87
75
|
s.add_dependency(%q<test-construct>, [">= 0"])
|
@@ -95,12 +83,6 @@ Gem::Specification.new do |s|
|
|
95
83
|
s.add_dependency(%q<hirb>, [">= 0"])
|
96
84
|
end
|
97
85
|
else
|
98
|
-
s.add_dependency(%q<churn>, [">= 0"])
|
99
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
100
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
101
|
-
s.add_dependency(%q<test-construct>, [">= 0"])
|
102
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
103
|
-
s.add_dependency(%q<mocha>, ["~> 0.9.5"])
|
104
86
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
105
87
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
106
88
|
s.add_dependency(%q<test-construct>, [">= 0"])
|
@@ -25,7 +25,9 @@ module Churn
|
|
25
25
|
def initialize(options={})
|
26
26
|
start_date = options.fetch(:start_date) { '3 months ago' }
|
27
27
|
@minimum_churn_count = options.fetch(:minimum_churn_count) { 5 }
|
28
|
-
@
|
28
|
+
@ignore_files = (options.fetch(:ignore_files){ "" }).split(',').map(&:strip)
|
29
|
+
@ignore_files << '/dev/null'
|
30
|
+
@source_control = set_source_control(start_date)
|
29
31
|
@changes = {}
|
30
32
|
@revision_changes = {}
|
31
33
|
@class_changes = {}
|
@@ -37,16 +39,16 @@ module Churn
|
|
37
39
|
# @param [Bolean] format to return the data, true for string or false for hash
|
38
40
|
# @return [Object] returns either a pretty string or a hash representing the chrun of the project
|
39
41
|
def report(print = true)
|
40
|
-
self.emit
|
42
|
+
self.emit
|
41
43
|
self.analyze
|
42
44
|
print ? self.to_s : self.to_h
|
43
45
|
end
|
44
|
-
|
46
|
+
|
45
47
|
# Emits various data from source control to be analyses later... Currently this is broken up like this as a throwback to metric_fu
|
46
48
|
def emit
|
47
|
-
@changes = parse_log_for_changes.reject {|file, change_count| change_count < @minimum_churn_count}
|
48
|
-
@revisions = parse_log_for_revision_changes
|
49
|
-
end
|
49
|
+
@changes = parse_log_for_changes.reject {|file, change_count| change_count < @minimum_churn_count || @ignore_files.include?(file) }
|
50
|
+
@revisions = parse_log_for_revision_changes
|
51
|
+
end
|
50
52
|
|
51
53
|
# Analyze the source control data, filter, sort, and find more information on the editted files
|
52
54
|
def analyze
|
@@ -83,7 +85,7 @@ module Churn
|
|
83
85
|
# Pretty print the data as a string for the user
|
84
86
|
def to_s
|
85
87
|
hash = to_h[:churn]
|
86
|
-
result = seperator
|
88
|
+
result = seperator
|
87
89
|
result +="* Revision Changes \n"
|
88
90
|
result += seperator
|
89
91
|
result += "Files: \n"
|
@@ -92,7 +94,7 @@ module Churn
|
|
92
94
|
result += display_array(hash[:changed_classes])
|
93
95
|
result += "\nMethods: \n"
|
94
96
|
result += display_array(hash[:changed_methods]) + "\n"
|
95
|
-
result += seperator
|
97
|
+
result += seperator
|
96
98
|
result +="* Project Churn \n"
|
97
99
|
result += seperator
|
98
100
|
result += "Files: \n"
|
@@ -106,7 +108,7 @@ module Churn
|
|
106
108
|
end
|
107
109
|
|
108
110
|
private
|
109
|
-
|
111
|
+
|
110
112
|
def collect_items(collection, match)
|
111
113
|
collection.map {|item| (item.delete(match) || {}).merge(item) }
|
112
114
|
end
|
@@ -165,14 +167,14 @@ module Churn
|
|
165
167
|
end
|
166
168
|
calculate_changes!(changed_methods, @method_changes) if changed_methods
|
167
169
|
calculate_changes!(changed_classes, @class_changes) if changed_classes
|
168
|
-
|
170
|
+
|
169
171
|
@revision_changes[revision] = { :files => changed_files, :classes => changed_classes, :methods => changed_methods }
|
170
172
|
end
|
171
173
|
end
|
172
174
|
|
173
175
|
def calculate_revision_data(revision)
|
174
176
|
changed_files = parse_logs_for_updated_files(revision, @revisions)
|
175
|
-
|
177
|
+
|
176
178
|
changed_classes = []
|
177
179
|
changed_methods = []
|
178
180
|
changed_files.each do |file_changes|
|
@@ -225,10 +227,10 @@ module Churn
|
|
225
227
|
end
|
226
228
|
changed_items
|
227
229
|
end
|
228
|
-
|
230
|
+
|
229
231
|
def parse_log_for_changes
|
230
232
|
changes = {}
|
231
|
-
|
233
|
+
|
232
234
|
logs = @source_control.get_logs
|
233
235
|
logs.each do |line|
|
234
236
|
changes[line] ? changes[line] += 1 : changes[line] = 1
|
@@ -240,11 +242,12 @@ module Churn
|
|
240
242
|
return [] unless @source_control.respond_to?(:get_revisions)
|
241
243
|
@source_control.get_revisions
|
242
244
|
end
|
243
|
-
|
245
|
+
|
244
246
|
def parse_logs_for_updated_files(revision, revisions)
|
245
247
|
#TODO SVN doesn't support this
|
246
248
|
return {} unless @source_control.respond_to?(:get_updated_files_change_info)
|
247
|
-
@source_control.get_updated_files_change_info(revision, revisions)
|
249
|
+
files = @source_control.get_updated_files_change_info(revision, revisions)
|
250
|
+
files.select{ |file, value| !@ignore_files.include?(file) }
|
248
251
|
end
|
249
252
|
|
250
253
|
end
|
data/lib/tasks/churn_tasks.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
def report_churn()
|
2
2
|
require File.join(File.dirname(__FILE__), '..', 'churn', 'churn_calculator')
|
3
|
-
Churn::ChurnCalculator.new({
|
3
|
+
Churn::ChurnCalculator.new({
|
4
|
+
:minimum_churn_count => ENV['CHURN_MINIMUM_CHURN_COUNT'],
|
5
|
+
:start_date => ENV['CHURN_START_DATE'],
|
6
|
+
:ignore_files => ENV['CHURN_IGNORE_FILES'],
|
7
|
+
}).report
|
4
8
|
end
|
5
9
|
|
6
10
|
desc "Report the current churn for the project"
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
class ChurnCalculatorTest < Test::Unit::TestCase
|
4
|
-
|
4
|
+
|
5
5
|
should "use minimum churn count" do
|
6
6
|
within_construct do |container|
|
7
7
|
Churn::ChurnCalculator.stubs(:git?).returns(true)
|
8
8
|
churn = Churn::ChurnCalculator.new({:minimum_churn_count => 3})
|
9
|
-
|
9
|
+
|
10
10
|
churn.stubs(:parse_log_for_changes).returns([['file.rb', 4],['less.rb',1]])
|
11
11
|
churn.stubs(:parse_log_for_revision_changes).returns(['revision'])
|
12
12
|
churn.stubs(:analyze)
|
@@ -16,11 +16,25 @@ class ChurnCalculatorTest < Test::Unit::TestCase
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
should "use ignore_files filter" do
|
20
|
+
within_construct do |container|
|
21
|
+
Churn::ChurnCalculator.stubs(:git?).returns(true)
|
22
|
+
churn = Churn::ChurnCalculator.new({:ignore_files => "file.rb"})
|
23
|
+
|
24
|
+
churn.stubs(:parse_log_for_changes).returns([['file.rb', 10],['new.rb',11]])
|
25
|
+
churn.stubs(:parse_log_for_revision_changes).returns(['revision'])
|
26
|
+
churn.stubs(:analyze)
|
27
|
+
report = churn.report(false)
|
28
|
+
assert_equal 1, report[:churn][:changes].length
|
29
|
+
assert_equal ["new.rb", 11], report[:churn][:changes].first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
19
33
|
should "analize sorts changes" do
|
20
34
|
within_construct do |container|
|
21
35
|
Churn::ChurnCalculator.stubs(:git?).returns(true)
|
22
36
|
churn = Churn::ChurnCalculator.new({:minimum_churn_count => 3})
|
23
|
-
|
37
|
+
|
24
38
|
churn.stubs(:parse_log_for_changes).returns([['file.rb', 4],['most.rb', 9],['less.rb',1]])
|
25
39
|
churn.stubs(:parse_log_for_revision_changes).returns(['revision'])
|
26
40
|
report = churn.report(false)
|
@@ -36,7 +50,7 @@ class ChurnCalculatorTest < Test::Unit::TestCase
|
|
36
50
|
within_construct do |container|
|
37
51
|
Churn::ChurnCalculator.stubs(:git?).returns(true)
|
38
52
|
churn = Churn::ChurnCalculator.new({:minimum_churn_count => 3})
|
39
|
-
|
53
|
+
|
40
54
|
churn.stubs(:parse_log_for_changes).returns([['less.rb',1]])
|
41
55
|
churn.stubs(:parse_log_for_revision_changes).returns(['first'])
|
42
56
|
churn.stubs(:parse_logs_for_updated_files).returns({'fake_file.rb'=>[]})
|
@@ -49,7 +63,7 @@ class ChurnCalculatorTest < Test::Unit::TestCase
|
|
49
63
|
within_construct do |container|
|
50
64
|
Churn::ChurnCalculator.stubs(:git?).returns(true)
|
51
65
|
churn = Churn::ChurnCalculator.new({:minimum_churn_count => 3})
|
52
|
-
|
66
|
+
|
53
67
|
churn.stubs(:parse_log_for_changes).returns([['less.rb',1]])
|
54
68
|
churn.stubs(:parse_log_for_revision_changes).returns(['first'])
|
55
69
|
churn.stubs(:parse_logs_for_updated_files).returns({'fake_file.rb'=>[]})
|
@@ -66,7 +80,7 @@ class ChurnCalculatorTest < Test::Unit::TestCase
|
|
66
80
|
within_construct do |container|
|
67
81
|
Churn::ChurnCalculator.stubs(:git?).returns(true)
|
68
82
|
churn = Churn::ChurnCalculator.new({:minimum_churn_count => 3})
|
69
|
-
|
83
|
+
|
70
84
|
churn.stubs(:parse_log_for_changes).returns([['less.rb',1]])
|
71
85
|
churn.stubs(:parse_log_for_revision_changes).returns(['first'])
|
72
86
|
churn.stubs(:parse_logs_for_updated_files).returns({'fake_file.rb'=>[]})
|
@@ -86,5 +100,5 @@ class ChurnCalculatorTest < Test::Unit::TestCase
|
|
86
100
|
assert churn.instance_variable_get(:@source_control).is_a?(Churn::HgAnalyzer)
|
87
101
|
end
|
88
102
|
|
89
|
-
|
103
|
+
|
90
104
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: churn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 53
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 21
|
10
|
+
version: 0.0.21
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dan Mayer
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-09-
|
18
|
+
date: 2012-09-14 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -187,82 +187,10 @@ dependencies:
|
|
187
187
|
version: "0"
|
188
188
|
requirement: *id012
|
189
189
|
prerelease: false
|
190
|
-
name: shoulda
|
191
|
-
type: :development
|
192
|
-
- !ruby/object:Gem::Dependency
|
193
|
-
version_requirements: &id013 !ruby/object:Gem::Requirement
|
194
|
-
none: false
|
195
|
-
requirements:
|
196
|
-
- - ">="
|
197
|
-
- !ruby/object:Gem::Version
|
198
|
-
hash: 3
|
199
|
-
segments:
|
200
|
-
- 0
|
201
|
-
version: "0"
|
202
|
-
requirement: *id013
|
203
|
-
prerelease: false
|
204
|
-
name: jeweler
|
205
|
-
type: :development
|
206
|
-
- !ruby/object:Gem::Dependency
|
207
|
-
version_requirements: &id014 !ruby/object:Gem::Requirement
|
208
|
-
none: false
|
209
|
-
requirements:
|
210
|
-
- - ">="
|
211
|
-
- !ruby/object:Gem::Version
|
212
|
-
hash: 3
|
213
|
-
segments:
|
214
|
-
- 0
|
215
|
-
version: "0"
|
216
|
-
requirement: *id014
|
217
|
-
prerelease: false
|
218
|
-
name: test-construct
|
219
|
-
type: :development
|
220
|
-
- !ruby/object:Gem::Dependency
|
221
|
-
version_requirements: &id015 !ruby/object:Gem::Requirement
|
222
|
-
none: false
|
223
|
-
requirements:
|
224
|
-
- - ">="
|
225
|
-
- !ruby/object:Gem::Version
|
226
|
-
hash: 3
|
227
|
-
segments:
|
228
|
-
- 0
|
229
|
-
version: "0"
|
230
|
-
requirement: *id015
|
231
|
-
prerelease: false
|
232
|
-
name: rake
|
233
|
-
type: :development
|
234
|
-
- !ruby/object:Gem::Dependency
|
235
|
-
version_requirements: &id016 !ruby/object:Gem::Requirement
|
236
|
-
none: false
|
237
|
-
requirements:
|
238
|
-
- - ~>
|
239
|
-
- !ruby/object:Gem::Version
|
240
|
-
hash: 49
|
241
|
-
segments:
|
242
|
-
- 0
|
243
|
-
- 9
|
244
|
-
- 5
|
245
|
-
version: 0.9.5
|
246
|
-
requirement: *id016
|
247
|
-
prerelease: false
|
248
|
-
name: mocha
|
249
|
-
type: :development
|
250
|
-
- !ruby/object:Gem::Dependency
|
251
|
-
version_requirements: &id017 !ruby/object:Gem::Requirement
|
252
|
-
none: false
|
253
|
-
requirements:
|
254
|
-
- - ">="
|
255
|
-
- !ruby/object:Gem::Version
|
256
|
-
hash: 3
|
257
|
-
segments:
|
258
|
-
- 0
|
259
|
-
version: "0"
|
260
|
-
requirement: *id017
|
261
|
-
prerelease: false
|
262
190
|
name: main
|
263
191
|
type: :runtime
|
264
192
|
- !ruby/object:Gem::Dependency
|
265
|
-
version_requirements: &
|
193
|
+
version_requirements: &id013 !ruby/object:Gem::Requirement
|
266
194
|
none: false
|
267
195
|
requirements:
|
268
196
|
- - ">="
|
@@ -271,12 +199,12 @@ dependencies:
|
|
271
199
|
segments:
|
272
200
|
- 0
|
273
201
|
version: "0"
|
274
|
-
requirement: *
|
202
|
+
requirement: *id013
|
275
203
|
prerelease: false
|
276
204
|
name: json_pure
|
277
205
|
type: :runtime
|
278
206
|
- !ruby/object:Gem::Dependency
|
279
|
-
version_requirements: &
|
207
|
+
version_requirements: &id014 !ruby/object:Gem::Requirement
|
280
208
|
none: false
|
281
209
|
requirements:
|
282
210
|
- - ">="
|
@@ -287,12 +215,12 @@ dependencies:
|
|
287
215
|
- 2
|
288
216
|
- 3
|
289
217
|
version: 0.2.3
|
290
|
-
requirement: *
|
218
|
+
requirement: *id014
|
291
219
|
prerelease: false
|
292
220
|
name: chronic
|
293
221
|
type: :runtime
|
294
222
|
- !ruby/object:Gem::Dependency
|
295
|
-
version_requirements: &
|
223
|
+
version_requirements: &id015 !ruby/object:Gem::Requirement
|
296
224
|
none: false
|
297
225
|
requirements:
|
298
226
|
- - ~>
|
@@ -302,12 +230,12 @@ dependencies:
|
|
302
230
|
- 3
|
303
231
|
- 0
|
304
232
|
version: "3.0"
|
305
|
-
requirement: *
|
233
|
+
requirement: *id015
|
306
234
|
prerelease: false
|
307
235
|
name: sexp_processor
|
308
236
|
type: :runtime
|
309
237
|
- !ruby/object:Gem::Dependency
|
310
|
-
version_requirements: &
|
238
|
+
version_requirements: &id016 !ruby/object:Gem::Requirement
|
311
239
|
none: false
|
312
240
|
requirements:
|
313
241
|
- - ~>
|
@@ -317,12 +245,12 @@ dependencies:
|
|
317
245
|
- 2
|
318
246
|
- 3
|
319
247
|
version: "2.3"
|
320
|
-
requirement: *
|
248
|
+
requirement: *id016
|
321
249
|
prerelease: false
|
322
250
|
name: ruby_parser
|
323
251
|
type: :runtime
|
324
252
|
- !ruby/object:Gem::Dependency
|
325
|
-
version_requirements: &
|
253
|
+
version_requirements: &id017 !ruby/object:Gem::Requirement
|
326
254
|
none: false
|
327
255
|
requirements:
|
328
256
|
- - ">="
|
@@ -331,7 +259,7 @@ dependencies:
|
|
331
259
|
segments:
|
332
260
|
- 0
|
333
261
|
version: "0"
|
334
|
-
requirement: *
|
262
|
+
requirement: *id017
|
335
263
|
prerelease: false
|
336
264
|
name: hirb
|
337
265
|
type: :runtime
|
@@ -343,13 +271,13 @@ extensions: []
|
|
343
271
|
|
344
272
|
extra_rdoc_files:
|
345
273
|
- LICENSE
|
346
|
-
- README.
|
274
|
+
- README.md
|
347
275
|
files:
|
348
276
|
- .document
|
349
277
|
- Gemfile
|
350
278
|
- Gemfile.lock
|
351
279
|
- LICENSE
|
352
|
-
- README.
|
280
|
+
- README.md
|
353
281
|
- Rakefile
|
354
282
|
- VERSION
|
355
283
|
- bin/churn
|
data/README.rdoc
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
= churn
|
2
|
-
|
3
|
-
A Project to give the churn file, class, and method for a project for a given checkin
|
4
|
-
Over time the tool adds up the history of chruns to give the number of times a file, class, or method is changing during the life of a project.
|
5
|
-
Churn for files is immediate, but classes and methods requires buildings up a history using churn between revisions. The history is stored in ./tmp
|
6
|
-
|
7
|
-
Currently has full Git, Mercurial (hg), and Bazaar (bzr) support, and partial SVN support (supports only file level churn currently)
|
8
|
-
|
9
|
-
Authors:
|
10
|
-
* danmayer
|
11
|
-
* ajwalters
|
12
|
-
* cldwalker
|
13
|
-
* absurdhero
|
14
|
-
|
15
|
-
Execute with:
|
16
|
-
rake churn #after adding require 'lib/tasks/churn_tasks' to projects rakefile
|
17
|
-
churn
|
18
|
-
|
19
|
-
== Example Output
|
20
|
-
**********************************************************************
|
21
|
-
* Revision Changes
|
22
|
-
**********************************************************************
|
23
|
-
Files:
|
24
|
-
+-------------------------------+
|
25
|
-
| file |
|
26
|
-
+-------------------------------+
|
27
|
-
| Rakefile |
|
28
|
-
| lib/churn/churn_calculator.rb |
|
29
|
-
+-------------------------------+
|
30
|
-
|
31
|
-
Classes:
|
32
|
-
+-------------------------------+-----------------+
|
33
|
-
| file | klass |
|
34
|
-
+-------------------------------+-----------------+
|
35
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator |
|
36
|
-
+-------------------------------+-----------------+
|
37
|
-
|
38
|
-
Methods:
|
39
|
-
+-------------------------------+-----------------+-------------------------------+
|
40
|
-
| file | klass | method |
|
41
|
-
+-------------------------------+-----------------+-------------------------------+
|
42
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#filters |
|
43
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#display_array |
|
44
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#to_s |
|
45
|
-
+-------------------------------+-----------------+-------------------------------+
|
46
|
-
|
47
|
-
**********************************************************************
|
48
|
-
* Project Churn
|
49
|
-
**********************************************************************
|
50
|
-
Files:
|
51
|
-
+------------------------------------+---------------+
|
52
|
-
| file_path | times_changed |
|
53
|
-
+------------------------------------+---------------+
|
54
|
-
| lib/churn/churn_calculator.rb | 14 |
|
55
|
-
| README.rdoc | 7 |
|
56
|
-
| lib/tasks/churn_tasks.rb | 6 |
|
57
|
-
| Rakefile | 6 |
|
58
|
-
| lib/churn/git_analyzer.rb | 4 |
|
59
|
-
| VERSION | 4 |
|
60
|
-
| test/test_helper.rb | 4 |
|
61
|
-
| test/unit/churn_calculator_test.rb | 3 |
|
62
|
-
| test/churn_test.rb | 3 |
|
63
|
-
+------------------------------------+---------------+
|
64
|
-
|
65
|
-
Classes:
|
66
|
-
+-------------------------------+-----------------+---------------+
|
67
|
-
| file | klass | times_changed |
|
68
|
-
+-------------------------------+-----------------+---------------+
|
69
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | 1 |
|
70
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | 1 |
|
71
|
-
+-------------------------------+-----------------+---------------+
|
72
|
-
|
73
|
-
Methods:
|
74
|
-
+-------------------------------+-----------------+-----------------------------------------+---------------+
|
75
|
-
| file | klass | method | times_changed |
|
76
|
-
+-------------------------------+-----------------+-----------------------------------------+---------------+
|
77
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#to_s | 1 |
|
78
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#display_array | 1 |
|
79
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#calculate_revision_data | 1 |
|
80
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#filters | 1 |
|
81
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#initialize | 1 |
|
82
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#filters | 1 |
|
83
|
-
| lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#to_s | 1 |
|
84
|
-
+-------------------------------+-----------------+-----------------------------------------+---------------+
|
85
|
-
|
86
|
-
|
87
|
-
TODO:
|
88
|
-
* SVN only supports file, add full SVN support
|
89
|
-
* support bazaar, cvs, and darcs
|
90
|
-
* make storage directory configurable instead of using tmp
|
91
|
-
* allow passing in directories to churn, directories to ignore
|
92
|
-
* add a filter that allows for other files besides. *.rb
|
93
|
-
* ignore files pattern, so you can ignore things like vendor/, lib/, or docs/
|
94
|
-
* finish adding better documenation using YARD
|
95
|
-
* better man page formatting from README (switch to markdown?)
|
96
|
-
* rake task for building manpage (currently manually run ronn -b1 README.rdoc)
|
97
|
-
* bug that reports '/dev/null' as a file during revision changes
|
98
|
-
* don't output methods and classes on a commit that has none detected (css and view only commits, etc)
|
99
|
-
|
100
|
-
Executable Usage:
|
101
|
-
* 'gem install churn'
|
102
|
-
* go to project root run 'churn'
|
103
|
-
|
104
|
-
Rake Usage:
|
105
|
-
* 'gem install churn'
|
106
|
-
* on any project you want to use churn, add "require 'churn'" to your rake file
|
107
|
-
* run 'rake churn' to view the current output, file churn history is immediate, class and method churn builds up a history as it is run on each revision
|
108
|
-
* temporary files with class / method churn history are stored in /tmp, to clear churn history delete them
|
109
|
-
|
110
|
-
== Note on Patches/Pull Requests
|
111
|
-
|
112
|
-
* Fork the project.
|
113
|
-
* Make your feature addition or bug fix.
|
114
|
-
* Add tests for it. This is important so I don't break it in a
|
115
|
-
future version unintentionally.
|
116
|
-
* Commit, do not mess with rakefile, version, or history.
|
117
|
-
(if you want to have your own version, that is fine but
|
118
|
-
bump version in a commit by itself I can ignore when I pull)
|
119
|
-
* Send me a pull request. Bonus points for topic branches.
|
120
|
-
|
121
|
-
== Copyright
|
122
|
-
|
123
|
-
Copyright (c) 2010 Dan Mayer. See LICENSE for details.
|