churn 0.0.25 → 0.0.26

Sign up to get free protection for your applications and to get access to all the features.
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