bugspots 0.1.0 → 0.1.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 +1 -0
- data/README.md +3 -3
- data/bin/bugspots +71 -0
- data/bin/git-bugspots +3 -57
- data/lib/bugspots/scanner.rb +8 -8
- data/lib/bugspots/version.rb +1 -1
- metadata +8 -6
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -10,15 +10,15 @@ Point bugspots at any git repo and it will identify the hotspots for you.
|
|
10
10
|
|
11
11
|
```
|
12
12
|
$> gem install bugspots
|
13
|
-
$>
|
14
|
-
$> git bugspots
|
13
|
+
$> bugspots /path/to/repo
|
14
|
+
$> git bugspots (in root of current git project, --help for options)
|
15
15
|
```
|
16
16
|
|
17
17
|
## Results
|
18
18
|
|
19
19
|
```
|
20
20
|
$> cd /your/git/repo
|
21
|
-
$> git bugspots
|
21
|
+
$> git bugspots -d 500
|
22
22
|
|
23
23
|
.. example output ..
|
24
24
|
|
data/bin/bugspots
ADDED
@@ -0,0 +1,71 @@
|
|
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
|
+
|
15
|
+
# Option: Set Branch
|
16
|
+
opts.on('-b', '--branch [name]', 'branch to crawl') do |b|
|
17
|
+
options[:branch] = b.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
# Option: Set Depth
|
21
|
+
opts.on('-d', '--depth [depth]', 'depth of log crawl (integer)') do |d|
|
22
|
+
options[:depth] = d.to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
# Option: Set Bugfix Indicator
|
26
|
+
opts.on('-w', '--words ["w1,w2"]', 'bugfix indicator word list, ie: "fixes,closed"') do |words|
|
27
|
+
options[:regex] = Regexp.new(words.split(',').join('|'))
|
28
|
+
end
|
29
|
+
|
30
|
+
# Option: Set Bugfix Indicator
|
31
|
+
opts.on('-r', '--regex [regex]', Regexp, 'bugfix indicator regex, ie: "fix(es|ed)?" or "/fixes #(\d+)/i"') do |regex|
|
32
|
+
options[:regex] = regex
|
33
|
+
end
|
34
|
+
|
35
|
+
# Option: Set Timestamp Display
|
36
|
+
opts.on('--display-timestamps', 'show timestamps of each identified fix commit') do |dt|
|
37
|
+
options[:display_timestamps] = true
|
38
|
+
end
|
39
|
+
end.parse!
|
40
|
+
|
41
|
+
# Set a reasonable default of depth
|
42
|
+
options[:depth] ||= 500
|
43
|
+
|
44
|
+
# Set master as the default branch
|
45
|
+
options[:branch] ||= "master"
|
46
|
+
|
47
|
+
puts "Scanning #{ARGV[0]} repo".foreground(:green)
|
48
|
+
|
49
|
+
begin
|
50
|
+
fixes, spots = Bugspots.scan(ARGV[0], options[:branch], options[:depth], options[:regex])
|
51
|
+
|
52
|
+
puts "\tFound #{fixes.size} bugfix commits, with #{spots.size} hotspots:".foreground(:yellow)
|
53
|
+
puts
|
54
|
+
|
55
|
+
puts "\tFixes:".foreground(:green).underline
|
56
|
+
fixes.each do |fix|
|
57
|
+
message = "\t\t- "
|
58
|
+
message << "#{fix.date} " if options[:display_timestamps]
|
59
|
+
message << "#{fix.message}"
|
60
|
+
puts message.foreground(:yellow)
|
61
|
+
end
|
62
|
+
|
63
|
+
puts "\n"
|
64
|
+
puts "\tHotspots:".foreground(:green).underline
|
65
|
+
spots.each do |spot|
|
66
|
+
puts "\t\t#{spot.score}".foreground(:red) + " - #{spot.file}".foreground(:yellow)
|
67
|
+
end
|
68
|
+
|
69
|
+
rescue Grit::InvalidGitRepositoryError
|
70
|
+
puts "Invalid Git repository - please run from or specify the full path to the root of the project.".foreground(:red)
|
71
|
+
end
|
data/bin/git-bugspots
CHANGED
@@ -1,61 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
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
|
-
|
15
|
-
# Option: Set Branch
|
16
|
-
opts.on('-b', '--branch [name]', 'branch to crawl') do |b|
|
17
|
-
options[:branch] = b.to_s
|
18
|
-
end
|
19
|
-
|
20
|
-
# Option: Set Depth
|
21
|
-
opts.on('-d', '--depth [depth]', 'depth of log crawl (integer)') do |d|
|
22
|
-
options[:depth] = d.to_i
|
23
|
-
end
|
24
|
-
|
25
|
-
# Option: Set Bugfix Indicator
|
26
|
-
opts.on('-w', '--words ["w1,w2"]', 'bugfix indicator, ie: "fixes,closed"') do |words|
|
27
|
-
options[:words] = words
|
28
|
-
end
|
29
|
-
|
30
|
-
# Option: Set Timestamp Display
|
31
|
-
opts.on('--display-timestamps', 'show timestamps of each identified fix commit') do |dt|
|
32
|
-
options[:display_timestamps] = true
|
33
|
-
end
|
34
|
-
end.parse!
|
35
|
-
|
36
|
-
# Set a reasonable default of depth
|
37
|
-
options[:depth] ||= 500
|
38
|
-
|
39
|
-
# Set master as the default branch
|
40
|
-
options[:branch] ||= "master"
|
41
|
-
|
42
|
-
puts "Scanning #{ARGV[0]} repo".foreground(:green)
|
43
|
-
|
44
|
-
fixes, spots = Bugspots.scan(ARGV[0], options[:branch], options[:depth], options[:words])
|
45
|
-
|
46
|
-
puts "\tFound #{fixes.size} bugfix commits, with #{spots.size} hotspots:".foreground(:yellow)
|
47
|
-
puts
|
48
|
-
|
49
|
-
puts "\tFixes:".foreground(:green).underline
|
50
|
-
fixes.each do |fix|
|
51
|
-
message = "\t\t- "
|
52
|
-
message << "#{fix.date} " if options[:display_timestamps]
|
53
|
-
message << "#{fix.message}"
|
54
|
-
puts message.foreground(:yellow)
|
3
|
+
if ARGV.empty? or not Dir.exists? ARGV[0]
|
4
|
+
ARGV.unshift Dir.pwd
|
55
5
|
end
|
56
6
|
|
57
|
-
|
58
|
-
puts "\tHotspots:".foreground(:green).underline
|
59
|
-
spots.each do |spot|
|
60
|
-
puts "\t\t#{spot.score}".foreground(:red) + " - #{spot.file}".foreground(:yellow)
|
61
|
-
end
|
7
|
+
exec("bugspots #{ARGV.join(' ')}")
|
data/lib/bugspots/scanner.rb
CHANGED
@@ -5,19 +5,19 @@ module Bugspots
|
|
5
5
|
Fix = Struct.new(:message, :date, :files)
|
6
6
|
Spot = Struct.new(:file, :score)
|
7
7
|
|
8
|
-
def self.scan(repo, branch = "master", depth = 500,
|
8
|
+
def self.scan(repo, branch = "master", depth = 500, regex = nil)
|
9
9
|
repo = Grit::Repo.new(repo)
|
10
|
+
unless repo.branches.find { |e| e.name == branch }
|
11
|
+
raise ArgumentError, "no such branch in the repo: #{branch}"
|
12
|
+
end
|
10
13
|
fixes = []
|
11
14
|
|
12
|
-
|
13
|
-
message_matchers = /#{words.split(',').join('|')}/
|
14
|
-
else
|
15
|
-
message_matchers = /fix(es|ed)?|close(s|d)?/i
|
16
|
-
end
|
15
|
+
regex ||= /fix(es|ed)?|close(s|d)?/i
|
17
16
|
|
17
|
+
tree = repo.tree(branch)
|
18
18
|
repo.commits(branch, depth).each do |commit|
|
19
|
-
if commit.message =~
|
20
|
-
files = commit.stats.files.map {|s| s.first}
|
19
|
+
if commit.message =~ regex
|
20
|
+
files = commit.stats.files.map {|s| s.first}.select{ |s| tree/s }
|
21
21
|
fixes << Fix.new(commit.short_message, commit.date, files)
|
22
22
|
end
|
23
23
|
end
|
data/lib/bugspots/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bugspots
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: grit
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153130800 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153130800
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rainbow
|
27
|
-
requirement: &
|
27
|
+
requirement: &2153129280 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,11 +32,12 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153129280
|
36
36
|
description: Implementation of simple bug prediction hotspot heuristic
|
37
37
|
email:
|
38
38
|
- ilya@igvita.com
|
39
39
|
executables:
|
40
|
+
- bugspots
|
40
41
|
- git-bugspots
|
41
42
|
extensions: []
|
42
43
|
extra_rdoc_files: []
|
@@ -45,6 +46,7 @@ files:
|
|
45
46
|
- Gemfile
|
46
47
|
- README.md
|
47
48
|
- Rakefile
|
49
|
+
- bin/bugspots
|
48
50
|
- bin/git-bugspots
|
49
51
|
- bugspots.gemspec
|
50
52
|
- lib/bugspots.rb
|