churn 0.0.13 → 0.0.14
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/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
|
+
|