bugwatch 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bugwatch.gemspec +74 -0
- data/lib/bugwatch.rb +50 -0
- data/lib/bugwatch/adapters.rb +50 -0
- data/lib/bugwatch/analysis.rb +58 -0
- data/lib/bugwatch/attrs.rb +64 -0
- data/lib/bugwatch/churn.rb +60 -0
- data/lib/bugwatch/commit.rb +82 -0
- data/lib/bugwatch/complexity_score.rb +59 -0
- data/lib/bugwatch/diff.rb +73 -0
- data/lib/bugwatch/diff_parser.rb +68 -0
- data/lib/bugwatch/exception_data.rb +57 -0
- data/lib/bugwatch/exception_tracker.rb +72 -0
- data/lib/bugwatch/file_adapters/ruby_file_adapter.rb +51 -0
- data/lib/bugwatch/flog_score.rb +88 -0
- data/lib/bugwatch/import.rb +57 -0
- data/lib/bugwatch/method_parser.rb +105 -0
- data/lib/bugwatch/repo.rb +134 -0
- data/lib/bugwatch/ruby_complexity.rb +85 -0
- data/lib/bugwatch/tag.rb +59 -0
- data/lib/bugwatch/tree.rb +65 -0
- data/vendor/flog/lib/flog.rb +803 -0
- metadata +113 -0
data/bugwatch.gemspec
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright (c) 2013, Groupon, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions
|
6
|
+
# are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of GROUPON nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
20
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
21
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
25
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
Gem::Specification.new do |s|
|
32
|
+
s.name = 'bugwatch'
|
33
|
+
s.version = '0.1'
|
34
|
+
s.date = '2012-02-13'
|
35
|
+
|
36
|
+
s.summary = 'bugwatch'
|
37
|
+
s.description = 'SCM history mining and code analysis platform'
|
38
|
+
|
39
|
+
s.authors = ['Jacob Richardson']
|
40
|
+
s.email = 'jacobr@groupon.com'
|
41
|
+
|
42
|
+
s.require_paths = %w[lib]
|
43
|
+
|
44
|
+
s.add_dependency('grit', '2.5.0')
|
45
|
+
s.add_dependency('ruby_parser', '~> 3.0.1')
|
46
|
+
s.add_dependency('rugged', '0.16.2')
|
47
|
+
|
48
|
+
# = MANIFEST =
|
49
|
+
s.files = %w[
|
50
|
+
bugwatch.gemspec
|
51
|
+
lib/bugwatch.rb
|
52
|
+
lib/bugwatch/adapters.rb
|
53
|
+
lib/bugwatch/analysis.rb
|
54
|
+
lib/bugwatch/attrs.rb
|
55
|
+
lib/bugwatch/churn.rb
|
56
|
+
lib/bugwatch/commit.rb
|
57
|
+
lib/bugwatch/complexity_score.rb
|
58
|
+
lib/bugwatch/diff.rb
|
59
|
+
lib/bugwatch/diff_parser.rb
|
60
|
+
lib/bugwatch/exception_data.rb
|
61
|
+
lib/bugwatch/exception_tracker.rb
|
62
|
+
lib/bugwatch/file_adapters/ruby_file_adapter.rb
|
63
|
+
lib/bugwatch/flog_score.rb
|
64
|
+
lib/bugwatch/import.rb
|
65
|
+
lib/bugwatch/method_parser.rb
|
66
|
+
lib/bugwatch/repo.rb
|
67
|
+
lib/bugwatch/ruby_complexity.rb
|
68
|
+
lib/bugwatch/tag.rb
|
69
|
+
lib/bugwatch/tree.rb
|
70
|
+
vendor/flog/lib/flog.rb
|
71
|
+
]
|
72
|
+
# = MANIFEST =
|
73
|
+
|
74
|
+
end
|
data/lib/bugwatch.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright (c) 2013, Groupon, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions
|
6
|
+
# are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of GROUPON nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
20
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
21
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
25
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
require 'rugged'
|
32
|
+
require 'grit'
|
33
|
+
|
34
|
+
require File.expand_path('../bugwatch/adapters', __FILE__)
|
35
|
+
require File.expand_path('../bugwatch/analysis', __FILE__)
|
36
|
+
require File.expand_path('../bugwatch/attrs', __FILE__)
|
37
|
+
require File.expand_path('../bugwatch/complexity_score', __FILE__)
|
38
|
+
require File.expand_path('../bugwatch/diff_parser', __FILE__)
|
39
|
+
require File.expand_path('../bugwatch/ruby_complexity', __FILE__)
|
40
|
+
require File.expand_path('../bugwatch/churn', __FILE__)
|
41
|
+
require File.expand_path('../bugwatch/commit', __FILE__)
|
42
|
+
require File.expand_path('../bugwatch/diff', __FILE__)
|
43
|
+
require File.expand_path('../bugwatch/exception_data', __FILE__)
|
44
|
+
require File.expand_path('../bugwatch/exception_tracker', __FILE__)
|
45
|
+
require File.expand_path('../bugwatch/flog_score', __FILE__)
|
46
|
+
require File.expand_path('../bugwatch/import', __FILE__)
|
47
|
+
require File.expand_path('../bugwatch/method_parser', __FILE__)
|
48
|
+
require File.expand_path('../bugwatch/repo', __FILE__)
|
49
|
+
require File.expand_path('../bugwatch/tag', __FILE__)
|
50
|
+
require File.expand_path('../bugwatch/tree', __FILE__)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright (c) 2013, Groupon, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions
|
6
|
+
# are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of GROUPON nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
20
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
21
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
25
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
require 'bugwatch/file_adapters/ruby_file_adapter'
|
32
|
+
require 'bugwatch/ruby_complexity'
|
33
|
+
|
34
|
+
module Bugwatch
|
35
|
+
|
36
|
+
Adapter = Struct.new(:file, :complexity)
|
37
|
+
|
38
|
+
@adapters = {
|
39
|
+
ruby: Adapter.new(RubyFileAdapter, RubyComplexity)
|
40
|
+
}
|
41
|
+
|
42
|
+
def self.add_adapter(name, file_adapter, complexity=nil)
|
43
|
+
@adapters.merge!(name => Adapter.new(file_adapter, complexity))
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.adapters
|
47
|
+
@adapters
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright (c) 2013, Groupon, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions
|
6
|
+
# are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of GROUPON nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
20
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
21
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
25
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
module Bugwatch
|
32
|
+
|
33
|
+
class Analysis
|
34
|
+
|
35
|
+
def initialize(repo, caching_strategy)
|
36
|
+
@repo = repo
|
37
|
+
@caching_strategy = caching_strategy
|
38
|
+
end
|
39
|
+
|
40
|
+
def analyze(*analyzers)
|
41
|
+
analyzers.each do |analyzer|
|
42
|
+
commits_to_analyze(analyzer).each do |commit_sha|
|
43
|
+
commit = @repo.commit(commit_sha)
|
44
|
+
analyzer.call(commit)
|
45
|
+
@caching_strategy.store_analysis(commit, analyzer.key)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def commits_to_analyze(analyzer)
|
53
|
+
@caching_strategy.imported - @caching_strategy.analyzed(analyzer.key)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright (c) 2013, Groupon, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions
|
6
|
+
# are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of GROUPON nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
20
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
21
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
25
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
module Bugwatch
|
32
|
+
|
33
|
+
module Attrs
|
34
|
+
|
35
|
+
def attrs(*attributes)
|
36
|
+
define_attr_reader(attributes) do |attr|
|
37
|
+
attr
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def lazy_attrs(*attributes)
|
42
|
+
define_attr_reader(attributes) do |attr|
|
43
|
+
if attr.respond_to? :call
|
44
|
+
attr.call
|
45
|
+
else
|
46
|
+
attr
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def define_attr_reader(attributes, &block)
|
54
|
+
attributes.each do |attribute|
|
55
|
+
define_method(attribute) do
|
56
|
+
data = instance_variable_get('@attributes') || {}
|
57
|
+
block.call(data[attribute])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (c) 2013, Groupon, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions
|
6
|
+
# are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of GROUPON nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
20
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
21
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
25
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
module Bugwatch
|
32
|
+
|
33
|
+
class Churn
|
34
|
+
|
35
|
+
DEFAULT_CHURN = 0
|
36
|
+
|
37
|
+
def initialize(commit_stats, file_adapter)
|
38
|
+
@commit_stats = commit_stats
|
39
|
+
@file_adapter = file_adapter
|
40
|
+
end
|
41
|
+
|
42
|
+
def score
|
43
|
+
calculate_churn(&@file_adapter.method(:analyzable_file?))
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_score
|
47
|
+
calculate_churn(&@file_adapter.method(:test_file?))
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def calculate_churn(&filter)
|
53
|
+
@commit_stats.select do |stat|
|
54
|
+
filter.call(stat.file)
|
55
|
+
end.map(&:total).reduce(:+) || DEFAULT_CHURN
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# Copyright (c) 2013, Groupon, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions
|
6
|
+
# are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of GROUPON nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
20
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
21
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
25
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
module Bugwatch
|
32
|
+
|
33
|
+
class Commit
|
34
|
+
|
35
|
+
include RubyFileAdapter
|
36
|
+
extend Attrs
|
37
|
+
|
38
|
+
Stats = Struct.new(:file, :additions, :deletions, :total)
|
39
|
+
|
40
|
+
def self.from_grit(grit)
|
41
|
+
author = grit.author
|
42
|
+
committer = grit.committer
|
43
|
+
stats = Enumerator.new {|y| grit.stats.files.each {|data| y << Stats.new(*data) } }
|
44
|
+
diffs = Enumerator.new {|y| grit.diffs.each {|diff| y << Diff.from_grit(diff) } }
|
45
|
+
tree = Tree.new(grit.tree)
|
46
|
+
new sha: grit.sha, message: grit.short_message, diffs: diffs, stats: stats, tree: tree,
|
47
|
+
author_name: author.name, author_email: author.email, authored_date: grit.authored_date,
|
48
|
+
committer_name: committer.name, committer_email: committer.email, committed_date: grit.committed_date
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize(attributes={})
|
52
|
+
@attributes = attributes
|
53
|
+
end
|
54
|
+
|
55
|
+
attrs :sha, :message, :diffs, :stats
|
56
|
+
attrs :author_name, :author_email, :authored_date
|
57
|
+
attrs :committer_name, :committer_email, :committed_date
|
58
|
+
lazy_attrs :tree
|
59
|
+
|
60
|
+
def files
|
61
|
+
@files ||= stats.map(&:file)
|
62
|
+
end
|
63
|
+
|
64
|
+
def complexity(lang=:ruby)
|
65
|
+
adapter = Bugwatch.adapters[lang]
|
66
|
+
adapter.complexity.new(diffs) if adapter && adapter.complexity
|
67
|
+
end
|
68
|
+
|
69
|
+
def churn(lang=:ruby)
|
70
|
+
adapter = Bugwatch.adapters[lang]
|
71
|
+
Churn.new(stats, adapter.file) if adapter
|
72
|
+
end
|
73
|
+
|
74
|
+
# TODO don't use grit blob
|
75
|
+
def identify(filename, line_number)
|
76
|
+
blob = tree / filename
|
77
|
+
blob ? MethodParser.find(blob.data, line_number..line_number) : {}
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|