churn 0.0.25 → 0.0.26

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/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ tmp
7
+ .rvmrc
8
+ .bundle
9
+ specs
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source :rubygems
2
2
 
3
- #gemspec
3
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,43 +1,53 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- churn (0.0.24)
4
+ churn (0.0.26)
5
5
  chronic (>= 0.2.3)
6
6
  hirb
7
7
  json_pure
8
8
  main
9
- ruby_parser (~> 2.3)
10
- sexp_processor (~> 3.0)
9
+ ruby_parser (~> 3.1.0)
10
+ sexp_processor (~> 4.1.0)
11
11
 
12
12
  GEM
13
13
  remote: http://rubygems.org/
14
14
  specs:
15
+ activesupport (3.2.10)
16
+ i18n (~> 0.6)
17
+ multi_json (~> 1.0)
15
18
  arrayfields (4.7.4)
16
- chronic (0.7.0)
19
+ chronic (0.9.0)
17
20
  fattr (2.2.1)
18
21
  git (1.2.5)
19
22
  hirb (0.7.0)
23
+ i18n (0.6.1)
20
24
  jeweler (1.8.4)
21
25
  bundler (~> 1.0)
22
26
  git (>= 1.2.5)
23
27
  rake
24
28
  rdoc
25
- json (1.7.5)
26
- json_pure (1.7.5)
27
- main (5.1.0)
29
+ json (1.7.6)
30
+ json_pure (1.7.6)
31
+ main (5.1.1)
28
32
  arrayfields (>= 4.7.4)
29
33
  chronic (>= 0.6.2)
30
34
  fattr (>= 2.2.0)
31
35
  map (>= 5.1.0)
32
36
  map (6.2.0)
33
37
  mocha (0.9.12)
34
- rake (0.9.2.2)
38
+ multi_json (1.5.0)
39
+ rake (10.0.3)
35
40
  rdoc (3.12)
36
41
  json (~> 1.4)
37
- ruby_parser (2.3.1)
38
- sexp_processor (~> 3.0)
39
- sexp_processor (3.2.0)
40
- shoulda (2.11.3)
42
+ ruby_parser (3.1.1)
43
+ sexp_processor (~> 4.1)
44
+ sexp_processor (4.1.3)
45
+ shoulda (3.3.2)
46
+ shoulda-context (~> 1.0.1)
47
+ shoulda-matchers (~> 1.4.1)
48
+ shoulda-context (1.0.2)
49
+ shoulda-matchers (1.4.1)
50
+ activesupport (>= 3.0.0)
41
51
  test-construct (1.2.0)
42
52
 
43
53
  PLATFORMS
data/Rakefile CHANGED
@@ -2,70 +2,6 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require File.join(File.dirname(__FILE__), 'lib', 'tasks', 'churn_tasks')
4
4
 
5
- begin
6
- #Bug in jeweler or bundler to make jeweler
7
- #create a proper gemspec that doesn't have a circular dependancy
8
- # on itself uninstall churn
9
- # Then comment this line out of the Gemfile 'gemspec'
10
- # then rake gemspec
11
- require 'jeweler'
12
- Jeweler::Tasks.new do |gem|
13
- gem.name = "churn"
14
- gem.summary = %Q{Providing additional churn metrics over the original metric_fu churn}
15
- gem.description = %Q{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. }
16
- gem.email = "dan@mayerdan.com"
17
- gem.homepage = "http://github.com/danmayer/churn"
18
- gem.authors = ["Dan Mayer"]
19
- gem.executables = ['churn']
20
-
21
- gem.add_development_dependency "shoulda"
22
- gem.add_development_dependency "jeweler"
23
- gem.add_development_dependency "test-construct"
24
- gem.add_development_dependency "rake"
25
- gem.add_development_dependency "mocha", '~> 0.9.5'
26
- gem.add_dependency "main"
27
- gem.add_dependency "json_pure"
28
- gem.add_dependency "chronic", '>= 0.2.3'
29
- gem.add_dependency "sexp_processor", '~> 3.0'
30
- gem.add_dependency "ruby_parser", '~> 2.3'
31
- gem.add_dependency 'hirb'
32
- end
33
- rescue LoadError
34
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
35
- end
36
-
37
- begin
38
- #for additional metrics, mostly Rcov which caliper doesn't do
39
- require 'metric_fu'
40
-
41
- MetricFu::Configuration.run do |config|
42
- config.metrics = [:churn, :saikuro, :roodi, :flog, :flay, :reek, :roodi, :rcov, :hotspots]
43
- config.graphs = [:roodi, :flog, :flay, :reek, :roodi, :rcov]
44
-
45
- config.flay = { :dirs_to_flay => ['lib'] }
46
- config.flog = { :dirs_to_flog => ['lib'] }
47
- config.reek = { :dirs_to_reek => ['lib'] }
48
- config.roodi = { :dirs_to_roodi => ['lib'] }
49
- config.saikuro = { :output_directory => 'tmp/tmp_saikuro',
50
- :input_directory => ['lib'],
51
- :cyclo => "",
52
- :filter_cyclo => "0",
53
- :warn_cyclo => "5",
54
- :error_cyclo => "7",
55
- :formater => "text"} #this needs to be set to "text"
56
- config.churn = { :start_date => "3 months ago", :minimum_churn_count => 10}
57
- config.rcov = { :test_files => ['test/unit/**/*_test.rb'],
58
- :rcov_opts => ["--sort coverage",
59
- "--no-html",
60
- "--text-coverage",
61
- "--no-color",
62
- "--profile",
63
- "--exclude /gems/,spec"]}
64
- end
65
- rescue Exception
66
- puts "metric_fu not working install it"
67
- end
68
-
69
5
  require 'rake/testtask'
70
6
  Rake::TestTask.new(:test) do |test|
71
7
  test.libs << 'lib' << 'test'
@@ -88,7 +24,13 @@ end
88
24
 
89
25
  task :default => :test
90
26
 
91
- require 'rake/rdoctask'
27
+ desc "Build Gem"
28
+ task :build_gem do
29
+ `gem build churn.gemspec`
30
+ `mv churn*.gem pkg/`
31
+ end
32
+
33
+ require 'rdoc/task'
92
34
  Rake::RDocTask.new do |rdoc|
93
35
  if File.exist?('VERSION')
94
36
  version = File.read('VERSION')
data/churn.gemspec CHANGED
@@ -1,101 +1,41 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "churn/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
6
  s.name = "churn"
8
- s.version = "0.0.25"
7
+ s.version = Churn::VERSION
9
8
 
10
9
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
10
  s.authors = ["Dan Mayer"]
12
11
  s.date = "2012-12-17"
12
+ s.summary = "Providing additional churn metrics over the original metric_fu churn"
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
- s.executables = ["churn"]
15
+ s.homepage = "http://github.com/danmayer/churn"
16
+ s.rubyforge_project = "churn"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
16
23
  s.extra_rdoc_files = [
17
24
  "LICENSE",
18
25
  "README.md"
19
26
  ]
20
- s.files = [
21
- ".deferred_server",
22
- ".document",
23
- ".travis.yml",
24
- "Gemfile",
25
- "Gemfile.lock",
26
- "LICENSE",
27
- "README.md",
28
- "Rakefile",
29
- "VERSION",
30
- "bin/churn",
31
- "churn.gemspec",
32
- "lib/churn.rb",
33
- "lib/churn/bzr_analyzer.rb",
34
- "lib/churn/churn_calculator.rb",
35
- "lib/churn/churn_history.rb",
36
- "lib/churn/git_analyzer.rb",
37
- "lib/churn/hg_analyzer.rb",
38
- "lib/churn/location_mapping.rb",
39
- "lib/churn/source_control.rb",
40
- "lib/churn/svn_analyzer.rb",
41
- "lib/tasks/churn_tasks.rb",
42
- "man/churn.1",
43
- "man/churn.html",
44
- "test/data/churn_calculator.rb",
45
- "test/data/test_helper.rb",
46
- "test/test_helper.rb",
47
- "test/unit/bzr_analyzer_test.rb",
48
- "test/unit/churn_calculator_test.rb",
49
- "test/unit/churn_history_test.rb",
50
- "test/unit/git_analyzer_test.rb",
51
- "test/unit/hg_analyzer_test.rb",
52
- "test/unit/location_mapping_test.rb"
53
- ]
54
- s.homepage = "http://github.com/danmayer/churn"
55
- s.require_paths = ["lib"]
56
- s.rubygems_version = "1.8.10"
57
- s.summary = "Providing additional churn metrics over the original metric_fu churn"
58
27
 
59
- if s.respond_to? :specification_version then
60
- s.specification_version = 3
28
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
29
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
30
+ s.add_development_dependency(%q<test-construct>, [">= 0"])
31
+ s.add_development_dependency(%q<rake>, [">= 0"])
32
+ s.add_development_dependency(%q<mocha>, ["~> 0.9.5"])
33
+ #s.add_development_dependency(%q<ruby-debug>, ["~> 0.10.4"])
34
+ s.add_runtime_dependency(%q<main>, [">= 0"])
35
+ s.add_runtime_dependency(%q<json_pure>, [">= 0"])
36
+ s.add_runtime_dependency(%q<chronic>, [">= 0.2.3"])
37
+ s.add_runtime_dependency(%q<sexp_processor>, ["~> 4.1.0"])
38
+ s.add_runtime_dependency(%q<ruby_parser>, ["~> 3.1.0"])
39
+ s.add_runtime_dependency(%q<hirb>, [">= 0"])
61
40
 
62
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
63
- s.add_development_dependency(%q<shoulda>, [">= 0"])
64
- s.add_development_dependency(%q<jeweler>, [">= 0"])
65
- s.add_development_dependency(%q<test-construct>, [">= 0"])
66
- s.add_development_dependency(%q<rake>, [">= 0"])
67
- s.add_development_dependency(%q<mocha>, ["~> 0.9.5"])
68
- s.add_runtime_dependency(%q<main>, [">= 0"])
69
- s.add_runtime_dependency(%q<json_pure>, [">= 0"])
70
- s.add_runtime_dependency(%q<chronic>, [">= 0.2.3"])
71
- s.add_runtime_dependency(%q<sexp_processor>, ["~> 3.0"])
72
- s.add_runtime_dependency(%q<ruby_parser>, ["~> 2.3"])
73
- s.add_runtime_dependency(%q<hirb>, [">= 0"])
74
- else
75
- s.add_dependency(%q<shoulda>, [">= 0"])
76
- s.add_dependency(%q<jeweler>, [">= 0"])
77
- s.add_dependency(%q<test-construct>, [">= 0"])
78
- s.add_dependency(%q<rake>, [">= 0"])
79
- s.add_dependency(%q<mocha>, ["~> 0.9.5"])
80
- s.add_dependency(%q<main>, [">= 0"])
81
- s.add_dependency(%q<json_pure>, [">= 0"])
82
- s.add_dependency(%q<chronic>, [">= 0.2.3"])
83
- s.add_dependency(%q<sexp_processor>, ["~> 3.0"])
84
- s.add_dependency(%q<ruby_parser>, ["~> 2.3"])
85
- s.add_dependency(%q<hirb>, [">= 0"])
86
- end
87
- else
88
- s.add_dependency(%q<shoulda>, [">= 0"])
89
- s.add_dependency(%q<jeweler>, [">= 0"])
90
- s.add_dependency(%q<test-construct>, [">= 0"])
91
- s.add_dependency(%q<rake>, [">= 0"])
92
- s.add_dependency(%q<mocha>, ["~> 0.9.5"])
93
- s.add_dependency(%q<main>, [">= 0"])
94
- s.add_dependency(%q<json_pure>, [">= 0"])
95
- s.add_dependency(%q<chronic>, [">= 0.2.3"])
96
- s.add_dependency(%q<sexp_processor>, ["~> 3.0"])
97
- s.add_dependency(%q<ruby_parser>, ["~> 2.3"])
98
- s.add_dependency(%q<hirb>, [">= 0"])
99
- end
100
41
  end
101
-
@@ -1,29 +1,33 @@
1
1
  module Churn
2
-
2
+
3
3
  # Given a ruby file, map the klass and methods to a range of line numbers
4
4
  # The klass and method to line numbers mappings, are stored in
5
5
  # @klasses_collection and @methods_collection
6
+ # this is based off https://github.com/seattlerb/ruby_parser which seems to have some known line number bugs
7
+ # perhaps look at and move more to the style of line numbers from metric_fu
8
+ # https://github.com/metricfu/metric_fu/blob/master/lib/data_structures/line_numbers.rb
6
9
  class LocationMapping < SexpProcessor
7
-
10
+
8
11
  attr_reader :klasses_collection, :methods_collection
9
-
12
+
10
13
  def initialize()
11
14
  super
12
15
  @klasses_collection = {}
13
16
  @methods_collection = {}
14
17
  @parser = RubyParser.new
15
18
  self.auto_shift_type = true
19
+ self.require_empty = false
16
20
  end
17
-
21
+
18
22
  def get_info(file)
19
23
  ast = @parser.process(File.read(file), file)
20
24
  process ast
21
25
  end
22
-
26
+
23
27
  def process_class(exp)
24
28
  name = exp.shift
25
29
  start_line = exp.line
26
- last_line = exp.last.line
30
+ last_line = deep_last_line(exp)
27
31
  name = name if name.is_a?(Symbol)
28
32
  name = name.values.value if name.is_a?(Sexp) #deals with cases like class Test::Unit::TestCase
29
33
  @current_class = name
@@ -32,15 +36,22 @@ module Churn
32
36
  analyze_list exp
33
37
  s()
34
38
  end
35
-
39
+
40
+ def deep_last_line(exp)
41
+ lines = []
42
+ exp.deep_each{|x| lines << x.line }
43
+ lines.max + 1
44
+ end
45
+
36
46
  def analyze_list exp
37
47
  process exp.shift until exp.empty?
48
+ exp
38
49
  end
39
-
50
+
40
51
  def process_defn(exp)
41
52
  name = exp.shift
42
53
  start_line = exp.line
43
- last_line = exp.last.line
54
+ last_line = deep_last_line(exp)
44
55
  full_name = "#{@current_class}##{name}"
45
56
  @methods_collection[full_name] = [] unless @methods_collection.include?(full_name)
46
57
  @methods_collection[full_name] << (start_line..last_line)
@@ -0,0 +1,3 @@
1
+ module Churn
2
+ VERSION = "0.0.26"
3
+ end
@@ -1,17 +1,17 @@
1
1
  require File.expand_path('../test_helper', File.dirname(__FILE__))
2
2
 
3
3
  class LocationMappingTest < Test::Unit::TestCase
4
-
4
+
5
5
  #todo unfortunately it looks like ruby parser can't handle construct tmp dirs
6
6
  #<Pathname:/private/var/folders/gl/glhHkYYSGgG5nb6+4OG0yU+++TI/-Tmp-/construct_container-56784-851001101/fake_class.rb>
7
7
  #(rdb:1) p locationmapping.get_info(file.to_s)
8
8
  #RegexpError Exception: invalid regular expression; there's no previous pattern, to which '+' would define cardinality at 2: /^+++/
9
9
 
10
- should "location_mapping gets correct classes info" do
10
+ should "location_mapping gets correct file classes info" do
11
11
  file = 'test/data/churn_calculator.rb'
12
12
  locationmapping = Churn::LocationMapping.new
13
13
  locationmapping.get_info(file.to_s)
14
- klass_hash = {"ChurnCalculator"=>[14..215]}
14
+ klass_hash = {"ChurnCalculator"=>[14..213]}
15
15
  assert_equal klass_hash, locationmapping.klasses_collection
16
16
  end
17
17
 
@@ -19,17 +19,17 @@ class LocationMappingTest < Test::Unit::TestCase
19
19
  file = 'test/data/churn_calculator.rb'
20
20
  locationmapping = Churn::LocationMapping.new
21
21
  locationmapping.get_info(file.to_s)
22
- methods_hash = {"ChurnCalculator#report"=>[32..36], "ChurnCalculator#emit"=>[38..41], "ChurnCalculator#changes_for_type"=>[139..155], "ChurnCalculator#get_klass_for"=>[135..137], "ChurnCalculator#calculate_changes!"=>[109..116], "ChurnCalculator#analyze"=>[43..53], "ChurnCalculator#calculate_revision_data"=>[95..107], "ChurnCalculator#calculate_revision_changes"=>[78..93], "ChurnCalculator#parse_logs_for_updated_files"=>[171..213], "ChurnCalculator#to_h"=>[55..70], "ChurnCalculator#parse_log_for_revision_changes"=>[167..169], "ChurnCalculator#get_changes"=>[118..133], "ChurnCalculator#parse_log_for_changes"=>[157..165], "ChurnCalculator#initialize"=>[16..30]}
23
- assert_equal methods_hash, locationmapping.methods_collection
22
+ methods_hash = {"ChurnCalculator#report"=>[32..36], "ChurnCalculator#emit"=>[38..41], "ChurnCalculator#changes_for_type"=>[139..155], "ChurnCalculator#get_klass_for"=>[135..137], "ChurnCalculator#calculate_changes!"=>[109..116], "ChurnCalculator#analyze"=>[43..53], "ChurnCalculator#calculate_revision_data"=>[95..107], "ChurnCalculator#calculate_revision_changes"=>[78..92], "ChurnCalculator#parse_logs_for_updated_files"=>[171..213], "ChurnCalculator#to_h"=>[55..70], "ChurnCalculator#parse_log_for_revision_changes"=>[167..169], "ChurnCalculator#get_changes"=>[118..133], "ChurnCalculator#parse_log_for_changes"=>[157..165], "ChurnCalculator#initialize"=>[16..30]}
23
+ assert_equal methods_hash.sort, locationmapping.methods_collection.sort
24
24
  end
25
-
25
+
26
26
  should "location_mapping gets correct classes info for test helper files" do
27
27
  file = 'test/data/test_helper.rb'
28
28
  locationmapping = Churn::LocationMapping.new
29
29
  locationmapping.get_info(file.to_s)
30
- klass_hash = {"TestCase"=>[12..14]}
31
- assert_equal klass_hash, locationmapping.klasses_collection
30
+ klass_hash = {"TestCase"=>[12..15]}
31
+ assert_equal klass_hash.sort, locationmapping.klasses_collection.sort
32
32
  end
33
-
33
+
34
34
  end
35
35
 
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: 45
4
+ hash: 43
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 25
10
- version: 0.0.25
9
+ - 26
10
+ version: 0.0.26
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dan Mayer
@@ -139,11 +139,12 @@ dependencies:
139
139
  requirements:
140
140
  - - ~>
141
141
  - !ruby/object:Gem::Version
142
- hash: 7
142
+ hash: 59
143
143
  segments:
144
- - 3
144
+ - 4
145
+ - 1
145
146
  - 0
146
- version: "3.0"
147
+ version: 4.1.0
147
148
  requirement: *id009
148
149
  prerelease: false
149
150
  name: sexp_processor
@@ -154,11 +155,12 @@ dependencies:
154
155
  requirements:
155
156
  - - ~>
156
157
  - !ruby/object:Gem::Version
157
- hash: 5
158
+ hash: 3
158
159
  segments:
159
- - 2
160
160
  - 3
161
- version: "2.3"
161
+ - 1
162
+ - 0
163
+ version: 3.1.0
162
164
  requirement: *id010
163
165
  prerelease: false
164
166
  name: ruby_parser
@@ -189,6 +191,7 @@ extra_rdoc_files:
189
191
  files:
190
192
  - .deferred_server
191
193
  - .document
194
+ - .gitignore
192
195
  - .travis.yml
193
196
  - Gemfile
194
197
  - Gemfile.lock
@@ -207,6 +210,7 @@ files:
207
210
  - lib/churn/location_mapping.rb
208
211
  - lib/churn/source_control.rb
209
212
  - lib/churn/svn_analyzer.rb
213
+ - lib/churn/version.rb
210
214
  - lib/tasks/churn_tasks.rb
211
215
  - man/churn.1
212
216
  - man/churn.html
@@ -247,10 +251,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
247
251
  version: "0"
248
252
  requirements: []
249
253
 
250
- rubyforge_project:
254
+ rubyforge_project: churn
251
255
  rubygems_version: 1.8.10
252
256
  signing_key:
253
257
  specification_version: 3
254
258
  summary: Providing additional churn metrics over the original metric_fu churn
255
- test_files: []
256
-
259
+ test_files:
260
+ - test/data/churn_calculator.rb
261
+ - test/data/test_helper.rb
262
+ - test/test_helper.rb
263
+ - test/unit/bzr_analyzer_test.rb
264
+ - test/unit/churn_calculator_test.rb
265
+ - test/unit/churn_history_test.rb
266
+ - test/unit/git_analyzer_test.rb
267
+ - test/unit/hg_analyzer_test.rb
268
+ - test/unit/location_mapping_test.rb