bugwatch 0.1

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/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