churn 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +2 -1
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +44 -38
  5. data/README.md +7 -7
  6. data/bin/churn +0 -1
  7. data/churn.gemspec +15 -14
  8. data/doc/Churn.html +165 -0
  9. data/doc/Churn/BzrAnalyzer.html +276 -0
  10. data/doc/Churn/ChurnCalculator.html +578 -0
  11. data/doc/Churn/ChurnHistory.html +250 -0
  12. data/doc/Churn/ChurnOptions.html +393 -0
  13. data/doc/Churn/GitAnalyzer.html +311 -0
  14. data/doc/Churn/HgAnalyzer.html +276 -0
  15. data/doc/Churn/LocationMapping.html +448 -0
  16. data/doc/Churn/SourceControl.html +451 -0
  17. data/doc/Churn/SvnAnalyzer.html +311 -0
  18. data/doc/LICENSE.html +123 -0
  19. data/doc/Object.html +246 -0
  20. data/doc/created.rid +15 -0
  21. data/doc/images/add.png +0 -0
  22. data/doc/images/arrow_up.png +0 -0
  23. data/doc/images/brick.png +0 -0
  24. data/doc/images/brick_link.png +0 -0
  25. data/doc/images/bug.png +0 -0
  26. data/doc/images/bullet_black.png +0 -0
  27. data/doc/images/bullet_toggle_minus.png +0 -0
  28. data/doc/images/bullet_toggle_plus.png +0 -0
  29. data/doc/images/date.png +0 -0
  30. data/doc/images/delete.png +0 -0
  31. data/doc/images/find.png +0 -0
  32. data/doc/images/loadingAnimation.gif +0 -0
  33. data/doc/images/macFFBgHack.png +0 -0
  34. data/doc/images/package.png +0 -0
  35. data/doc/images/page_green.png +0 -0
  36. data/doc/images/page_white_text.png +0 -0
  37. data/doc/images/page_white_width.png +0 -0
  38. data/doc/images/plugin.png +0 -0
  39. data/doc/images/ruby.png +0 -0
  40. data/doc/images/tag_blue.png +0 -0
  41. data/doc/images/tag_green.png +0 -0
  42. data/doc/images/transparent.png +0 -0
  43. data/doc/images/wrench.png +0 -0
  44. data/doc/images/wrench_orange.png +0 -0
  45. data/doc/images/zoom.png +0 -0
  46. data/doc/index.html +100 -0
  47. data/doc/js/darkfish.js +155 -0
  48. data/doc/js/jquery.js +18 -0
  49. data/doc/js/navigation.js +142 -0
  50. data/doc/js/search.js +94 -0
  51. data/doc/js/search_index.js +1 -0
  52. data/doc/js/searcher.js +228 -0
  53. data/doc/rdoc.css +595 -0
  54. data/doc/table_of_contents.html +167 -0
  55. data/lib/churn/calculator.rb +43 -43
  56. data/lib/churn/options.rb +3 -3
  57. data/lib/churn/scm/bzr_analyzer.rb +6 -2
  58. data/lib/churn/scm/git_analyzer.rb +19 -5
  59. data/lib/churn/scm/hg_analyzer.rb +5 -1
  60. data/lib/churn/scm/source_control.rb +15 -15
  61. data/lib/churn/scm/svn_analyzer.rb +5 -0
  62. data/lib/churn/version.rb +1 -1
  63. data/lib/tasks/churn_tasks.rb +1 -1
  64. data/test/data/churn_calculator.rb +14 -14
  65. data/test/data/test_helper.rb +5 -5
  66. data/test/test_helper.rb +5 -5
  67. data/test/unit/bzr_analyzer_test.rb +2 -2
  68. data/test/unit/churn_calculator_test.rb +1 -1
  69. data/test/unit/churn_history_test.rb +5 -5
  70. data/test/unit/churn_options_test.rb +3 -3
  71. data/test/unit/git_analyzer_test.rb +3 -3
  72. data/test/unit/hg_analyzer_test.rb +2 -2
  73. data/test/unit/location_mapping_test.rb +2 -2
  74. data/test/unit/source_control_test.rb +3 -3
  75. data/test/unit/svn_analyzer_test.rb +3 -3
  76. metadata +94 -76
@@ -0,0 +1,167 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
6
+
7
+ <title>Table of Contents - RDoc Documentation</title>
8
+
9
+ <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet">
10
+
11
+ <script type="text/javascript">
12
+ var rdoc_rel_prefix = "./";
13
+ </script>
14
+
15
+ <script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script>
16
+ <script type="text/javascript" charset="utf-8" src="./js/navigation.js"></script>
17
+ <script type="text/javascript" charset="utf-8" src="./js/search_index.js"></script>
18
+ <script type="text/javascript" charset="utf-8" src="./js/search.js"></script>
19
+ <script type="text/javascript" charset="utf-8" src="./js/searcher.js"></script>
20
+ <script type="text/javascript" charset="utf-8" src="./js/darkfish.js"></script>
21
+
22
+
23
+ <body class="indexpage">
24
+ <h1>Table of Contents - RDoc Documentation</h1>
25
+
26
+ <h2>Pages</h2>
27
+ <ul>
28
+ <li class="file">
29
+ <a href="LICENSE.html">LICENSE</a>
30
+ </li>
31
+
32
+ </ul>
33
+
34
+ <h2 id="classes">Classes/Modules</h2>
35
+ <ul>
36
+ <li class="module">
37
+ <a href="Churn.html">Churn</a>
38
+ </li>
39
+ <li class="class">
40
+ <a href="Churn/BzrAnalyzer.html">Churn::BzrAnalyzer</a>
41
+ </li>
42
+ <li class="class">
43
+ <a href="Churn/ChurnCalculator.html">Churn::ChurnCalculator</a>
44
+ </li>
45
+ <li class="class">
46
+ <a href="Churn/ChurnHistory.html">Churn::ChurnHistory</a>
47
+ </li>
48
+ <li class="class">
49
+ <a href="Churn/ChurnOptions.html">Churn::ChurnOptions</a>
50
+ </li>
51
+ <li class="class">
52
+ <a href="Churn/GitAnalyzer.html">Churn::GitAnalyzer</a>
53
+ </li>
54
+ <li class="class">
55
+ <a href="Churn/HgAnalyzer.html">Churn::HgAnalyzer</a>
56
+ </li>
57
+ <li class="class">
58
+ <a href="Churn/LocationMapping.html">Churn::LocationMapping</a>
59
+ </li>
60
+ <li class="class">
61
+ <a href="Churn/SourceControl.html">Churn::SourceControl</a>
62
+ </li>
63
+ <li class="class">
64
+ <a href="Churn/SvnAnalyzer.html">Churn::SvnAnalyzer</a>
65
+ </li>
66
+ <li class="class">
67
+ <a href="Object.html">Object</a>
68
+ </li>
69
+
70
+ </ul>
71
+
72
+ <h2 id="methods">Methods</h2>
73
+ <ul>
74
+
75
+ <li class="method"><a href="Churn/ChurnHistory.html#method-c-load_revision_data">::load_revision_data &mdash; Churn::ChurnHistory</a>
76
+
77
+ <li class="method"><a href="Churn/LocationMapping.html#method-c-new">::new &mdash; Churn::LocationMapping</a>
78
+
79
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-c-new">::new &mdash; Churn::ChurnCalculator</a>
80
+
81
+ <li class="method"><a href="Churn/SourceControl.html#method-c-new">::new &mdash; Churn::SourceControl</a>
82
+
83
+ <li class="method"><a href="Churn/ChurnOptions.html#method-c-new">::new &mdash; Churn::ChurnOptions</a>
84
+
85
+ <li class="method"><a href="Churn/SourceControl.html#method-c-set_source_control">::set_source_control &mdash; Churn::SourceControl</a>
86
+
87
+ <li class="method"><a href="Churn/ChurnHistory.html#method-c-store_revision_history">::store_revision_history &mdash; Churn::ChurnHistory</a>
88
+
89
+ <li class="method"><a href="Churn/BzrAnalyzer.html#method-c-supported-3F">::supported? &mdash; Churn::BzrAnalyzer</a>
90
+
91
+ <li class="method"><a href="Churn/HgAnalyzer.html#method-c-supported-3F">::supported? &mdash; Churn::HgAnalyzer</a>
92
+
93
+ <li class="method"><a href="Churn/SourceControl.html#method-c-supported-3F">::supported? &mdash; Churn::SourceControl</a>
94
+
95
+ <li class="method"><a href="Churn/GitAnalyzer.html#method-c-supported-3F">::supported? &mdash; Churn::GitAnalyzer</a>
96
+
97
+ <li class="method"><a href="Churn/SvnAnalyzer.html#method-c-supported-3F">::supported? &mdash; Churn::SvnAnalyzer</a>
98
+
99
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-c-to_s">::to_s &mdash; Churn::ChurnCalculator</a>
100
+
101
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-i-analyze">#analyze &mdash; Churn::ChurnCalculator</a>
102
+
103
+ <li class="method"><a href="Churn/LocationMapping.html#method-i-analyze_list">#analyze_list &mdash; Churn::LocationMapping</a>
104
+
105
+ <li class="method"><a href="Churn/LocationMapping.html#method-i-deep_last_line">#deep_last_line &mdash; Churn::LocationMapping</a>
106
+
107
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-i-emit">#emit &mdash; Churn::ChurnCalculator</a>
108
+
109
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-i-generate_history">#generate_history &mdash; Churn::ChurnCalculator</a>
110
+
111
+ <li class="method"><a href="Churn/GitAnalyzer.html#method-i-get_commit_history">#get_commit_history &mdash; Churn::GitAnalyzer</a>
112
+
113
+ <li class="method"><a href="Churn/LocationMapping.html#method-i-get_info">#get_info &mdash; Churn::LocationMapping</a>
114
+
115
+ <li class="method"><a href="Churn/SvnAnalyzer.html#method-i-get_logs">#get_logs &mdash; Churn::SvnAnalyzer</a>
116
+
117
+ <li class="method"><a href="Churn/HgAnalyzer.html#method-i-get_logs">#get_logs &mdash; Churn::HgAnalyzer</a>
118
+
119
+ <li class="method"><a href="Churn/BzrAnalyzer.html#method-i-get_logs">#get_logs &mdash; Churn::BzrAnalyzer</a>
120
+
121
+ <li class="method"><a href="Churn/GitAnalyzer.html#method-i-get_logs">#get_logs &mdash; Churn::GitAnalyzer</a>
122
+
123
+ <li class="method"><a href="Churn/SourceControl.html#method-i-get_logs">#get_logs &mdash; Churn::SourceControl</a>
124
+
125
+ <li class="method"><a href="Churn/BzrAnalyzer.html#method-i-get_revisions">#get_revisions &mdash; Churn::BzrAnalyzer</a>
126
+
127
+ <li class="method"><a href="Churn/GitAnalyzer.html#method-i-get_revisions">#get_revisions &mdash; Churn::GitAnalyzer</a>
128
+
129
+ <li class="method"><a href="Churn/SourceControl.html#method-i-get_revisions">#get_revisions &mdash; Churn::SourceControl</a>
130
+
131
+ <li class="method"><a href="Churn/SvnAnalyzer.html#method-i-get_revisions">#get_revisions &mdash; Churn::SvnAnalyzer</a>
132
+
133
+ <li class="method"><a href="Churn/HgAnalyzer.html#method-i-get_revisions">#get_revisions &mdash; Churn::HgAnalyzer</a>
134
+
135
+ <li class="method"><a href="Churn/SourceControl.html#method-i-get_updated_files_change_info">#get_updated_files_change_info &mdash; Churn::SourceControl</a>
136
+
137
+ <li class="method"><a href="Churn/SvnAnalyzer.html#method-i-get_updated_files_change_info">#get_updated_files_change_info &mdash; Churn::SvnAnalyzer</a>
138
+
139
+ <li class="method"><a href="Churn/SourceControl.html#method-i-get_updated_files_from_log">#get_updated_files_from_log &mdash; Churn::SourceControl</a>
140
+
141
+ <li class="method"><a href="Churn/LocationMapping.html#method-i-process_class">#process_class &mdash; Churn::LocationMapping</a>
142
+
143
+ <li class="method"><a href="Churn/LocationMapping.html#method-i-process_defn">#process_defn &mdash; Churn::LocationMapping</a>
144
+
145
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-i-remote_report">#remote_report &mdash; Churn::ChurnCalculator</a>
146
+
147
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-i-report">#report &mdash; Churn::ChurnCalculator</a>
148
+
149
+ <li class="method"><a href="Object.html#method-i-report_churn">#report_churn &mdash; Object</a>
150
+
151
+ <li class="method"><a href="Object.html#method-i-run">#run &mdash; Object</a>
152
+
153
+ <li class="method"><a href="Churn/ChurnOptions.html#method-i-set_options">#set_options &mdash; Churn::ChurnOptions</a>
154
+
155
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-i-to_h">#to_h &mdash; Churn::ChurnCalculator</a>
156
+
157
+ <li class="method"><a href="Churn/ChurnCalculator.html#method-i-to_s">#to_s &mdash; Churn::ChurnCalculator</a>
158
+
159
+ </ul>
160
+
161
+
162
+ <footer id="validator-badges">
163
+ <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
164
+ <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 4.0.1.
165
+ <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
166
+ </footer>
167
+
@@ -20,16 +20,18 @@ require 'options'
20
20
  module Churn
21
21
 
22
22
  # The work horse of the the churn library.
23
- # This class takes user input, determins the SCM the user is using.
23
+ # This class takes user input, determines the SCM the user is using.
24
24
  # It then determines changes made during this revision.
25
- # Finally it reads all the changes from previous revisions and displays human readable output on the command line.
26
- # It can also ouput a yaml format readable by other tools such as metric_fu and Caliper.
25
+ # Finally it reads all the changes from previous revisions and displays human
26
+ # readable output on the command line.
27
+ # It can also output a yaml format readable by other tools such as metric_fu
28
+ # and Caliper.
27
29
  class ChurnCalculator
28
30
 
29
- # intialized the churn calculator object
31
+ # intialize the churn calculator object
30
32
  def initialize(options={})
31
33
  @churn_options = ChurnOptions.new.set_options(options)
32
-
34
+
33
35
  @minimum_churn_count = @churn_options.minimum_churn_count
34
36
  @ignores = @churn_options.ignores
35
37
  @source_control = SourceControl.set_source_control(@churn_options.start_date)
@@ -41,9 +43,11 @@ module Churn
41
43
  end
42
44
 
43
45
  # prepares the data for the given project to be reported.
44
- # reads git/svn logs analyzes the output, generates a report and either formats as a nice string or returns hash.
45
- # @param [Bolean] format to return the data, true for string or false for hash
46
- # @return [Object] returns either a pretty string or a hash representing the chrun of the project
46
+ # reads git/svn logs analyzes the output, generates a report and either
47
+ # formats as a nice string or returns hash.
48
+ # @param [Boolean] format to return the data, true for string or false for hash
49
+ # @return [Object] returns either a pretty string or a hash representing the
50
+ # churn of the project
47
51
  def report(print = true)
48
52
  if @churn_options.history
49
53
  generate_history
@@ -58,44 +62,31 @@ module Churn
58
62
  def remote_report
59
63
  if @churn_options.report_host
60
64
  puts "posting churn results to #{@churn_options.report_host}"
61
- data = {:name => @churn_options.name, :revision => @revisions.first, :data => self.to_h}.to_json
65
+ data = {:name => @churn_options.name, :revision => @revisions.first, :data => self.to_h}.to_json
62
66
  RestClient.post @churn_options.report_host, {"results" => data}, :content_type => :json, :accept => :json
63
67
  end
64
68
  rescue Errno::ECONNREFUSED
65
69
  puts "error posting churn results connection refused to host: #{@churn_options.report_host}"
66
70
  end
67
71
 
68
- # this method generates the past history of a churn project from first commit to current
69
- # running the report for oldest commits first so they are built up correctly
72
+ # this method generates the past history of a churn project from first
73
+ # commit to current running the report for oldest commits first so they
74
+ # are built up correctly
70
75
  def generate_history
71
- if @source_control.is_a?(GitAnalyzer)
72
- begin
73
- history_starting_point = Chronic.parse(@churn_options.history)
74
- @source_control.get_commit_history.each do |commit|
75
- `git checkout #{commit}`
76
- commit_date = `git show -s --format="%ci"`
77
- commit_date = Time.parse(commit_date)
78
- next if commit_date < history_starting_point
79
- #7776000 == 3.months without adding active support depenancy
80
- start_date = (commit_date - 7776000)
81
- `churn -s "#{start_date}"`
82
- end
83
- ensure
84
- `git checkout master`
85
- end
86
- "churn history complete, this has munipulated git please make sure you are back on HEAD where you expect to be"
87
- else
88
- raise "currently generate history only supports git"
89
- end
76
+ history_starting_point = Chronic.parse(@churn_options.history)
77
+ @source_control.generate_history(history_starting_point)
78
+ "churn history complete, this has manipulated your source control system so please make sure you are back on HEAD where you expect to be"
90
79
  end
91
80
 
92
- # Emits various data from source control to be analyses later... Currently this is broken up like this as a throwback to metric_fu
81
+ # Emits various data from source control to be analyzed later...
82
+ # Currently this is broken up like this as a throwback to metric_fu
93
83
  def emit
94
- @changes = parse_log_for_changes.reject {|file, change_count| change_count < @minimum_churn_count || @ignores.any?{ |ignore| file.match(/#{ignore}/) } }
84
+ @changes = reject_ignored_files(reject_low_churn_files(parse_log_for_changes))
95
85
  @revisions = parse_log_for_revision_changes
96
86
  end
97
87
 
98
- # Analyze the source control data, filter, sort, and find more information on the editted files
88
+ # Analyze the source control data, filter, sort, and find more information
89
+ # on the edited files
99
90
  def analyze
100
91
  @changes = sort_changes(@changes)
101
92
  @changes = @changes.map {|file_path, times_changed| {:file_path => file_path, :times_changed => times_changed }}
@@ -122,7 +113,8 @@ module Churn
122
113
  hash[:churn][:changed_classes] = changes[:classes]
123
114
  hash[:churn][:changed_methods] = changes[:methods]
124
115
  end
125
- #TODO crappy place to do this but save hash to revision file but while entirely under metric_fu only choice
116
+ # TODO crappy place to do this but save hash to revision file but
117
+ # while entirely under metric_fu only choice
126
118
  ChurnHistory.store_revision_history(first_revision, hash, @churn_options.data_directory)
127
119
  hash
128
120
  end
@@ -133,17 +125,17 @@ module Churn
133
125
 
134
126
  # Pretty print the data as a string for the user
135
127
  def self.to_s(hash)
136
- result = seperator
128
+ result = separator
137
129
  result +="* Revision Changes \n"
138
- result += seperator
130
+ result += separator
139
131
  result += display_array("Files", hash[:changed_files], :fields=>[:to_str], :headers=>{:to_str=>'file'})
140
132
  result += "\n"
141
133
  result += display_array("Classes", hash[:changed_classes])
142
134
  result += "\n"
143
135
  result += display_array("Methods", hash[:changed_methods]) + "\n"
144
- result += seperator
136
+ result += separator
145
137
  result +="* Project Churn \n"
146
- result += seperator
138
+ result += separator
147
139
  result += "\n"
148
140
  result += display_array("Files", hash[:changes])
149
141
  result += "\n"
@@ -178,7 +170,7 @@ module Churn
178
170
  response
179
171
  end
180
172
 
181
- def self.seperator
173
+ def self.separator
182
174
  "*"*70+"\n"
183
175
  end
184
176
 
@@ -205,7 +197,7 @@ module Churn
205
197
  changed_classes = []
206
198
  changed_methods = []
207
199
  changed_files.each do |file_changes|
208
- if file_changes.first.match(filters)
200
+ if file_changes.first =~ filters
209
201
  classes, methods = get_changes(file_changes)
210
202
  changed_classes += classes
211
203
  changed_methods += methods
@@ -256,11 +248,11 @@ module Churn
256
248
  end
257
249
 
258
250
  def parse_log_for_changes
259
- changes = {}
251
+ changes = Hash.new(0)
260
252
 
261
253
  logs = @source_control.get_logs
262
254
  logs.each do |line|
263
- changes[line] ? changes[line] += 1 : changes[line] = 1
255
+ changes[line] += 1
264
256
  end
265
257
  changes
266
258
  end
@@ -271,7 +263,15 @@ module Churn
271
263
 
272
264
  def parse_logs_for_updated_files(revision, revisions)
273
265
  files = @source_control.get_updated_files_change_info(revision, revisions)
274
- files.select{ |file, value| !@ignores.any?{ |ignore| file.match(/#{ignore}/) } }
266
+ reject_ignored_files(files)
267
+ end
268
+
269
+ def reject_low_churn_files(files)
270
+ files.reject{ |_, change_count| change_count < @minimum_churn_count }
271
+ end
272
+
273
+ def reject_ignored_files(files)
274
+ files.reject{ |file, _| @ignores.any?{ |ignore| /#{ignore}/ =~ file } }
275
275
  end
276
276
 
277
277
  end
@@ -1,7 +1,7 @@
1
1
  require 'singleton'
2
2
 
3
3
  module Churn
4
-
4
+
5
5
  # responsible for storing the churn configuration
6
6
  class ChurnOptions
7
7
  DEFAULT_CHURN_DIRECTORY = "tmp/churn"
@@ -31,7 +31,7 @@ module Churn
31
31
  if @history=='true'
32
32
  @history = DEFAULT_START_TIME
33
33
  end
34
- if !options[:report].nil? && options[:report]!=''
34
+ if !options[:report].nil? && options[:report]!=''
35
35
  @report_host = options[:report]
36
36
  if @report_host=='true'
37
37
  @report_host = DEFAULT_REPORT_HOST
@@ -45,7 +45,7 @@ module Churn
45
45
 
46
46
  self
47
47
  end
48
-
48
+
49
49
  end
50
50
 
51
51
  end
@@ -2,7 +2,7 @@ module Churn
2
2
 
3
3
  #analizes Bzr / Bazaar SCM to find recently changed files, and what lines have been altered
4
4
  class BzrAnalyzer < SourceControl
5
-
5
+
6
6
  def self.supported?
7
7
  !!(`bzr nick 2>&1` && $?.success?)
8
8
  end
@@ -15,10 +15,14 @@ module Churn
15
15
  `bzr log --line #{date_range}`.split("\n").map{|line| line[/^(\S+):/, 1] }
16
16
  end
17
17
 
18
+ def generate_history(starting_point)
19
+ raise "currently the generate history option does not support bazaar"
20
+ end
21
+
18
22
  private
19
23
 
20
24
  def get_diff(revision, previous_revision)
21
- `bzr diff -r #{previous_revision}..#{revision}`.split(/\n/).select{|line| line.match(/^@@/) || line.match(/^---/) || line.match(/^\+\+\+/) }
25
+ `bzr diff -r #{previous_revision}..#{revision}`.split(/\n/).select{|line| /^@@|^---|^\+\+\+/ =~ line }
22
26
  end
23
27
 
24
28
  def date_range
@@ -10,19 +10,33 @@ module Churn
10
10
  def get_logs
11
11
  `git log #{date_range} --name-only --pretty=format:`.split(/\n/).reject{|line| line == ""}
12
12
  end
13
-
13
+
14
14
  def get_revisions
15
15
  `git log #{date_range} --pretty=format:"%H"`.split(/\n/).reject{|line| line == ""}
16
16
  end
17
17
 
18
+ def generate_history(starting_point)
19
+ get_commit_history.each do |commit|
20
+ `git checkout #{commit}`
21
+ commit_date = `git show -s --format="%ci"`
22
+ commit_date = Time.parse(commit_date)
23
+ next if commit_date < starting_point
24
+ #7776000 == 3.months without adding active support depenancy
25
+ start_date = (commit_date - 7776000)
26
+ `churn -s "#{start_date}"`
27
+ end
28
+ ensure
29
+ `git checkout master`
30
+ end
31
+
32
+ private
33
+
18
34
  def get_commit_history
19
35
  `git log --reverse --pretty=format:"%H"`.split(/\n/).reject{|line| line == ""}
20
36
  end
21
-
22
- private
23
37
 
24
38
  def get_diff(revision, previous_revision)
25
- `git diff #{revision} #{previous_revision} --unified=0`.split(/\n/).select{|line| line.match(/^@@/) || line.match(/^---/) || line.match(/^\+\+\+/) }
39
+ `git diff #{revision} #{previous_revision} --unified=0`.split(/\n/).select{|line| /^@@|^---|^\+\+\+/ =~ line }
26
40
  end
27
41
 
28
42
  def date_range
@@ -31,6 +45,6 @@ module Churn
31
45
  "--after=#{date.strftime('%Y-%m-%d')}"
32
46
  end
33
47
  end
34
-
48
+
35
49
  end
36
50
  end
@@ -15,10 +15,14 @@ module Churn
15
15
  `hg log#{date_range}`.split("\n").reject{|line| line !~ /^changeset:/}.map{|line| line[/:(\S+)$/, 1] }
16
16
  end
17
17
 
18
+ def generate_history(starting_point)
19
+ raise "currently the generate history option does not support mercurial"
20
+ end
21
+
18
22
  private
19
23
 
20
24
  def get_diff(revision, previous_revision)
21
- `hg diff -r #{revision}:#{previous_revision} -U 0`.split(/\n/).select{|line| line.match(/^@@/) || line.match(/^---/) || line.match(/^\+\+\+/) }
25
+ `hg diff -r #{revision}:#{previous_revision} -U 0`.split(/\n/).select{|line| /^@@|^---|^\+\+\+/ =~ line }
22
26
  end
23
27
 
24
28
  def date_range