churn 0.0.29 → 0.0.30

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -6,4 +6,5 @@ pkg
6
6
  tmp
7
7
  .rvmrc
8
8
  .bundle
9
- specs
9
+ specs
10
+ .yardoc/
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- churn (0.0.29)
4
+ churn (0.0.30)
5
5
  chronic (>= 0.2.3)
6
6
  hirb
7
7
  json_pure
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- __churn__
1
+ Churn
2
+ ===
2
3
 
3
4
  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 churns to give the number of times a file, class, or method is changing during the life of a project.
4
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
@@ -13,13 +14,14 @@ Authors:
13
14
  * absurdhero
14
15
  * bf4
15
16
 
16
- __CI Build Status__
17
+ ## CI Build Status
17
18
 
18
19
  [![Build Status](https://secure.travis-ci.org/danmayer/churn.png)](http://travis-ci.org/danmayer/churn)
19
20
 
20
21
  This project runs [travis-ci.org](http://travis-ci.org)
21
22
 
22
- __Churn Usage__
23
+ ## Churn Usage
24
+
23
25
  Install with `gem install churn` or for bundler add to your Gemfile `gem 'churn', :require => false`.
24
26
 
25
27
  The reason you want require false is that when required by default churn is expecting to add some rake tasks, you don't really want or need it loading when running your server or tests. Previous versions required this change, churn will now do the right thing if you forget to add `require => false`.
@@ -45,7 +47,7 @@ The reason you want require false is that when required by default churn is expe
45
47
  churn --start_date "6 months ago" #Start looking at file changes from 6 months ago
46
48
 
47
49
 
48
- __Example Output__
50
+ ## Example Output
49
51
 
50
52
  **********************************************************************
51
53
  * Revision Changes
@@ -113,7 +115,7 @@ __Example Output__
113
115
  | lib/churn/churn_calculator.rb | ChurnCalculator | ChurnCalculator#to_s | 1 |
114
116
  +-------------------------------+-----------------+-----------------------------------------+---------------+
115
117
 
116
- __Options__
118
+ ## Options
117
119
 
118
120
  [~/projects/churn] churn -h
119
121
  NAME
@@ -129,20 +131,13 @@ __Options__
129
131
  --start_date=[start_date], -s (0 ~> string(start_date=))
130
132
  --help, -h
131
133
 
132
- __TODO:__
134
+ ## TODO
135
+
136
+ The list of items has been moved to the [churn wafflie.io](http://waffle.io/danmayer/churn)
133
137
 
134
- * SVN only supports file, add full SVN support (method and line numbers)
135
- * add support for cvs, and darcs
136
- * make storage directory configurable instead of using tmp
137
- * allow passing in directories to churn
138
- * add a filter that allows for other files besides. *.rb to get method/class checks
139
- * improve line number matching for Ruby files
140
- * add line number matching for other langauges
141
- * finish adding better documenation using YARD
142
- * rake task for building manpage (currently manually run `ronn -b1 README.rdoc`)
143
- * don't output methods and classes on a commit that has none detected (css and view only commits, etc)
138
+ [![Stories in Ready](https://badge.waffle.io/danmayer/churn.png)](http://waffle.io/danmayer/churn)
144
139
 
145
- __Notes on Patches/Pull Requests__
140
+ ## Notes on Patches/Pull Requests
146
141
 
147
142
  * Fork the project.
148
143
  * Make your feature addition or bug fix.
@@ -153,6 +148,6 @@ __Notes on Patches/Pull Requests__
153
148
  bump version in a commit by itself I can ignore when I pull)
154
149
  * Send me a pull request. Bonus points for topic branches.
155
150
 
156
- __Copyright__
151
+ ## Copyright
157
152
 
158
153
  Copyright (c) 2013 Dan Mayer. See LICENSE for details.
data/bin/churn CHANGED
@@ -27,9 +27,15 @@ Main do
27
27
  default ''
28
28
  end
29
29
 
30
+ option('data_directory', 'd') do
31
+ cast :string
32
+ argument :optional
33
+ default ''
34
+ end
35
+
30
36
  def report_churn(output_string)
31
37
  require File.join(File.dirname(__FILE__), '..', 'lib', 'churn', 'churn_calculator')
32
- result = Churn::ChurnCalculator.new({:minimum_churn_count => params['minimum_churn_count'].value, :ignore_files => params['ignore_files'].value, :start_date => params['start_date'].value}).report(output_string)
38
+ result = Churn::ChurnCalculator.new({:minimum_churn_count => params['minimum_churn_count'].value, :ignore_files => params['ignore_files'].value, :start_date => params['start_date'].value, :data_directory => params['data_directory'].value}).report(output_string)
33
39
  unless output_string
34
40
  result = YAML::dump(result)
35
41
  end
@@ -13,22 +13,26 @@ require 'hg_analyzer'
13
13
  require 'bzr_analyzer'
14
14
  require 'location_mapping'
15
15
  require 'churn_history'
16
+ require 'churn_options'
16
17
 
17
18
  module Churn
18
19
 
19
- # The work horse of the the churn library. This class takes user input, determins the SCM the user is using. It then determines changes
20
- # made during this revision. Finally it reads all the changes from previous revisions and displays human readable output to the command
21
- # line. It can also ouput a yaml format readable by other tools such as metric_fu and Caliper.
20
+ # The work horse of the the churn library.
21
+ # This class takes user input, determins the SCM the user is using.
22
+ # It then determines changes made during this revision.
23
+ # Finally it reads all the changes from previous revisions and displays human readable output on the command line.
24
+ # It can also ouput a yaml format readable by other tools such as metric_fu and Caliper.
22
25
  class ChurnCalculator
23
26
 
24
27
  # intialized the churn calculator object
25
28
  def initialize(options={})
26
- options[:start_date]=nil if options[:start_date]==''
27
- start_date = options.fetch(:start_date) { '3 months ago' }
28
- @minimum_churn_count = options.fetch(:minimum_churn_count) { 5 }.to_i
29
- @ignore_files = (options.fetch(:ignore_files){ "" }).to_s.split(',').map(&:strip)
30
- @ignore_files << '/dev/null'
31
- @source_control = set_source_control(start_date)
29
+ @churn_options = ChurnOptions.instance.set_options(options)
30
+
31
+ @minimum_churn_count = @churn_options.minimum_churn_count
32
+ @ignore_files = @churn_options.ignore_files
33
+ start_date = @churn_options.start_date
34
+ @source_control = set_source_control(start_date)
35
+
32
36
  @changes = {}
33
37
  @revision_changes = {}
34
38
  @class_changes = {}
@@ -83,9 +87,7 @@ module Churn
83
87
  hash
84
88
  end
85
89
 
86
- # Pretty print the data as a string for the user
87
- def to_s
88
- hash = to_h[:churn]
90
+ def self.to_s(hash)
89
91
  result = seperator
90
92
  result +="* Revision Changes \n"
91
93
  result += seperator
@@ -108,6 +110,11 @@ module Churn
108
110
  result += display_array(method_churn)
109
111
  end
110
112
 
113
+ # Pretty print the data as a string for the user
114
+ def to_s
115
+ ChurnCalculator(to_h[:churn])
116
+ end
117
+
111
118
  private
112
119
 
113
120
  def collect_items(collection, match)
@@ -1,19 +1,19 @@
1
1
  module Churn
2
2
 
3
- # responcible for storing the churn history to json,
3
+ # responsible for storing the churn history to json,
4
4
  # and for loading old churn history data from json.
5
5
  class ChurnHistory
6
-
6
+
7
7
  #takes current revision and it's hash_data and stores it
8
8
  def self.store_revision_history(revision, hash_data)
9
- FileUtils.mkdir 'tmp' unless File.directory?('tmp')
10
- File.open("tmp/#{revision}.json", 'w') {|file| file.write(hash_data.to_json) }
9
+ FileUtils.mkdir_p tmp_churn_directory unless File.directory?(tmp_churn_directory)
10
+ File.open("#{tmp_churn_directory}/#{revision}.json", 'w') {|file| file.write(hash_data.to_json) }
11
11
  end
12
-
12
+
13
13
  #given a previous project revision find and load the churn data from a json file
14
14
  def self.load_revision_data(revision)
15
15
  #load revision data from scratch folder if it exists
16
- filename = "tmp/#{revision}.json"
16
+ filename = "#{tmp_churn_directory}/#{revision}.json"
17
17
  if File.exists?(filename)
18
18
  begin
19
19
  json_data = File.read(filename)
@@ -28,6 +28,10 @@ module Churn
28
28
  [changed_files, changed_classes, changed_methods]
29
29
  end
30
30
 
31
+ def self.tmp_churn_directory
32
+ ChurnOptions.instance.data_directory
33
+ end
34
+
31
35
  end
32
36
 
33
37
  end
@@ -1,3 +1,3 @@
1
1
  module Churn
2
- VERSION = "0.0.29"
2
+ VERSION = "0.0.30"
3
3
  end
@@ -0,0 +1,31 @@
1
+ require 'singleton'
2
+
3
+ module Churn
4
+
5
+ # responsible for storing the churn configuration
6
+ class ChurnOptions
7
+ include Singleton
8
+ DEFAULT_CHURN_DIRECTORY = "tmp/churn"
9
+ DEFAULT_MINIMUM_CHURN_COUNT = 5
10
+
11
+ attr_accessor :data_directory, :minimum_churn_count, :ignore_files, :start_date
12
+
13
+ def initialize()
14
+ @data_directory = DEFAULT_CHURN_DIRECTORY
15
+ @minimum_churn_count = DEFAULT_MINIMUM_CHURN_COUNT
16
+ @ignore_files = ['/dev/null']
17
+ @start_date = '3 months ago'
18
+ end
19
+
20
+ def set_options(options = {})
21
+ @data_directory = options.fetch(:data_directory){ @data_directory } unless options[:data_directory]==''
22
+ @minimum_churn_count = options.fetch(:minimum_churn_count){ @minimum_churn_count }.to_i
23
+ @ignore_files = (options.fetch(:ignore_files){ @ignore_files }).to_s.split(',').map(&:strip)
24
+ @ignore_files << '/dev/null' unless @ignore_files.include?('/dev/null')
25
+ @start_date = options[:start_date] if options[:start_date].nil? || options[:start_date]!=''
26
+ self
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -5,6 +5,7 @@ if defined?(RakeFileUtils) # self.respond_to?(:desc)
5
5
  { :minimum_churn_count => ENV['CHURN_MINIMUM_CHURN_COUNT'],
6
6
  :start_date => ENV['CHURN_START_DATE'],
7
7
  :ignore_files => ENV['CHURN_IGNORE_FILES'],
8
+ :data_directory => ENV['CHURN_DATA_DIRECTORY'],
8
9
  }.each {|k,v| params[k] = v unless v.nil? }
9
10
  Churn::ChurnCalculator.new(params).report
10
11
  end
@@ -5,15 +5,15 @@ class ChurnHistoryTest < Test::Unit::TestCase
5
5
  should "store results" do
6
6
  within_construct do |container|
7
7
  Churn::ChurnHistory.store_revision_history('aaa','data')
8
- assert File.exists?('tmp/aaa.json')
9
- data = File.read('tmp/aaa.json')
8
+ assert File.exists?('tmp/churn/aaa.json')
9
+ data = File.read('tmp/churn/aaa.json')
10
10
  assert data.match(/data/)
11
11
  end
12
12
  end
13
13
 
14
14
  should "restores results" do
15
15
  within_construct do |container|
16
- container.file('tmp/aaa.json', '{"churn":{"changes":[{"file_path":".gitignore","times_changed":2},{"file_path":"lib\/churn.rb","times_changed":2},{"file_path":"Rakefile","times_changed":2},{"file_path":"README.rdoc","times_changed":2},{"file_path":"lib\/churn\/source_control.rb","times_changed":1},{"file_path":"lib\/churn\/svn_analyzer.rb","times_changed":1},{"file_path":"lib\/tasks\/churn_tasks.rb","times_changed":1},{"file_path":"LICENSE","times_changed":1},{"file_path":"test\/churn_test.rb","times_changed":1},{"file_path":"lib\/churn\/locationmapping.rb","times_changed":1},{"file_path":"lib\/churn\/git_analyzer.rb","times_changed":1},{"file_path":".document","times_changed":1},{"file_path":"test\/test_helper.rb","times_changed":1},{"file_path":"lib\/churn\/churn_calculator.rb","times_changed":1}],"method_churn":[],"changed_files":[".gitignore","lib\/churn\/source_control.rb","lib\/tasks\/churn_tasks.rb","lib\/churn\/svn_analyzer.rb","Rakefile","README.rdoc","lib\/churn\/locationmapping.rb","lib\/churn\/git_analyzer.rb","\/dev\/null","lib\/churn\/churn_calculator.rb","lib\/churn.rb"],"class_churn":[],"changed_classes":[{"klass":"ChurnTest","file":"test\/churn_test.rb"},{"klass":"ChurnCalculator","file":"lib\/churn\/churn_calculator.rb"}],"changed_methods":[{"klass":"","method":"#report_churn","file":"lib\/tasks\/churn_tasks.rb"}]}}')
16
+ container.file('tmp/churn/aaa.json', '{"churn":{"changes":[{"file_path":".gitignore","times_changed":2},{"file_path":"lib\/churn.rb","times_changed":2},{"file_path":"Rakefile","times_changed":2},{"file_path":"README.rdoc","times_changed":2},{"file_path":"lib\/churn\/source_control.rb","times_changed":1},{"file_path":"lib\/churn\/svn_analyzer.rb","times_changed":1},{"file_path":"lib\/tasks\/churn_tasks.rb","times_changed":1},{"file_path":"LICENSE","times_changed":1},{"file_path":"test\/churn_test.rb","times_changed":1},{"file_path":"lib\/churn\/locationmapping.rb","times_changed":1},{"file_path":"lib\/churn\/git_analyzer.rb","times_changed":1},{"file_path":".document","times_changed":1},{"file_path":"test\/test_helper.rb","times_changed":1},{"file_path":"lib\/churn\/churn_calculator.rb","times_changed":1}],"method_churn":[],"changed_files":[".gitignore","lib\/churn\/source_control.rb","lib\/tasks\/churn_tasks.rb","lib\/churn\/svn_analyzer.rb","Rakefile","README.rdoc","lib\/churn\/locationmapping.rb","lib\/churn\/git_analyzer.rb","\/dev\/null","lib\/churn\/churn_calculator.rb","lib\/churn.rb"],"class_churn":[],"changed_classes":[{"klass":"ChurnTest","file":"test\/churn_test.rb"},{"klass":"ChurnCalculator","file":"lib\/churn\/churn_calculator.rb"}],"changed_methods":[{"klass":"","method":"#report_churn","file":"lib\/tasks\/churn_tasks.rb"}]}}')
17
17
  changed_files, changed_classes, changed_methods = Churn::ChurnHistory.load_revision_data('aaa')
18
18
  assert changed_files.include?("lib/churn/source_control.rb")
19
19
  assert_equal 2, changed_classes.length
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../test_helper', File.dirname(__FILE__))
2
+
3
+ class ChurnOptionsTest < Test::Unit::TestCase
4
+
5
+ should "store get default directory" do
6
+ assert_equal Churn::ChurnOptions::DEFAULT_CHURN_DIRECTORY, Churn::ChurnOptions.instance.data_directory
7
+ end
8
+
9
+ should "store get over ride directory" do
10
+ options = Churn::ChurnOptions.instance
11
+ tmp_dir = '/tmp/fake'
12
+ options.set_options({:data_directory => tmp_dir})
13
+ assert_equal tmp_dir, Churn::ChurnOptions.instance.data_directory
14
+ end
15
+
16
+ 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: 37
4
+ hash: 35
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 29
10
- version: 0.0.29
9
+ - 30
10
+ version: 0.0.30
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dan Mayer
@@ -208,6 +208,7 @@ files:
208
208
  - lib/churn/source_control.rb
209
209
  - lib/churn/svn_analyzer.rb
210
210
  - lib/churn/version.rb
211
+ - lib/churn_options.rb
211
212
  - lib/tasks/churn_tasks.rb
212
213
  - man/churn.1
213
214
  - man/churn.html
@@ -217,6 +218,7 @@ files:
217
218
  - test/unit/bzr_analyzer_test.rb
218
219
  - test/unit/churn_calculator_test.rb
219
220
  - test/unit/churn_history_test.rb
221
+ - test/unit/churn_options_test.rb
220
222
  - test/unit/git_analyzer_test.rb
221
223
  - test/unit/hg_analyzer_test.rb
222
224
  - test/unit/location_mapping_test.rb
@@ -260,6 +262,7 @@ test_files:
260
262
  - test/unit/bzr_analyzer_test.rb
261
263
  - test/unit/churn_calculator_test.rb
262
264
  - test/unit/churn_history_test.rb
265
+ - test/unit/churn_options_test.rb
263
266
  - test/unit/git_analyzer_test.rb
264
267
  - test/unit/hg_analyzer_test.rb
265
268
  - test/unit/location_mapping_test.rb