churn 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +20 -0
- data/Gemfile.lock +47 -0
- data/README.rdoc +6 -1
- data/Rakefile +3 -5
- data/VERSION +1 -1
- data/churn.gemspec +102 -0
- data/lib/churn/bzr_analyzer.rb +31 -0
- data/lib/churn/churn_calculator.rb +8 -1
- data/man/churn.1 +2 -1
- data/man/churn.html +3 -2
- data/test/unit/bzr_analyzer_test.rb +65 -0
- metadata +250 -57
- data/.gitignore +0 -6
data/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'arrayfields', '4.7.4'
|
4
|
+
gem 'chronic', '0.6.4'
|
5
|
+
gem 'fattr', '2.2.0'
|
6
|
+
gem 'hirb', '0.5.0'
|
7
|
+
gem 'jeweler', '1.6.4'
|
8
|
+
gem 'json', '1.6.1'
|
9
|
+
gem 'main', '4.7.7'
|
10
|
+
gem 'map', '4.3.0'
|
11
|
+
gem 'ruby_parser', '2.3.1'
|
12
|
+
gem 'sexp_processor', '3.0.7'
|
13
|
+
|
14
|
+
group :test do
|
15
|
+
# bundler requires these gems while running tests
|
16
|
+
gem "shoulda", '2.11.3'
|
17
|
+
gem "test-construct", '1.2.0'
|
18
|
+
gem "mocha", '0.10.0'
|
19
|
+
gem 'rake', '0.8.7'
|
20
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
arrayfields (4.7.4)
|
5
|
+
chronic (0.6.4)
|
6
|
+
fattr (2.2.0)
|
7
|
+
git (1.2.5)
|
8
|
+
hirb (0.5.0)
|
9
|
+
jeweler (1.6.4)
|
10
|
+
bundler (~> 1.0)
|
11
|
+
git (>= 1.2.5)
|
12
|
+
rake
|
13
|
+
json (1.6.1)
|
14
|
+
main (4.7.7)
|
15
|
+
arrayfields (~> 4.7.4)
|
16
|
+
chronic (~> 0.6.2)
|
17
|
+
fattr (~> 2.2.0)
|
18
|
+
map (~> 4.3.0)
|
19
|
+
map (4.3.0)
|
20
|
+
metaclass (0.0.1)
|
21
|
+
mocha (0.10.0)
|
22
|
+
metaclass (~> 0.0.1)
|
23
|
+
rake (0.8.7)
|
24
|
+
ruby_parser (2.3.1)
|
25
|
+
sexp_processor (~> 3.0)
|
26
|
+
sexp_processor (3.0.7)
|
27
|
+
shoulda (2.11.3)
|
28
|
+
test-construct (1.2.0)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
arrayfields (= 4.7.4)
|
35
|
+
chronic (= 0.6.4)
|
36
|
+
fattr (= 2.2.0)
|
37
|
+
hirb (= 0.5.0)
|
38
|
+
jeweler (= 1.6.4)
|
39
|
+
json (= 1.6.1)
|
40
|
+
main (= 4.7.7)
|
41
|
+
map (= 4.3.0)
|
42
|
+
mocha (= 0.10.0)
|
43
|
+
rake (= 0.8.7)
|
44
|
+
ruby_parser (= 2.3.1)
|
45
|
+
sexp_processor (= 3.0.7)
|
46
|
+
shoulda (= 2.11.3)
|
47
|
+
test-construct (= 1.2.0)
|
data/README.rdoc
CHANGED
@@ -4,13 +4,18 @@ A Project to give the churn file, class, and method for a project for a given ch
|
|
4
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
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
6
|
|
7
|
-
Currently has
|
7
|
+
Currently has full Git, Mercurial (hg), and Bazaar (bzr) support, and partial SVN support (supports only file level churn currently)
|
8
8
|
|
9
9
|
Authors:
|
10
10
|
* danmayer
|
11
11
|
* ajwalters
|
12
12
|
* cldwalker
|
13
|
+
* absurdhero
|
13
14
|
|
15
|
+
Execute with:
|
16
|
+
rake churn #after adding require 'lib/tasks/churn_tasks' to projects rakefile
|
17
|
+
churn
|
18
|
+
|
14
19
|
== Example Output
|
15
20
|
**********************************************************************
|
16
21
|
* Revision Changes
|
data/Rakefile
CHANGED
@@ -8,20 +8,20 @@ begin
|
|
8
8
|
gem.name = "churn"
|
9
9
|
gem.summary = %Q{Providing additional churn metrics over the original metric_fu churn}
|
10
10
|
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. }
|
11
|
-
gem.email = "dan@
|
11
|
+
gem.email = "dan@mayerdan.com"
|
12
12
|
gem.homepage = "http://github.com/danmayer/churn"
|
13
13
|
gem.authors = ["Dan Mayer"]
|
14
14
|
gem.add_development_dependency "shoulda"
|
15
|
+
gem.add_development_dependency "jeweler", '~> 1.6.0'
|
15
16
|
gem.add_development_dependency "test-construct"
|
16
17
|
gem.add_development_dependency "mocha", '~> 0.9.5'
|
17
18
|
gem.add_dependency "main"
|
18
19
|
gem.add_dependency "json_pure"
|
19
20
|
gem.add_dependency "chronic", '>= 0.2.3'
|
20
21
|
gem.add_dependency "sexp_processor", '~> 3.0.3'
|
21
|
-
gem.add_dependency "ruby_parser", '~> 2.
|
22
|
+
gem.add_dependency "ruby_parser", '~> 2.3'
|
22
23
|
gem.add_dependency 'hirb'
|
23
24
|
gem.executables = ['churn']
|
24
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
25
25
|
end
|
26
26
|
rescue LoadError
|
27
27
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
@@ -79,8 +79,6 @@ rescue LoadError
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
task :test => :check_dependencies
|
83
|
-
|
84
82
|
task :default => :test
|
85
83
|
|
86
84
|
require 'rake/rdoctask'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.14
|
data/churn.gemspec
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{churn}
|
8
|
+
s.version = "0.0.13"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Dan Mayer"]
|
12
|
+
s.date = %q{2010-11-30}
|
13
|
+
s.default_executable = %q{churn}
|
14
|
+
s.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. }
|
15
|
+
s.email = %q{dan@devver.net}
|
16
|
+
s.executables = ["churn"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".gitignore",
|
24
|
+
"LICENSE",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/churn",
|
29
|
+
"lib/churn.rb",
|
30
|
+
"lib/churn/churn_calculator.rb",
|
31
|
+
"lib/churn/churn_history.rb",
|
32
|
+
"lib/churn/git_analyzer.rb",
|
33
|
+
"lib/churn/hg_analyzer.rb",
|
34
|
+
"lib/churn/location_mapping.rb",
|
35
|
+
"lib/churn/source_control.rb",
|
36
|
+
"lib/churn/svn_analyzer.rb",
|
37
|
+
"lib/tasks/churn_tasks.rb",
|
38
|
+
"man/churn.1",
|
39
|
+
"man/churn.html",
|
40
|
+
"test/data/churn_calculator.rb",
|
41
|
+
"test/data/test_helper.rb",
|
42
|
+
"test/test_helper.rb",
|
43
|
+
"test/unit/churn_calculator_test.rb",
|
44
|
+
"test/unit/churn_history_test.rb",
|
45
|
+
"test/unit/git_analyzer_test.rb",
|
46
|
+
"test/unit/hg_analyzer_test.rb",
|
47
|
+
"test/unit/location_mapping_test.rb"
|
48
|
+
]
|
49
|
+
s.homepage = %q{http://github.com/danmayer/churn}
|
50
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
51
|
+
s.require_paths = ["lib"]
|
52
|
+
s.rubygems_version = %q{1.3.6}
|
53
|
+
s.summary = %q{Providing additional churn metrics over the original metric_fu churn}
|
54
|
+
s.test_files = [
|
55
|
+
"test/data/churn_calculator.rb",
|
56
|
+
"test/data/test_helper.rb",
|
57
|
+
"test/test_helper.rb",
|
58
|
+
"test/unit/churn_calculator_test.rb",
|
59
|
+
"test/unit/churn_history_test.rb",
|
60
|
+
"test/unit/git_analyzer_test.rb",
|
61
|
+
"test/unit/hg_analyzer_test.rb",
|
62
|
+
"test/unit/location_mapping_test.rb"
|
63
|
+
]
|
64
|
+
|
65
|
+
if s.respond_to? :specification_version then
|
66
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
67
|
+
s.specification_version = 3
|
68
|
+
|
69
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
70
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
71
|
+
s.add_development_dependency(%q<test-construct>, [">= 0"])
|
72
|
+
s.add_development_dependency(%q<mocha>, ["~> 0.9.5"])
|
73
|
+
s.add_runtime_dependency(%q<main>, [">= 0"])
|
74
|
+
s.add_runtime_dependency(%q<json_pure>, [">= 0"])
|
75
|
+
s.add_runtime_dependency(%q<chronic>, [">= 0.2.3"])
|
76
|
+
s.add_runtime_dependency(%q<sexp_processor>, ["~> 3.0.3"])
|
77
|
+
s.add_runtime_dependency(%q<ruby_parser>, ["~> 2.0.4"])
|
78
|
+
s.add_runtime_dependency(%q<hirb>, [">= 0"])
|
79
|
+
else
|
80
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
81
|
+
s.add_dependency(%q<test-construct>, [">= 0"])
|
82
|
+
s.add_dependency(%q<mocha>, ["~> 0.9.5"])
|
83
|
+
s.add_dependency(%q<main>, [">= 0"])
|
84
|
+
s.add_dependency(%q<json_pure>, [">= 0"])
|
85
|
+
s.add_dependency(%q<chronic>, [">= 0.2.3"])
|
86
|
+
s.add_dependency(%q<sexp_processor>, ["~> 3.0.3"])
|
87
|
+
s.add_dependency(%q<ruby_parser>, ["~> 2.0.4"])
|
88
|
+
s.add_dependency(%q<hirb>, [">= 0"])
|
89
|
+
end
|
90
|
+
else
|
91
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
92
|
+
s.add_dependency(%q<test-construct>, [">= 0"])
|
93
|
+
s.add_dependency(%q<mocha>, ["~> 0.9.5"])
|
94
|
+
s.add_dependency(%q<main>, [">= 0"])
|
95
|
+
s.add_dependency(%q<json_pure>, [">= 0"])
|
96
|
+
s.add_dependency(%q<chronic>, [">= 0.2.3"])
|
97
|
+
s.add_dependency(%q<sexp_processor>, ["~> 3.0.3"])
|
98
|
+
s.add_dependency(%q<ruby_parser>, ["~> 2.0.4"])
|
99
|
+
s.add_dependency(%q<hirb>, [">= 0"])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Churn
|
2
|
+
|
3
|
+
#analizes Bzr / Bazaar SCM to find recently changed files, and what lines have been altered
|
4
|
+
class BzrAnalyzer < SourceControl
|
5
|
+
def get_logs
|
6
|
+
`bzr log -v --short #{date_range}`.split("\n").reject{|line| line !~ /^[ ]*(M|A) /}.map{|line| line.strip.split(" ")[1..-1]}.flatten
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_revisions
|
10
|
+
`bzr log --line #{date_range}`.split("\n").map{|line| line[/^(\S+):/, 1] }
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def get_diff(revision, previous_revision)
|
16
|
+
`bzr diff -r #{previous_revision}..#{revision}`.split(/\n/).select{|line| line.match(/^@@/) || line.match(/^---/) || line.match(/^\+\+\+/) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def date_range
|
20
|
+
if @start_date
|
21
|
+
date = Chronic.parse(@start_date)
|
22
|
+
"-r #{date.strftime('%Y-%m-%d')}.."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_recent_file(line)
|
27
|
+
super(line).split("\t")[0]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -10,6 +10,7 @@ require 'source_control'
|
|
10
10
|
require 'git_analyzer'
|
11
11
|
require 'svn_analyzer'
|
12
12
|
require 'hg_analyzer'
|
13
|
+
require 'bzr_analyzer'
|
13
14
|
require 'location_mapping'
|
14
15
|
require 'churn_history'
|
15
16
|
|
@@ -134,15 +135,21 @@ module Churn
|
|
134
135
|
system("hg branch")
|
135
136
|
end
|
136
137
|
|
138
|
+
def self.bzr?
|
139
|
+
system("bzr nick")
|
140
|
+
end
|
141
|
+
|
137
142
|
def set_source_control(start_date)
|
138
143
|
if self.class.git?
|
139
144
|
GitAnalyzer.new(start_date)
|
140
145
|
elsif self.class.hg?
|
141
146
|
HgAnalyzer.new(start_date)
|
147
|
+
elsif self.class.bzr?
|
148
|
+
BzrAnalyzer.new(start_date)
|
142
149
|
elsif File.exist?(".svn")
|
143
150
|
SvnAnalyzer.new(start_date)
|
144
151
|
else
|
145
|
-
raise "Churning requires a
|
152
|
+
raise "Churning requires a bazaar, git, mercurial, or subversion repo"
|
146
153
|
end
|
147
154
|
end
|
148
155
|
|
data/man/churn.1
CHANGED
@@ -10,13 +10,14 @@ Over time the tool adds up the history of chruns to give the number of times a f
|
|
10
10
|
Churn for files is immediate, but classes and methods requires buildings up a history using churn between revisions. The history is stored in ./tmp
|
11
11
|
.
|
12
12
|
.P
|
13
|
-
Currently has Full Git
|
13
|
+
Currently has Full Git, Mercurial (hg), and Bazaar (bzr) support, and partial SVN support (supports only file level churn currnetly)
|
14
14
|
.
|
15
15
|
.P
|
16
16
|
Authors:
|
17
17
|
* danmayer
|
18
18
|
* ajwalters
|
19
19
|
* cldwalker
|
20
|
+
* absurdhero
|
20
21
|
.
|
21
22
|
.P
|
22
23
|
== Example Output
|
data/man/churn.html
CHANGED
@@ -391,11 +391,12 @@ div#toc a:visited { color: blue; }
|
|
391
391
|
<div class="paragraph"><p>A Project to give the churn file, class, and method for a project for a given checkin
|
392
392
|
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.
|
393
393
|
Churn for files is immediate, but classes and methods requires buildings up a history using churn between revisions. The history is stored in ./tmp</p></div>
|
394
|
-
<div class="paragraph"><p>Currently has Full Git
|
394
|
+
<div class="paragraph"><p>Currently has Full Git, Mercurial (hg), and Bazaar (bzr) support, and partial SVN support (supports only file level churn currnetly)</p></div>
|
395
395
|
<div class="paragraph"><p>Authors:
|
396
396
|
* danmayer
|
397
397
|
* ajwalters
|
398
|
-
* cldwalker
|
398
|
+
* cldwalker
|
399
|
+
* absurdhero</p></div>
|
399
400
|
</div>
|
400
401
|
</div>
|
401
402
|
<h2 id="_example_output">Example Output</h2>
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class BzrAnalyzerTest < Test::Unit::TestCase
|
4
|
+
context "BzrAnalyzer#get_logs" do
|
5
|
+
should "return a list of changed files" do
|
6
|
+
bzr_analyzer = Churn::BzrAnalyzer.new
|
7
|
+
bzr_analyzer.expects(:`).with('bzr log -v --short ').returns(" 1947 Adam Walters 2010-01-16\n Second commit with 3 files now.\n M file1.rb\n M file2.rb\n M file3.rb\n\n 1946 Adam Walters 2010-01-16\n First commit\n A file1.rb\n")
|
8
|
+
assert_equal ["file1.rb", "file2.rb", "file3.rb", "file1.rb"], bzr_analyzer.get_logs
|
9
|
+
end
|
10
|
+
|
11
|
+
should "scope the changed files to an optional date range" do
|
12
|
+
bzr_analyzer = Churn::BzrAnalyzer.new("1/16/2010")
|
13
|
+
bzr_analyzer.expects(:`).with('bzr log -v --short -r 2010-01-16..').returns(" 1947 Adam Walters 2010-01-16\n Second commit with 3 files now.\n M file1.rb\n M file2.rb\n M file3.rb\n\n 1946 Adam Walters 2010-01-16\n First commit\n A file1.rb\n")
|
14
|
+
assert_equal ["file1.rb", "file2.rb", "file3.rb", "file1.rb"], bzr_analyzer.get_logs
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "BzrAnalyzer#get_revisions" do
|
19
|
+
should "return a list of changeset ids" do
|
20
|
+
bzr_analyzer = Churn::BzrAnalyzer.new
|
21
|
+
bzr_analyzer.expects(:`).with('bzr log --line ').returns("1947: Adam Walters 2010-01-16 Second commit with 3 files now.\n1946: Adam Walters 2010-01-16 First commit\n")
|
22
|
+
assert_equal ["1947", "1946"], bzr_analyzer.get_revisions
|
23
|
+
end
|
24
|
+
|
25
|
+
should "scope the changesets to an optional date range" do
|
26
|
+
bzr_analyzer = Churn::BzrAnalyzer.new("1/16/2010")
|
27
|
+
bzr_analyzer.expects(:`).with('bzr log --line -r 2010-01-16..').returns("1947: Adam Walters 2010-01-16 Second commit with 3 files now.\n1946: Adam Walters 2010-01-16 First commit\n")
|
28
|
+
assert_equal ["1947", "1946"], bzr_analyzer.get_revisions
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "BzrAnalyzer#get_updated_files_from_log(revision, revisions)" do
|
33
|
+
should "return a list of modified files and the change hunks (chunks)" do
|
34
|
+
bzr_analyzer = Churn::BzrAnalyzer.new
|
35
|
+
bzr_analyzer.expects(:`).with('bzr diff -r 1946..1947').returns("=== modified file 'a/file1.rb'\n--- a/file1.rb\tSat Jan 16 14:21:28 2010 -0600\n+++ b/file1.rb\tSat Jan 16 14:19:32 2010 -0600\n@@ -1,3 +0,0 @@\n-First\n-Adding sample data\n-Third line\ndiff -r 1947 -r 1946 file2.rb\n=== modified file 'a/file2.rb'\n--- a/file2.rb\tSat Jan 16 14:21:28 2010 -0600\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,7 +0,0 @@\n-This is the second file.\n-\n-Little more data\n-\n-def cool_method\n- \"hello\"\n-end\ndiff -r 1947 -r 1946 file3.rb\n--- a/file3.rb\tSat Jan 16 14:21:28 2010 -0600\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,5 +0,0 @@\n-Third file here.\n-\n-def another_method\n- \"foo\"\n-end\n")
|
36
|
+
assert_equal ["--- a/file1.rb\tSat Jan 16 14:21:28 2010 -0600", "+++ b/file1.rb\tSat Jan 16 14:19:32 2010 -0600", "@@ -1,3 +0,0 @@", "--- a/file2.rb\tSat Jan 16 14:21:28 2010 -0600", "+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000", "@@ -1,7 +0,0 @@", "--- a/file3.rb\tSat Jan 16 14:21:28 2010 -0600", "+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000", "@@ -1,5 +0,0 @@"], bzr_analyzer.get_updated_files_from_log("1947", ["1947", "1946"])
|
37
|
+
end
|
38
|
+
|
39
|
+
should "return an empty array if it's the final revision" do
|
40
|
+
bzr_analyzer = Churn::BzrAnalyzer.new
|
41
|
+
assert_equal [], bzr_analyzer.get_updated_files_from_log("1946", ["1947", "1946"])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "BzrAnalyzer#get_updated_files_change_info(revision, revisions)" do
|
46
|
+
setup do
|
47
|
+
@bzr_analyzer = Churn::BzrAnalyzer.new
|
48
|
+
end
|
49
|
+
|
50
|
+
should "return all modified files with their line differences" do
|
51
|
+
@bzr_analyzer.expects(:get_updated_files_from_log).with("1947", ["1947", "1946"]).returns(["--- a/file1.rb\tSat Jan 16 14:21:28 2010 -0600", "+++ b/file1.rb\tSat Jan 16 14:19:32 2010 -0600", "@@ -1,3 +0,0 @@", "--- a/file2.rb\tSat Jan 16 14:21:28 2010 -0600", "+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000", "@@ -1,7 +0,0 @@", "--- a/file3.rb\tSat Jan 16 14:21:28 2010 -0600", "+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000", "@@ -1,5 +0,0 @@"])
|
52
|
+
assert_equal({"/dev/null" => [1..8, 0..0, 1..6, 0..0], "file3.rb" => [], "file1.rb" => [], "file2.rb" => [], "file1.rb" => [1..4, 0..0]}, @bzr_analyzer.get_updated_files_change_info("1947", ["1947", "1946"]))
|
53
|
+
end
|
54
|
+
|
55
|
+
should "raise an error if it encounters a line it cannot parse" do
|
56
|
+
@bzr_analyzer.expects(:get_updated_files_from_log).with("1947", ["1947", "1946"]).returns(["foo"])
|
57
|
+
assert_raise RuntimeError do
|
58
|
+
@bzr_analyzer.stubs(:puts) # supress output from raised error
|
59
|
+
@bzr_analyzer.get_updated_files_change_info("1947", ["1947", "1946"])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: churn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 3
|
5
|
+
prerelease:
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
9
|
+
- 14
|
10
|
+
version: 0.0.14
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Dan Mayer
|
@@ -14,127 +15,319 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date:
|
18
|
-
default_executable: churn
|
18
|
+
date: 2011-10-30 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - "="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
hash: 43
|
27
|
+
segments:
|
28
|
+
- 4
|
29
|
+
- 7
|
30
|
+
- 4
|
31
|
+
version: 4.7.4
|
32
|
+
requirement: *id001
|
33
|
+
prerelease: false
|
34
|
+
name: arrayfields
|
35
|
+
type: :runtime
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - "="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 15
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 6
|
46
|
+
- 4
|
47
|
+
version: 0.6.4
|
48
|
+
requirement: *id002
|
49
|
+
prerelease: false
|
50
|
+
name: chronic
|
51
|
+
type: :runtime
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - "="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 7
|
59
|
+
segments:
|
60
|
+
- 2
|
61
|
+
- 2
|
62
|
+
- 0
|
63
|
+
version: 2.2.0
|
64
|
+
requirement: *id003
|
65
|
+
prerelease: false
|
66
|
+
name: fattr
|
67
|
+
type: :runtime
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - "="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 11
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
- 5
|
78
|
+
- 0
|
79
|
+
version: 0.5.0
|
80
|
+
requirement: *id004
|
81
|
+
prerelease: false
|
82
|
+
name: hirb
|
83
|
+
type: :runtime
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - "="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 7
|
91
|
+
segments:
|
92
|
+
- 1
|
93
|
+
- 6
|
94
|
+
- 4
|
95
|
+
version: 1.6.4
|
96
|
+
requirement: *id005
|
97
|
+
prerelease: false
|
98
|
+
name: jeweler
|
99
|
+
type: :runtime
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - "="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
hash: 13
|
107
|
+
segments:
|
108
|
+
- 1
|
109
|
+
- 6
|
110
|
+
- 1
|
111
|
+
version: 1.6.1
|
112
|
+
requirement: *id006
|
113
|
+
prerelease: false
|
114
|
+
name: json
|
115
|
+
type: :runtime
|
116
|
+
- !ruby/object:Gem::Dependency
|
117
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - "="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
hash: 45
|
123
|
+
segments:
|
124
|
+
- 4
|
125
|
+
- 7
|
126
|
+
- 7
|
127
|
+
version: 4.7.7
|
128
|
+
requirement: *id007
|
129
|
+
prerelease: false
|
130
|
+
name: main
|
131
|
+
type: :runtime
|
132
|
+
- !ruby/object:Gem::Dependency
|
133
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - "="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
hash: 51
|
139
|
+
segments:
|
140
|
+
- 4
|
141
|
+
- 3
|
142
|
+
- 0
|
143
|
+
version: 4.3.0
|
144
|
+
requirement: *id008
|
145
|
+
prerelease: false
|
146
|
+
name: map
|
147
|
+
type: :runtime
|
148
|
+
- !ruby/object:Gem::Dependency
|
149
|
+
version_requirements: &id009 !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - "="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
hash: 1
|
155
|
+
segments:
|
156
|
+
- 2
|
157
|
+
- 3
|
158
|
+
- 1
|
159
|
+
version: 2.3.1
|
160
|
+
requirement: *id009
|
161
|
+
prerelease: false
|
162
|
+
name: ruby_parser
|
163
|
+
type: :runtime
|
164
|
+
- !ruby/object:Gem::Dependency
|
165
|
+
version_requirements: &id010 !ruby/object:Gem::Requirement
|
166
|
+
none: false
|
167
|
+
requirements:
|
168
|
+
- - "="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
hash: 9
|
171
|
+
segments:
|
172
|
+
- 3
|
173
|
+
- 0
|
174
|
+
- 7
|
175
|
+
version: 3.0.7
|
176
|
+
requirement: *id010
|
22
177
|
prerelease: false
|
23
|
-
|
178
|
+
name: sexp_processor
|
179
|
+
type: :runtime
|
180
|
+
- !ruby/object:Gem::Dependency
|
181
|
+
version_requirements: &id011 !ruby/object:Gem::Requirement
|
182
|
+
none: false
|
24
183
|
requirements:
|
25
184
|
- - ">="
|
26
185
|
- !ruby/object:Gem::Version
|
186
|
+
hash: 3
|
27
187
|
segments:
|
28
188
|
- 0
|
29
189
|
version: "0"
|
190
|
+
requirement: *id011
|
191
|
+
prerelease: false
|
192
|
+
name: shoulda
|
30
193
|
type: :development
|
31
|
-
version_requirements: *id001
|
32
194
|
- !ruby/object:Gem::Dependency
|
33
|
-
|
195
|
+
version_requirements: &id012 !ruby/object:Gem::Requirement
|
196
|
+
none: false
|
197
|
+
requirements:
|
198
|
+
- - ~>
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
hash: 15
|
201
|
+
segments:
|
202
|
+
- 1
|
203
|
+
- 6
|
204
|
+
- 0
|
205
|
+
version: 1.6.0
|
206
|
+
requirement: *id012
|
34
207
|
prerelease: false
|
35
|
-
|
208
|
+
name: jeweler
|
209
|
+
type: :development
|
210
|
+
- !ruby/object:Gem::Dependency
|
211
|
+
version_requirements: &id013 !ruby/object:Gem::Requirement
|
212
|
+
none: false
|
36
213
|
requirements:
|
37
214
|
- - ">="
|
38
215
|
- !ruby/object:Gem::Version
|
216
|
+
hash: 3
|
39
217
|
segments:
|
40
218
|
- 0
|
41
219
|
version: "0"
|
220
|
+
requirement: *id013
|
221
|
+
prerelease: false
|
222
|
+
name: test-construct
|
42
223
|
type: :development
|
43
|
-
version_requirements: *id002
|
44
224
|
- !ruby/object:Gem::Dependency
|
45
|
-
|
46
|
-
|
47
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
225
|
+
version_requirements: &id014 !ruby/object:Gem::Requirement
|
226
|
+
none: false
|
48
227
|
requirements:
|
49
228
|
- - ~>
|
50
229
|
- !ruby/object:Gem::Version
|
230
|
+
hash: 49
|
51
231
|
segments:
|
52
232
|
- 0
|
53
233
|
- 9
|
54
234
|
- 5
|
55
235
|
version: 0.9.5
|
236
|
+
requirement: *id014
|
237
|
+
prerelease: false
|
238
|
+
name: mocha
|
56
239
|
type: :development
|
57
|
-
version_requirements: *id003
|
58
240
|
- !ruby/object:Gem::Dependency
|
59
|
-
|
60
|
-
|
61
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
241
|
+
version_requirements: &id015 !ruby/object:Gem::Requirement
|
242
|
+
none: false
|
62
243
|
requirements:
|
63
244
|
- - ">="
|
64
245
|
- !ruby/object:Gem::Version
|
246
|
+
hash: 3
|
65
247
|
segments:
|
66
248
|
- 0
|
67
249
|
version: "0"
|
250
|
+
requirement: *id015
|
251
|
+
prerelease: false
|
252
|
+
name: main
|
68
253
|
type: :runtime
|
69
|
-
version_requirements: *id004
|
70
254
|
- !ruby/object:Gem::Dependency
|
71
|
-
|
72
|
-
|
73
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
255
|
+
version_requirements: &id016 !ruby/object:Gem::Requirement
|
256
|
+
none: false
|
74
257
|
requirements:
|
75
258
|
- - ">="
|
76
259
|
- !ruby/object:Gem::Version
|
260
|
+
hash: 3
|
77
261
|
segments:
|
78
262
|
- 0
|
79
263
|
version: "0"
|
264
|
+
requirement: *id016
|
265
|
+
prerelease: false
|
266
|
+
name: json_pure
|
80
267
|
type: :runtime
|
81
|
-
version_requirements: *id005
|
82
268
|
- !ruby/object:Gem::Dependency
|
83
|
-
|
84
|
-
|
85
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
269
|
+
version_requirements: &id017 !ruby/object:Gem::Requirement
|
270
|
+
none: false
|
86
271
|
requirements:
|
87
272
|
- - ">="
|
88
273
|
- !ruby/object:Gem::Version
|
274
|
+
hash: 17
|
89
275
|
segments:
|
90
276
|
- 0
|
91
277
|
- 2
|
92
278
|
- 3
|
93
279
|
version: 0.2.3
|
280
|
+
requirement: *id017
|
281
|
+
prerelease: false
|
282
|
+
name: chronic
|
94
283
|
type: :runtime
|
95
|
-
version_requirements: *id006
|
96
284
|
- !ruby/object:Gem::Dependency
|
97
|
-
|
98
|
-
|
99
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
285
|
+
version_requirements: &id018 !ruby/object:Gem::Requirement
|
286
|
+
none: false
|
100
287
|
requirements:
|
101
288
|
- - ~>
|
102
289
|
- !ruby/object:Gem::Version
|
290
|
+
hash: 1
|
103
291
|
segments:
|
104
292
|
- 3
|
105
293
|
- 0
|
106
294
|
- 3
|
107
295
|
version: 3.0.3
|
296
|
+
requirement: *id018
|
297
|
+
prerelease: false
|
298
|
+
name: sexp_processor
|
108
299
|
type: :runtime
|
109
|
-
version_requirements: *id007
|
110
300
|
- !ruby/object:Gem::Dependency
|
111
|
-
|
112
|
-
|
113
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
301
|
+
version_requirements: &id019 !ruby/object:Gem::Requirement
|
302
|
+
none: false
|
114
303
|
requirements:
|
115
304
|
- - ~>
|
116
305
|
- !ruby/object:Gem::Version
|
306
|
+
hash: 5
|
117
307
|
segments:
|
118
308
|
- 2
|
119
|
-
-
|
120
|
-
|
121
|
-
|
309
|
+
- 3
|
310
|
+
version: "2.3"
|
311
|
+
requirement: *id019
|
312
|
+
prerelease: false
|
313
|
+
name: ruby_parser
|
122
314
|
type: :runtime
|
123
|
-
version_requirements: *id008
|
124
315
|
- !ruby/object:Gem::Dependency
|
125
|
-
|
126
|
-
|
127
|
-
requirement: &id009 !ruby/object:Gem::Requirement
|
316
|
+
version_requirements: &id020 !ruby/object:Gem::Requirement
|
317
|
+
none: false
|
128
318
|
requirements:
|
129
319
|
- - ">="
|
130
320
|
- !ruby/object:Gem::Version
|
321
|
+
hash: 3
|
131
322
|
segments:
|
132
323
|
- 0
|
133
324
|
version: "0"
|
325
|
+
requirement: *id020
|
326
|
+
prerelease: false
|
327
|
+
name: hirb
|
134
328
|
type: :runtime
|
135
|
-
version_requirements: *id009
|
136
329
|
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. "
|
137
|
-
email: dan@
|
330
|
+
email: dan@mayerdan.com
|
138
331
|
executables:
|
139
332
|
- churn
|
140
333
|
extensions: []
|
@@ -144,13 +337,16 @@ extra_rdoc_files:
|
|
144
337
|
- README.rdoc
|
145
338
|
files:
|
146
339
|
- .document
|
147
|
-
-
|
340
|
+
- Gemfile
|
341
|
+
- Gemfile.lock
|
148
342
|
- LICENSE
|
149
343
|
- README.rdoc
|
150
344
|
- Rakefile
|
151
345
|
- VERSION
|
152
346
|
- bin/churn
|
347
|
+
- churn.gemspec
|
153
348
|
- lib/churn.rb
|
349
|
+
- lib/churn/bzr_analyzer.rb
|
154
350
|
- lib/churn/churn_calculator.rb
|
155
351
|
- lib/churn/churn_history.rb
|
156
352
|
- lib/churn/git_analyzer.rb
|
@@ -164,47 +360,44 @@ files:
|
|
164
360
|
- test/data/churn_calculator.rb
|
165
361
|
- test/data/test_helper.rb
|
166
362
|
- test/test_helper.rb
|
363
|
+
- test/unit/bzr_analyzer_test.rb
|
167
364
|
- test/unit/churn_calculator_test.rb
|
168
365
|
- test/unit/churn_history_test.rb
|
169
366
|
- test/unit/git_analyzer_test.rb
|
170
367
|
- test/unit/hg_analyzer_test.rb
|
171
368
|
- test/unit/location_mapping_test.rb
|
172
|
-
has_rdoc: true
|
173
369
|
homepage: http://github.com/danmayer/churn
|
174
370
|
licenses: []
|
175
371
|
|
176
372
|
post_install_message:
|
177
|
-
rdoc_options:
|
178
|
-
|
373
|
+
rdoc_options: []
|
374
|
+
|
179
375
|
require_paths:
|
180
376
|
- lib
|
181
377
|
required_ruby_version: !ruby/object:Gem::Requirement
|
378
|
+
none: false
|
182
379
|
requirements:
|
183
380
|
- - ">="
|
184
381
|
- !ruby/object:Gem::Version
|
382
|
+
hash: 3
|
185
383
|
segments:
|
186
384
|
- 0
|
187
385
|
version: "0"
|
188
386
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
387
|
+
none: false
|
189
388
|
requirements:
|
190
389
|
- - ">="
|
191
390
|
- !ruby/object:Gem::Version
|
391
|
+
hash: 3
|
192
392
|
segments:
|
193
393
|
- 0
|
194
394
|
version: "0"
|
195
395
|
requirements: []
|
196
396
|
|
197
397
|
rubyforge_project:
|
198
|
-
rubygems_version: 1.
|
398
|
+
rubygems_version: 1.8.10
|
199
399
|
signing_key:
|
200
400
|
specification_version: 3
|
201
401
|
summary: Providing additional churn metrics over the original metric_fu churn
|
202
|
-
test_files:
|
203
|
-
|
204
|
-
- test/data/test_helper.rb
|
205
|
-
- test/test_helper.rb
|
206
|
-
- test/unit/churn_calculator_test.rb
|
207
|
-
- test/unit/churn_history_test.rb
|
208
|
-
- test/unit/git_analyzer_test.rb
|
209
|
-
- test/unit/hg_analyzer_test.rb
|
210
|
-
- test/unit/location_mapping_test.rb
|
402
|
+
test_files: []
|
403
|
+
|