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.
@@ -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
@@ -1,4 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ #gem 'rugged', git: 'git://github.com/libgit2/rugged.git', branch: 'development', submodules: true
4
+
3
5
  # Specify your gem's dependencies in bugspots.gemspec
4
6
  gemspec
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:
@@ -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 Grit::InvalidGitRepositoryError
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
@@ -4,4 +4,4 @@ if ARGV.empty? or not Dir.exists? ARGV[0]
4
4
  ARGV.unshift Dir.pwd
5
5
  end
6
6
 
7
- exec("bugspots #{ARGV.join(' ')}")
7
+ exec 'bugspots', ARGV.join(' ')
@@ -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 "grit"
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"
@@ -1,33 +1,43 @@
1
- require 'rainbow'
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
- repo = Grit::Repo.new(repo)
10
- unless repo.branches.find { |e| e.name == branch }
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
- regex ||= /fix(es|ed)?|close(s|d)?/i
16
+ walker = Rugged::Walker.new(repo)
17
+ walker.sorting(Rugged::SORT_TOPO | Rugged::SORT_REVERSE)
16
18
 
17
- tree = repo.tree(branch)
19
+ tip = Rugged::Branch.lookup(repo, branch).tip.oid
20
+ walker.push(tip)
18
21
 
19
- commit_list = repo.git.rev_list({:max_count => false, :no_merges => true, :pretty => "raw", :timeout => false}, branch)
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.stats.files.map {|s| s.first}.select{ |s| tree/s }
23
- fixes << Fix.new(commit.short_message, commit.date, files)
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
- t = 1 - ((Time.now - fix.date).to_f / (Time.now - fixes.last.date))
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
@@ -1,3 +1,3 @@
1
1
  module Bugspots
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
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.1.2
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: 2012-04-17 00:00:00.000000000 Z
11
+ date: 2014-06-14 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: grit
16
- requirement: &2152884960 !ruby/object:Gem::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: *2152884960
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: &2152882760 !ruby/object:Gem::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: *2152882760
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: 1.8.10
79
+ rubygems_version: 2.0.6
76
80
  signing_key:
77
- specification_version: 3
81
+ specification_version: 4
78
82
  summary: Implementation of simple bug prediction hotspot heuristic
79
83
  test_files: []
80
84
  has_rdoc: