bugspots 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +85 -0
- data/Rakefile +1 -0
- data/bin/bugspots +33 -0
- data/bugspots.gemspec +27 -0
- data/lib/bugspots.rb +2 -0
- data/lib/bugspots/scanner.rb +33 -0
- data/lib/bugspots/version.rb +3 -0
- metadata +78 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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,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
|
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:
|