bugspots 0.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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bugspots.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # Bugspots - Bug Prediction Heuristic
2
+
3
+ An implementation of the simple bug prediction heuristic outlined by the Google Engineering team: [Bug Prediction at Google](http://google-engtools.blogspot.com/2011/12/bug-prediction-at-google.html)
4
+
5
+ > Well, we actually have a great, authoritative record of where code has been requiring fixes: our bug tracker and our source control commit log! The research indicates that predicting bugs from the source history works very well, so we decided to deploy it at Google.
6
+
7
+ Point bugspots at any git repo and it will identify the hotspots for you.
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ $> gem install bugspots
13
+ $> bugspots /path/to/repo
14
+ ```
15
+
16
+ ## Results
17
+
18
+ ```
19
+ $> bugspots /git/eventmachine
20
+
21
+ Scanning /git/eventmachine repo
22
+ Found 31 bugfix commits, with 23 hotspots:
23
+
24
+ Fixes:
25
+ - Revert "Write maximum of 16KB of data to an SSL connection per tick (fixes #233)" for #273
26
+ - Do not close attached sockets (fixes #200)
27
+ - Write maximum of 16KB of data to an SSL connection per tick (fixes #233)
28
+ - Merge branch 'master' into close_schedule_fix
29
+ - Remove dependency on readbytes.rb for ruby 1.9 (fixes #167, #234)
30
+ - Fix compilation on MSVC2008 (fixes #253)
31
+ - EM::Deferrable#(callback|errback|timeout) now return self so you can chain them (closes #177)
32
+ - Make EventMachine::Connection#get_peername and #get_sockname valid for IPv6 (closes #132)
33
+ - reconnect DNS socket if closed
34
+ - Use String#bytesize in EM::Connection#send_datagram for 1.9 (closes #153)
35
+ - Fix an issue that would cause the EM process to block when the loopbreak pipe filled up (closes #158)
36
+ - namespace std is already included, so just call min(). fixes vc6 issue with min macro
37
+ - Use close() instead of closesocket() to prevent FD leaks on windows.
38
+ - Stop advertising non-available authentication mechanisms, allow multi-line authentication - fixes compatibility with javamail
39
+ - typo fixes and undef fstat for ruby on Windows
40
+ - Deprecate now aged info, as it's fixed
41
+ - Some fixes for Solaris and Nexenta (opensolaris kernel + linux userland)
42
+ - Some fixes for solaris
43
+ - Minor fixes for rbx compatibility
44
+ - Reduce the size of the RunEpollOnce stack frame by 800kb. This fixes the long-standing epoll+threads issue (#84)
45
+ - Fixed aggregated event handling for kqueue and notify, fixed path for ifconfig.
46
+ - More win32 fixes
47
+ - Added test for reactor_thread? and fixed up EM.schedule for pre-reactor schedules
48
+ - Merge branch 'master' of git@github.com:eventmachine/eventmachine
49
+ - Use read instead of recv in ConnectionDescriptor::Read (fixes EM.attach issues with pipes)
50
+ - Use false to indicated a cancelled timer instead of using an empty proc. Reduces mem usage in certain situations.
51
+ - Inotify fixes: file_delete only fires after fds have been closed, use syscall hackery for older linux distributions (*cough* debian)
52
+ - Clean up deferrable.rb: fixed rdoc, alias method wrappers, remove unnecessary forwardable
53
+ - More solaris build fixes.
54
+ - More solaris build issues fixed
55
+ - fixed a small bug with basic auth (cherry-pick conflict merge from mmmurf (closes #92))
56
+
57
+ Hotspots:
58
+ 0.9723 - ext/ed.cpp
59
+ 0.3311 - ext/ed.h
60
+ 0.3271 - ext/em.cpp
61
+ 0.3034 - lib/eventmachine.rb
62
+ 0.2433 - lib/em/protocols/postgres3.rb
63
+ 0.2403 - ext/project.h
64
+ 0.0431 - lib/em/deferrable.rb
65
+ 0.029 - ext/cmain.cpp
66
+ 0.0278 - ext/rubymain.cpp
67
+ 0.0277 - ext/eventmachine.h
68
+ 0.0241 - lib/em/resolver.rb
69
+ 0.0241 - tests/test_resolver.rb
70
+ 0.0225 - lib/em/connection.rb
71
+ 0.0013 - lib/em/protocols/smtpserver.rb
72
+ 0.0003 - ext/extconf.rb
73
+ 0.0002 - tests/test_basic.rb
74
+ 0.0001 - ext/em.h
75
+ 0.0001 - ext/cplusplus.cpp
76
+ 0.0001 - ext/fastfilereader/extconf.rb
77
+ 0.0 - lib/em/filewatcher.rb
78
+ 0.0 - tests/test_file_watch.rb
79
+ 0.0 - ext/fastfilereader/mapper.cpp
80
+ 0.0 - lib/protocols/httpclient.rb
81
+ ```
82
+
83
+ ### License
84
+
85
+ (MIT License) - Copyright (c) 2011 Ilya Grigorik
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/bugspots ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require 'bugspots'
7
+ require 'optparse'
8
+
9
+ ARGV << '--help' if ARGV.empty?
10
+
11
+ options = {}
12
+ OptionParser.new do |opts|
13
+ opts.banner = "Usage: bugspots /path/to/git/repo"
14
+ end.parse!
15
+
16
+ puts "Scanning #{ARGV[0]} repo".foreground(:green)
17
+
18
+ fixes, spots = Bugspots.scan(ARGV[0])
19
+
20
+ puts "\tFound #{fixes.size} bugfix commits, with #{spots.size} hotspots:".foreground(:yellow)
21
+ puts
22
+
23
+ puts "\tFixes:".foreground(:green).underline
24
+ fixes.each do |fix|
25
+ puts "\t\t- #{fix.message}".foreground(:yellow)
26
+ end
27
+
28
+ puts "\n"
29
+ puts "\tHotspots:".foreground(:green).underline
30
+ spots.each do |spot|
31
+ puts "\t\t#{spot.score}".foreground(:red) + " - #{spot.file}".foreground(:yellow)
32
+ end
33
+
data/bugspots.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bugspots/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bugspots"
7
+ s.version = Bugspots::VERSION
8
+ s.authors = ["Ilya Grigorik"]
9
+ s.email = ["ilya@igvita.com"]
10
+ s.homepage = "https://github.com/igrigorik/bugspots"
11
+ s.summary = "Implementation of simple bug prediction hotspot heuristic"
12
+ s.description = s.summary
13
+
14
+ s.rubyforge_project = "bugspots"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "grit"
22
+ s.add_dependency "rainbow"
23
+
24
+ # specify any dependencies here; for example:
25
+ # s.add_development_dependency "rspec"
26
+ # s.add_runtime_dependency "rest-client"
27
+ end
data/lib/bugspots.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "bugspots/version"
2
+ require "bugspots/scanner"
@@ -0,0 +1,33 @@
1
+ require 'rainbow'
2
+ require 'grit'
3
+
4
+ module Bugspots
5
+ Fix = Struct.new(:message, :date, :files)
6
+ Spot = Struct.new(:file, :score)
7
+
8
+ def self.scan(repo, depth = 500)
9
+ repo = Grit::Repo.new(repo)
10
+ fixes = []
11
+
12
+ repo.commits('master', depth).each do |commit|
13
+ if commit.message =~ /fix(es|ed)|close(s|d)/
14
+ files = commit.stats.files.map {|s| s.first}
15
+ fixes << Fix.new(commit.short_message, commit.date, files)
16
+ end
17
+ end
18
+
19
+ hotspots = Hash.new(0)
20
+ fixes.each do |fix|
21
+ fix.files.each do |file|
22
+ t = 1 - ((Time.now - fix.date).to_f / (Time.now - fixes.last.date))
23
+ hotspots[file] += 1/(1+Math.exp((-12*t)+12))
24
+ end
25
+ end
26
+
27
+ spots = hotspots.sort_by {|k,v| v}.reverse.collect do |spot|
28
+ Spot.new(spot.first, spot.last.round(4))
29
+ end
30
+
31
+ return fixes, spots
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module Bugspots
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bugspots
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ilya Grigorik
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: grit
16
+ requirement: &2160537420 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2160537420
25
+ - !ruby/object:Gem::Dependency
26
+ name: rainbow
27
+ requirement: &2160537000 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2160537000
36
+ description: Implementation of simple bug prediction hotspot heuristic
37
+ email:
38
+ - ilya@igvita.com
39
+ executables:
40
+ - bugspots
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - README.md
47
+ - Rakefile
48
+ - bin/bugspots
49
+ - bugspots.gemspec
50
+ - lib/bugspots.rb
51
+ - lib/bugspots/scanner.rb
52
+ - lib/bugspots/version.rb
53
+ homepage: https://github.com/igrigorik/bugspots
54
+ licenses: []
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project: bugspots
73
+ rubygems_version: 1.8.10
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Implementation of simple bug prediction hotspot heuristic
77
+ test_files: []
78
+ has_rdoc: