bugspots 0.1.2 → 0.2.0
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.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/README.md +3 -3
- data/bin/bugspots +3 -1
- data/bin/git-bugspots +1 -1
- data/bugspots.gemspec +2 -2
- data/lib/bugspots/scanner.rb +22 -12
- data/lib/bugspots/version.rb +1 -1
- metadata +22 -18
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b3605e350429ccbd15135861af54c0cea4333298
|
4
|
+
data.tar.gz: 6c1ccbbd2ca85c606c97dfdb93bae9267fa170bd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 32a6c2d01b8ff2e4121061261b7d7c600cac44722d2775ba561cece41907cbc70fba290b7664cf906c33b39e56ee04c03dae44a5c00741cb19c942d4b7493c6a
|
7
|
+
data.tar.gz: 18e6e5a7d0b60af895f4cac8b0c517f4f16f973bff0e6874f086cfe97054bba6ca9258c5011fcfa101dbf23ee95f90bd1b573fe95c59096bcab4737f94ac3e1f
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Point bugspots at any git repo and it will identify the hotspots for you.
|
|
8
8
|
|
9
9
|
## Usage
|
10
10
|
|
11
|
-
```
|
11
|
+
```bash
|
12
12
|
$> gem install bugspots
|
13
13
|
$> bugspots /path/to/repo
|
14
14
|
$> git bugspots (in root of current git project, --help for options)
|
@@ -16,11 +16,11 @@ $> git bugspots (in root of current git project, --help for options)
|
|
16
16
|
|
17
17
|
## Results
|
18
18
|
|
19
|
-
```
|
19
|
+
```bash
|
20
20
|
$> cd /your/git/repo
|
21
21
|
$> git bugspots -d 500
|
22
22
|
|
23
|
-
.. example output ..
|
23
|
+
.. example output ..
|
24
24
|
|
25
25
|
Scanning /git/eventmachine repo
|
26
26
|
Found 31 bugfix commits, with 23 hotspots:
|
data/bin/bugspots
CHANGED
@@ -5,6 +5,8 @@ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
|
5
5
|
|
6
6
|
require 'bugspots'
|
7
7
|
require 'optparse'
|
8
|
+
require 'rainbow'
|
9
|
+
require 'rainbow/ext/string'
|
8
10
|
|
9
11
|
ARGV << '--help' if ARGV.empty?
|
10
12
|
|
@@ -66,6 +68,6 @@ begin
|
|
66
68
|
puts "\t\t#{spot.score}".foreground(:red) + " - #{spot.file}".foreground(:yellow)
|
67
69
|
end
|
68
70
|
|
69
|
-
rescue
|
71
|
+
rescue Rugged::RepositoryError
|
70
72
|
puts "Invalid Git repository - please run from or specify the full path to the root of the project.".foreground(:red)
|
71
73
|
end
|
data/bin/git-bugspots
CHANGED
data/bugspots.gemspec
CHANGED
@@ -18,9 +18,9 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_dependency "
|
21
|
+
s.add_dependency "rugged"
|
22
22
|
s.add_dependency "rainbow"
|
23
|
-
|
23
|
+
|
24
24
|
# specify any dependencies here; for example:
|
25
25
|
# s.add_development_dependency "rspec"
|
26
26
|
# s.add_runtime_dependency "rest-client"
|
data/lib/bugspots/scanner.rb
CHANGED
@@ -1,33 +1,43 @@
|
|
1
|
-
require
|
2
|
-
require 'grit'
|
1
|
+
require "rugged"
|
3
2
|
|
4
3
|
module Bugspots
|
5
4
|
Fix = Struct.new(:message, :date, :files)
|
6
5
|
Spot = Struct.new(:file, :score)
|
7
6
|
|
8
7
|
def self.scan(repo, branch = "master", depth = 500, regex = nil)
|
9
|
-
|
10
|
-
|
8
|
+
regex ||= /\b(fix(es|ed)?|close(s|d)?)\b/i
|
9
|
+
fixes = []
|
10
|
+
|
11
|
+
repo = Rugged::Repository.new(repo)
|
12
|
+
unless Rugged::Branch.each_name(repo).sort.find { |b| b == branch }
|
11
13
|
raise ArgumentError, "no such branch in the repo: #{branch}"
|
12
14
|
end
|
13
|
-
fixes = []
|
14
15
|
|
15
|
-
|
16
|
+
walker = Rugged::Walker.new(repo)
|
17
|
+
walker.sorting(Rugged::SORT_TOPO | Rugged::SORT_REVERSE)
|
16
18
|
|
17
|
-
|
19
|
+
tip = Rugged::Branch.lookup(repo, branch).tip.oid
|
20
|
+
walker.push(tip)
|
18
21
|
|
19
|
-
|
20
|
-
Grit::Commit.list_from_string(repo, commit_list).each do |commit|
|
22
|
+
walker.each do |commit|
|
21
23
|
if commit.message =~ regex
|
22
|
-
files = commit.
|
23
|
-
|
24
|
+
files = commit.diff(commit.parents.first).deltas.collect do |d|
|
25
|
+
d.old_file[:path]
|
26
|
+
end
|
27
|
+
fixes << Fix.new(commit.message.split("\n").first, commit.time, files)
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
31
|
hotspots = Hash.new(0)
|
28
32
|
fixes.each do |fix|
|
29
33
|
fix.files.each do |file|
|
30
|
-
|
34
|
+
# The timestamp used in the equation is normalized from 0 to 1, where
|
35
|
+
# 0 is the earliest point in the code base, and 1 is now (where now is
|
36
|
+
# when the algorithm was run). Note that the score changes over time
|
37
|
+
# with this algorithm due to the moving normalization; it's not meant
|
38
|
+
# to provide some objective score, only provide a means of comparison
|
39
|
+
# between one file and another at any one point in time
|
40
|
+
t = 1 - ((Time.now - fix.date).to_f / (Time.now - fixes.first.date))
|
31
41
|
hotspots[file] += 1/(1+Math.exp((-12*t)+12))
|
32
42
|
end
|
33
43
|
end
|
data/lib/bugspots/version.rb
CHANGED
metadata
CHANGED
@@ -1,38 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bugspots
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Ilya Grigorik
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-06-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement:
|
17
|
-
none: false
|
14
|
+
name: rugged
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
|
-
version_requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
25
27
|
- !ruby/object:Gem::Dependency
|
26
28
|
name: rainbow
|
27
|
-
requirement:
|
28
|
-
none: false
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
29
30
|
requirements:
|
30
|
-
- -
|
31
|
+
- - '>='
|
31
32
|
- !ruby/object:Gem::Version
|
32
33
|
version: '0'
|
33
34
|
type: :runtime
|
34
35
|
prerelease: false
|
35
|
-
version_requirements:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
36
41
|
description: Implementation of simple bug prediction hotspot heuristic
|
37
42
|
email:
|
38
43
|
- ilya@igvita.com
|
@@ -54,27 +59,26 @@ files:
|
|
54
59
|
- lib/bugspots/version.rb
|
55
60
|
homepage: https://github.com/igrigorik/bugspots
|
56
61
|
licenses: []
|
62
|
+
metadata: {}
|
57
63
|
post_install_message:
|
58
64
|
rdoc_options: []
|
59
65
|
require_paths:
|
60
66
|
- lib
|
61
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
-
none: false
|
63
68
|
requirements:
|
64
|
-
- -
|
69
|
+
- - '>='
|
65
70
|
- !ruby/object:Gem::Version
|
66
71
|
version: '0'
|
67
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
-
none: false
|
69
73
|
requirements:
|
70
|
-
- -
|
74
|
+
- - '>='
|
71
75
|
- !ruby/object:Gem::Version
|
72
76
|
version: '0'
|
73
77
|
requirements: []
|
74
78
|
rubyforge_project: bugspots
|
75
|
-
rubygems_version:
|
79
|
+
rubygems_version: 2.0.6
|
76
80
|
signing_key:
|
77
|
-
specification_version:
|
81
|
+
specification_version: 4
|
78
82
|
summary: Implementation of simple bug prediction hotspot heuristic
|
79
83
|
test_files: []
|
80
84
|
has_rdoc:
|