metior 0.1.2 → 0.1.3
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/Gemfile +0 -2
- data/Gemfile.lock +0 -1
- data/lib/metior.rb +22 -16
- data/lib/metior/github/commit.rb +4 -4
- data/lib/metior/github/repository.rb +18 -16
- data/lib/metior/vcs.rb +3 -1
- data/lib/metior/version.rb +1 -1
- data/metior.gemspec +1 -0
- data/test/fixtures.rb +115 -0
- data/test/helper.rb +1 -0
- data/test/test_git.rb +94 -0
- data/test/test_github.rb +103 -6
- data/test/test_repository.rb +0 -104
- metadata +6 -10
- data/test/mock_vcs/actor.rb +0 -28
- data/test/mock_vcs/commit.rb +0 -53
- data/test/mock_vcs/repository.rb +0 -72
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/lib/metior.rb
CHANGED
@@ -5,12 +5,6 @@
|
|
5
5
|
|
6
6
|
require 'bundler'
|
7
7
|
|
8
|
-
libdir = File.dirname(__FILE__)
|
9
|
-
Dir.chdir libdir do
|
10
|
-
Bundler.setup
|
11
|
-
end
|
12
|
-
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
13
|
-
|
14
8
|
require 'core_ext/object'
|
15
9
|
require 'metior/git'
|
16
10
|
require 'metior/github'
|
@@ -22,6 +16,14 @@ require 'metior/version'
|
|
22
16
|
# @author Sebastian Staudt
|
23
17
|
module Metior
|
24
18
|
|
19
|
+
# Returns the Bundler runtime to access Metior's dependencies
|
20
|
+
#
|
21
|
+
# @return [Bundler::Runtime] The Bundler runtime instance
|
22
|
+
def self.runtime
|
23
|
+
@@runtime ||= Bundler::Runtime.new File.dirname(__FILE__),
|
24
|
+
Bundler.definition
|
25
|
+
end
|
26
|
+
|
25
27
|
# Creates a new repository for the given repository type and path
|
26
28
|
#
|
27
29
|
# @param [Symbol] type The type of the repository, e.g. `:git`
|
@@ -35,19 +37,23 @@ module Metior
|
|
35
37
|
# Calculates simplistic stats for the given repository and branch
|
36
38
|
#
|
37
39
|
# @param [Symbol] type The type of the repository, e.g. `:git`
|
38
|
-
# @param [
|
39
|
-
# @param [String]
|
40
|
-
#
|
40
|
+
# @param [Array<Object>] options The options for the repository
|
41
|
+
# @param [String, Range] range The range of commits for which the commits
|
42
|
+
# should be loaded. This may be given as a string
|
43
|
+
# (`'master..development'`), a range (`'master'..'development'`)
|
44
|
+
# or as a single ref (`'master'`). A single ref name means all
|
45
|
+
# commits reachable from that ref.
|
41
46
|
# @return [Hash] The calculated stats for the given repository and branch
|
42
|
-
def self.simple_stats(type,
|
43
|
-
|
44
|
-
branch
|
47
|
+
def self.simple_stats(type, *options)
|
48
|
+
arity = vcs(type)::Repository.instance_method(:initialize).arity
|
49
|
+
branch = options.delete_at arity
|
50
|
+
branch = vcs(type)::DEFAULT_BRANCH if branch.nil?
|
51
|
+
repo = repository type, *options
|
45
52
|
|
46
53
|
{
|
47
|
-
:
|
48
|
-
:
|
49
|
-
|
50
|
-
}
|
54
|
+
:commit_count => repo.commits(branch).size,
|
55
|
+
:top_contributors => repo.top_contributors(branch, 5),
|
56
|
+
}.merge Commit.activity(repo.commits(branch))
|
51
57
|
end
|
52
58
|
|
53
59
|
end
|
data/lib/metior/github/commit.rb
CHANGED
@@ -29,20 +29,20 @@ module Metior
|
|
29
29
|
|
30
30
|
@added_files = []
|
31
31
|
@additions = 0
|
32
|
-
@authored_date = commit.authored_date
|
33
|
-
@committed_date = commit.committed_date
|
32
|
+
@authored_date = Time.parse commit.authored_date
|
33
|
+
@committed_date = Time.parse commit.committed_date
|
34
34
|
@deleted_files = []
|
35
35
|
@deletions = 0
|
36
36
|
@id = commit.id
|
37
37
|
@message = commit.message
|
38
38
|
@modified_files = []
|
39
39
|
|
40
|
-
authors = repo.authors
|
40
|
+
authors = repo.authors range
|
41
41
|
@author = authors[Actor.id_for commit.author]
|
42
42
|
@author = Actor.new repo, commit.author if author.nil?
|
43
43
|
@author.add_commit self
|
44
44
|
|
45
|
-
committers = repo.committers
|
45
|
+
committers = repo.committers range
|
46
46
|
@committer = committers[Actor.id_for commit.committer]
|
47
47
|
@committer = Actor.new repo, commit.committer if @committer.nil?
|
48
48
|
@committer.add_commit self
|
@@ -57,37 +57,39 @@ module Metior
|
|
57
57
|
# or as a single ref (`'master'`). A single ref name means all
|
58
58
|
# commits reachable from that ref.
|
59
59
|
# @return [Array<Commit>] All commits in the given commit range
|
60
|
-
# @see #
|
60
|
+
# @see #load_ref_commits
|
61
61
|
def load_commits(range)
|
62
|
-
commits =
|
63
|
-
|
64
|
-
|
62
|
+
commits = load_ref_commits(range.last)
|
63
|
+
if range.first == ''
|
64
|
+
base_commits = []
|
65
|
+
else
|
66
|
+
base_commits = load_ref_commits(range.first).map! do |commit|
|
67
|
+
commit.id
|
68
|
+
end
|
65
69
|
end
|
66
70
|
commits.reject { |commit| base_commits.include? commit.id }
|
67
71
|
end
|
68
72
|
|
69
|
-
# This method uses Octokit to load all commits from the given
|
73
|
+
# This method uses Octokit to load all commits from the given ref
|
70
74
|
#
|
71
75
|
# Because of GitHub API limitations, the commits have to be loaded in
|
72
76
|
# batches.
|
73
77
|
#
|
74
78
|
# @note GitHub API is currently limited to 60 calls a minute, so you
|
75
|
-
# won't be able to query
|
76
|
-
#
|
77
|
-
# @param [String]
|
78
|
-
# @
|
79
|
-
# commits should be assigned
|
80
|
-
# @return [Array<Commit>] All commits from the given branch
|
79
|
+
# won't be able to query refs with more than 2100 commits (35
|
80
|
+
# commits per call).
|
81
|
+
# @param [String] ref The ref to load commits from
|
82
|
+
# @return [Array<Commit>] All commits from the given ref
|
81
83
|
# @see Octokit::Commits#commits
|
82
|
-
def
|
84
|
+
def load_ref_commits(ref)
|
83
85
|
commits = []
|
84
86
|
page = 1
|
85
87
|
begin
|
86
|
-
|
87
|
-
commits += Octokit.commits(@path,
|
88
|
+
loop do
|
89
|
+
commits += Octokit.commits(@path, ref, :page => page)
|
88
90
|
page += 1
|
89
|
-
end
|
90
|
-
rescue
|
91
|
+
end
|
92
|
+
rescue Faraday::Error::ResourceNotFound
|
91
93
|
end
|
92
94
|
commits
|
93
95
|
end
|
data/lib/metior/vcs.rb
CHANGED
data/lib/metior/version.rb
CHANGED
data/metior.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.summary = 'A source code history analyzer API'
|
13
13
|
s.description = 'Metior is a source code history analyzer that provides various statistics about a source code repository and its change over time.'
|
14
14
|
|
15
|
+
s.add_dependency 'bundler', '~> 1.0.14'
|
15
16
|
Bundler.definition.dependencies.each do |dep|
|
16
17
|
if dep.groups.include?(:development) || dep.groups.include?(:test)
|
17
18
|
s.add_development_dependency(dep.name, dep.requirement.to_s)
|
data/test/fixtures.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'rash'
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
module Fixtures
|
10
|
+
|
11
|
+
@@commits = {}
|
12
|
+
|
13
|
+
def self.commits(range)
|
14
|
+
unless @@commits.key? range
|
15
|
+
file = File.open(File.expand_path("#{File.dirname(__FILE__)}/fixtures/mojombo-grit-master-1b2fe77.txt"), 'r')
|
16
|
+
file.set_encoding 'utf-8' if file.respond_to? :set_encoding
|
17
|
+
|
18
|
+
commits = []
|
19
|
+
|
20
|
+
commit = {}
|
21
|
+
file.lines.each do |line|
|
22
|
+
line.strip!
|
23
|
+
|
24
|
+
next if line.empty?
|
25
|
+
|
26
|
+
if line.match /^[AMD]\0/
|
27
|
+
commit[:files] = [] unless commit.key? :files
|
28
|
+
commit[:files] << line.split("\0")
|
29
|
+
elsif line.match /\d+\0\d+$/
|
30
|
+
commit[:impact] = line.split("\0")
|
31
|
+
else
|
32
|
+
line = line.split("\0")
|
33
|
+
ids = [line[0]]
|
34
|
+
ids += line[1][2..-2].split(', ') unless line[1].empty?
|
35
|
+
commit[:ids] = ids
|
36
|
+
commit[:info] = line[2..-1]
|
37
|
+
|
38
|
+
if commits.empty?
|
39
|
+
if !commit[:ids].include?(range.last)
|
40
|
+
commit = {}
|
41
|
+
next
|
42
|
+
end
|
43
|
+
elsif commit[:ids].include? range.first
|
44
|
+
break
|
45
|
+
end
|
46
|
+
|
47
|
+
if commit != {}
|
48
|
+
commits << commit
|
49
|
+
commit = {}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
@@commits[range] = commits
|
55
|
+
end
|
56
|
+
|
57
|
+
@@commits[range]
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.commits_as_grit_commits(range)
|
61
|
+
commits = commits(range)
|
62
|
+
|
63
|
+
commits.map do |commit|
|
64
|
+
grit_commit = Grit::Commit.new(
|
65
|
+
nil,
|
66
|
+
commit[:ids].first,
|
67
|
+
[],
|
68
|
+
nil,
|
69
|
+
Grit::Actor.new(commit[:info][4], commit[:info][5]),
|
70
|
+
Time.at(commit[:info][6].to_i),
|
71
|
+
Grit::Actor.new(commit[:info][1], commit[:info][2]),
|
72
|
+
Time.at(commit[:info][3].to_i),
|
73
|
+
commit[:info].first.lines.to_a
|
74
|
+
)
|
75
|
+
|
76
|
+
grit_commit.stubs(:diffs).returns []
|
77
|
+
|
78
|
+
stats = Hashie::Rash.new
|
79
|
+
if commit.key? :impact
|
80
|
+
stats.additions = commit[:impact].first.to_i
|
81
|
+
stats.deletions = commit[:impact].last.to_i
|
82
|
+
else
|
83
|
+
stats.additions = 0
|
84
|
+
stats.deletions = 0
|
85
|
+
end
|
86
|
+
grit_commit.stubs(:stats).returns stats
|
87
|
+
|
88
|
+
grit_commit
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.commits_as_rashies(range)
|
93
|
+
commits = commits(range)
|
94
|
+
|
95
|
+
commits.map do |commit|
|
96
|
+
Hashie::Rash.new({
|
97
|
+
:author => {
|
98
|
+
:email => commit[:info][4],
|
99
|
+
:login => commit[:info][5],
|
100
|
+
:name => commit[:info][5]
|
101
|
+
},
|
102
|
+
:authored_date => Time.at(commit[:info][6].to_i).to_s,
|
103
|
+
:committed_date => Time.at(commit[:info][3].to_i).to_s,
|
104
|
+
:committer => {
|
105
|
+
:email => commit[:info][1],
|
106
|
+
:login => commit[:info][2],
|
107
|
+
:name => commit[:info][2]
|
108
|
+
},
|
109
|
+
:id => commit[:ids].first,
|
110
|
+
:message => commit[:info].first,
|
111
|
+
})
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
data/test/helper.rb
CHANGED
data/test/test_git.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# Copyright (c) 2011, Sebastian Staudt
|
5
5
|
|
6
|
+
require 'fixtures'
|
6
7
|
require 'helper'
|
7
8
|
|
8
9
|
class TestGit < Test::Unit::TestCase
|
@@ -19,4 +20,97 @@ class TestGit < Test::Unit::TestCase
|
|
19
20
|
|
20
21
|
end
|
21
22
|
|
23
|
+
context 'A Git repository' do
|
24
|
+
|
25
|
+
setup do
|
26
|
+
@repo = Metior::Git::Repository.new File.dirname(File.dirname(__FILE__))
|
27
|
+
@@grit_commits ||= Fixtures.commits_as_grit_commits(''..'master')
|
28
|
+
@commits_stub = Grit::Repo.any_instance.stubs :commits
|
29
|
+
@commits_stub.returns @@grit_commits
|
30
|
+
end
|
31
|
+
|
32
|
+
should 'be able to load all commits from the repository\'s default branch' do
|
33
|
+
commits = @repo.commits
|
34
|
+
assert_equal 460, commits.size
|
35
|
+
assert commits.all? { |commit| commit.is_a? Metior::Git::Commit }
|
36
|
+
|
37
|
+
head = commits.first
|
38
|
+
assert_equal '1b2fe77', head.id
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'be able to load a range of commits from the repository' do
|
42
|
+
@commits_stub = Grit::Repo.any_instance.stubs :commits
|
43
|
+
api_response = Fixtures.commits_as_grit_commits('ef2870b'..'4c592b4')
|
44
|
+
@commits_stub.returns api_response
|
45
|
+
|
46
|
+
commits = @repo.commits 'ef2870b'..'4c592b4'
|
47
|
+
assert_equal 6, commits.size
|
48
|
+
assert commits.all? { |commit| commit.is_a? Metior::Git::Commit }
|
49
|
+
assert_equal '4c592b4', commits.first.id
|
50
|
+
assert_equal 'f0cc7f7', commits.last.id
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'know the authors of the repository' do
|
54
|
+
authors = @repo.authors
|
55
|
+
assert_equal 37, authors.size
|
56
|
+
assert authors.values.all? { |author| author.is_a? Metior::Git::Actor }
|
57
|
+
|
58
|
+
assert_equal %w{
|
59
|
+
adam@therealadam.com aman@tmm1.net antonin@hildebrand.cz
|
60
|
+
bobbywilson0@gmail.com bryce@worldmedia.net cehoffman@gmail.com
|
61
|
+
chapados@sciencegeeks.org cho45@lowreal.net chris@ozmm.org
|
62
|
+
davetron5000@gmail.com david.kowis@rackspace.com dustin@spy.net
|
63
|
+
engel@engel.uk.to evil@che.lu gram.gibson@uky.edu
|
64
|
+
hiroshi3110@gmail.com igor@wiedler.ch johan@johansorensen.com
|
65
|
+
jos@catnook.com jpriddle@nevercraft.net kamal.fariz@gmail.com
|
66
|
+
koraktor@gmail.com mtraverso@acm.org ohnobinki@ohnopublishing.net
|
67
|
+
paul+git@mjr.org pjhyett@gmail.com rsanheim@gmail.com
|
68
|
+
rtomayko@gmail.com schacon@gmail.com scott@railsnewbie.com
|
69
|
+
technoweenie@gmail.com tim@dysinger.net tim@spork.in
|
70
|
+
tom@mojombo.com tom@taco.(none) voker57@gmail.com wayne@larsen.st
|
71
|
+
}, authors.keys.sort
|
72
|
+
end
|
73
|
+
|
74
|
+
should 'know the committers of the repository' do
|
75
|
+
committers = @repo.committers
|
76
|
+
assert_equal 29, committers.size
|
77
|
+
assert committers.values.all? { |committer| committer.is_a? Metior::Git::Actor }
|
78
|
+
|
79
|
+
assert_equal %w{
|
80
|
+
adam@therealadam.com aman@tmm1.net antonin@hildebrand.cz
|
81
|
+
bobbywilson0@gmail.com bryce@worldmedia.net chris@ozmm.org
|
82
|
+
davetron5000@gmail.com david.kowis@rackspace.com dustin@spy.net
|
83
|
+
engel@engel.uk.to evil@che.lu hiroshi3110@gmail.com
|
84
|
+
johan@johansorensen.com jos@catnook.com kamal.fariz@gmail.com
|
85
|
+
koraktor@gmail.com mtraverso@acm.org ohnobinki@ohnopublishing.net
|
86
|
+
paul+git@mjr.org pjhyett@gmail.com rsanheim@gmail.com
|
87
|
+
rtomayko@gmail.com schacon@gmail.com technoweenie@gmail.com
|
88
|
+
tim@dysinger.net tim@spork.in tom@mojombo.com tom@taco.(none)
|
89
|
+
voker57@gmail.com
|
90
|
+
}, committers.keys.sort
|
91
|
+
end
|
92
|
+
|
93
|
+
should 'know the top authors of the repository' do
|
94
|
+
authors = @repo.top_authors
|
95
|
+
assert_equal 3, authors.size
|
96
|
+
assert authors.all? { |author| author.is_a? Metior::Git::Actor }
|
97
|
+
|
98
|
+
assert_equal [
|
99
|
+
"tom@mojombo.com", "schacon@gmail.com", "technoweenie@gmail.com"
|
100
|
+
], authors.collect { |author| author.id }
|
101
|
+
end
|
102
|
+
|
103
|
+
should 'provide easy access to simple repository statistics' do
|
104
|
+
stats = Metior.simple_stats :git, File.dirname(File.dirname(__FILE__))
|
105
|
+
|
106
|
+
assert_equal 157, stats[:active_days].size
|
107
|
+
assert_equal 460, stats[:commit_count]
|
108
|
+
assert_in_delta 2.92993630573248, stats[:commits_per_active_day], 0.0001
|
109
|
+
assert_equal Time.at(1191997100), stats[:first_commit_date]
|
110
|
+
assert_equal Time.at(1306794294), stats[:last_commit_date]
|
111
|
+
assert_equal 5, stats[:top_contributors].size
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
22
116
|
end
|
data/test/test_github.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# Copyright (c) 2011, Sebastian Staudt
|
5
5
|
|
6
|
+
require 'fixtures'
|
6
7
|
require 'helper'
|
7
8
|
|
8
9
|
class TestGitHub < Test::Unit::TestCase
|
@@ -17,27 +18,123 @@ class TestGitHub < Test::Unit::TestCase
|
|
17
18
|
assert_not Metior::GitHub.supports? :line_stats
|
18
19
|
end
|
19
20
|
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'A GitHub repository' do
|
24
|
+
|
25
|
+
setup do
|
26
|
+
@repo = Metior::GitHub::Repository.new 'mojombo', 'grit'
|
27
|
+
|
28
|
+
api_response = Fixtures.commits_as_rashies(''..'master')
|
29
|
+
@commits_stub = Octokit.stubs :commits
|
30
|
+
14.times { @commits_stub.returns api_response.shift(35) }
|
31
|
+
@commits_stub.then.raises Faraday::Error::ResourceNotFound.new(nil)
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'be able to load all commits from the repository\'s default branch' do
|
35
|
+
commits = @repo.commits
|
36
|
+
assert_equal 460, commits.size
|
37
|
+
assert commits.all? { |commit| commit.is_a? Metior::GitHub::Commit }
|
38
|
+
|
39
|
+
head = commits.first
|
40
|
+
assert_equal '1b2fe77', head.id
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'be able to load a range of commits from the repository' do
|
44
|
+
@commits_stub = Octokit.stubs :commits
|
45
|
+
api_response = Fixtures.commits_as_rashies(''..'4c592b4')
|
46
|
+
14.times { @commits_stub.returns api_response.shift(35) }
|
47
|
+
@commits_stub.raises Faraday::Error::ResourceNotFound.new(nil)
|
48
|
+
api_response = Fixtures.commits_as_rashies(''..'ef2870b')
|
49
|
+
13.times { @commits_stub.returns api_response.shift(35) }
|
50
|
+
@commits_stub.then.raises Faraday::Error::ResourceNotFound.new(nil)
|
51
|
+
|
52
|
+
commits = @repo.commits 'ef2870b'..'4c592b4'
|
53
|
+
assert_equal 6, commits.size
|
54
|
+
assert commits.all? { |commit| commit.is_a? Metior::GitHub::Commit }
|
55
|
+
assert_equal '4c592b4', commits.first.id
|
56
|
+
assert_equal 'f0cc7f7', commits.last.id
|
57
|
+
end
|
58
|
+
|
59
|
+
should 'know the authors of the repository' do
|
60
|
+
authors = @repo.authors
|
61
|
+
assert_equal 37, authors.size
|
62
|
+
assert authors.values.all? { |author| author.is_a? Metior::GitHub::Actor }
|
63
|
+
|
64
|
+
assert_equal %w{
|
65
|
+
adam@therealadam.com aman@tmm1.net antonin@hildebrand.cz
|
66
|
+
bobbywilson0@gmail.com bryce@worldmedia.net cehoffman@gmail.com
|
67
|
+
chapados@sciencegeeks.org cho45@lowreal.net chris@ozmm.org
|
68
|
+
davetron5000@gmail.com david.kowis@rackspace.com dustin@spy.net
|
69
|
+
engel@engel.uk.to evil@che.lu gram.gibson@uky.edu
|
70
|
+
hiroshi3110@gmail.com igor@wiedler.ch johan@johansorensen.com
|
71
|
+
jos@catnook.com jpriddle@nevercraft.net kamal.fariz@gmail.com
|
72
|
+
koraktor@gmail.com mtraverso@acm.org ohnobinki@ohnopublishing.net
|
73
|
+
paul+git@mjr.org pjhyett@gmail.com rsanheim@gmail.com
|
74
|
+
rtomayko@gmail.com schacon@gmail.com scott@railsnewbie.com
|
75
|
+
technoweenie@gmail.com tim@dysinger.net tim@spork.in
|
76
|
+
tom@mojombo.com tom@taco.(none) voker57@gmail.com wayne@larsen.st
|
77
|
+
}, authors.keys.sort
|
78
|
+
end
|
79
|
+
|
80
|
+
should 'know the committers of the repository' do
|
81
|
+
committers = @repo.committers
|
82
|
+
assert_equal 29, committers.size
|
83
|
+
assert committers.values.all? { |committer| committer.is_a? Metior::GitHub::Actor }
|
84
|
+
|
85
|
+
assert_equal %w{
|
86
|
+
adam@therealadam.com aman@tmm1.net antonin@hildebrand.cz
|
87
|
+
bobbywilson0@gmail.com bryce@worldmedia.net chris@ozmm.org
|
88
|
+
davetron5000@gmail.com david.kowis@rackspace.com dustin@spy.net
|
89
|
+
engel@engel.uk.to evil@che.lu hiroshi3110@gmail.com
|
90
|
+
johan@johansorensen.com jos@catnook.com kamal.fariz@gmail.com
|
91
|
+
koraktor@gmail.com mtraverso@acm.org ohnobinki@ohnopublishing.net
|
92
|
+
paul+git@mjr.org pjhyett@gmail.com rsanheim@gmail.com
|
93
|
+
rtomayko@gmail.com schacon@gmail.com technoweenie@gmail.com
|
94
|
+
tim@dysinger.net tim@spork.in tom@mojombo.com tom@taco.(none)
|
95
|
+
voker57@gmail.com
|
96
|
+
}, committers.keys.sort
|
97
|
+
end
|
98
|
+
|
99
|
+
should 'know the top authors of the repository' do
|
100
|
+
authors = @repo.top_authors
|
101
|
+
assert_equal 3, authors.size
|
102
|
+
assert authors.all? { |author| author.is_a? Metior::GitHub::Actor }
|
103
|
+
|
104
|
+
assert_equal [
|
105
|
+
"tom@mojombo.com", "schacon@gmail.com", "technoweenie@gmail.com"
|
106
|
+
], authors.collect { |author| author.id }
|
107
|
+
end
|
108
|
+
|
20
109
|
should 'not be able to get file stats of a repository' do
|
21
|
-
repo = Metior::GitHub::Repository.new 'koraktor', 'rubikon'
|
22
110
|
assert_raises UnsupportedError do
|
23
|
-
repo.file_stats
|
111
|
+
@repo.file_stats
|
24
112
|
end
|
25
113
|
end
|
26
114
|
|
27
115
|
should 'not be able to get the most significant authors of a repository' do
|
28
|
-
repo = Metior::GitHub::Repository.new 'koraktor', 'rubikon'
|
29
116
|
assert_raises UnsupportedError do
|
30
|
-
repo.significant_authors
|
117
|
+
@repo.significant_authors
|
31
118
|
end
|
32
119
|
end
|
33
120
|
|
34
121
|
should 'not be able to get the most significant commits of a repository' do
|
35
|
-
repo = Metior::GitHub::Repository.new 'koraktor', 'rubikon'
|
36
122
|
assert_raises UnsupportedError do
|
37
|
-
repo.significant_commits
|
123
|
+
@repo.significant_commits
|
38
124
|
end
|
39
125
|
end
|
40
126
|
|
127
|
+
should 'provide easy access to simple repository statistics' do
|
128
|
+
stats = Metior.simple_stats :github, 'mojombo', 'grit'
|
129
|
+
|
130
|
+
assert_equal 157, stats[:active_days].size
|
131
|
+
assert_equal 460, stats[:commit_count]
|
132
|
+
assert_in_delta 2.92993630573248, stats[:commits_per_active_day], 0.0001
|
133
|
+
assert_equal Time.at(1191997100), stats[:first_commit_date]
|
134
|
+
assert_equal Time.at(1306794294), stats[:last_commit_date]
|
135
|
+
assert_equal 5, stats[:top_contributors].size
|
136
|
+
end
|
137
|
+
|
41
138
|
end
|
42
139
|
|
43
140
|
end
|
data/test/test_repository.rb
CHANGED
@@ -43,108 +43,4 @@ class TestRepository < Test::Unit::TestCase
|
|
43
43
|
|
44
44
|
end
|
45
45
|
|
46
|
-
context 'A repository implementation' do
|
47
|
-
|
48
|
-
setup do
|
49
|
-
require 'mock_vcs/repository'
|
50
|
-
|
51
|
-
repo_file = "#{File.dirname(__FILE__)}/fixtures/mojombo-grit-master-1b2fe77.txt"
|
52
|
-
@repo = MockVCS::Repository.new repo_file
|
53
|
-
end
|
54
|
-
|
55
|
-
should 'be able to load all commits from the repository' do
|
56
|
-
commits = @repo.commits
|
57
|
-
assert_equal 415, commits.size
|
58
|
-
assert commits.all? { |commit| commit.is_a? Metior::Commit }
|
59
|
-
|
60
|
-
head = commits.first
|
61
|
-
assert_equal '4c592b4', head.id
|
62
|
-
end
|
63
|
-
|
64
|
-
should 'be able to load a range of commits from the repository' do
|
65
|
-
commits = @repo.commits 'ef2870b'..'4c592b4'
|
66
|
-
assert_equal 5, commits.size
|
67
|
-
assert commits.all? { |commit| commit.is_a? Metior::Commit }
|
68
|
-
assert_equal '4c592b4', commits.first.id
|
69
|
-
assert_equal 'f0cc7f7', commits.last.id
|
70
|
-
end
|
71
|
-
|
72
|
-
should 'know the authors of the repository' do
|
73
|
-
authors = @repo.authors
|
74
|
-
assert_equal 37, authors.size
|
75
|
-
assert authors.values.all? { |author| author.is_a? Metior::Actor }
|
76
|
-
|
77
|
-
assert_equal %w{
|
78
|
-
adam@therealadam.com aman@tmm1.net antonin@hildebrand.cz
|
79
|
-
bobbywilson0@gmail.com bryce@worldmedia.net cehoffman@gmail.com
|
80
|
-
chapados@sciencegeeks.org cho45@lowreal.net chris@ozmm.org
|
81
|
-
davetron5000@gmail.com david.kowis@rackspace.com dustin@spy.net
|
82
|
-
engel@engel.uk.to evil@che.lu gram.gibson@uky.edu
|
83
|
-
hiroshi3110@gmail.com igor@wiedler.ch johan@johansorensen.com
|
84
|
-
jos@catnook.com jpriddle@nevercraft.net kamal.fariz@gmail.com
|
85
|
-
koraktor@gmail.com mtraverso@acm.org ohnobinki@ohnopublishing.net
|
86
|
-
paul+git@mjr.org pjhyett@gmail.com rsanheim@gmail.com
|
87
|
-
rtomayko@gmail.com schacon@gmail.com scott@railsnewbie.com
|
88
|
-
technoweenie@gmail.com tim@dysinger.net tim@spork.in
|
89
|
-
tom@mojombo.com tom@taco.(none) voker57@gmail.com wayne@larsen.st
|
90
|
-
}, authors.keys.sort
|
91
|
-
end
|
92
|
-
|
93
|
-
should 'know the committers of the repository' do
|
94
|
-
committers = @repo.committers
|
95
|
-
assert_equal 29, committers.size
|
96
|
-
assert committers.values.all? { |committer| committer.is_a? Metior::Actor }
|
97
|
-
|
98
|
-
assert_equal %w{
|
99
|
-
adam@therealadam.com aman@tmm1.net antonin@hildebrand.cz
|
100
|
-
bobbywilson0@gmail.com bryce@worldmedia.net chris@ozmm.org
|
101
|
-
davetron5000@gmail.com david.kowis@rackspace.com dustin@spy.net
|
102
|
-
engel@engel.uk.to evil@che.lu hiroshi3110@gmail.com
|
103
|
-
johan@johansorensen.com jos@catnook.com kamal.fariz@gmail.com
|
104
|
-
koraktor@gmail.com mtraverso@acm.org ohnobinki@ohnopublishing.net
|
105
|
-
paul+git@mjr.org pjhyett@gmail.com rsanheim@gmail.com
|
106
|
-
rtomayko@gmail.com schacon@gmail.com technoweenie@gmail.com
|
107
|
-
tim@dysinger.net tim@spork.in tom@mojombo.com tom@taco.(none)
|
108
|
-
voker57@gmail.com
|
109
|
-
}, committers.keys.sort
|
110
|
-
end
|
111
|
-
|
112
|
-
should 'know the most significant authors of the repository' do
|
113
|
-
authors = @repo.significant_authors
|
114
|
-
assert_equal 3, authors.size
|
115
|
-
assert authors.all? { |author| author.is_a? Metior::Actor }
|
116
|
-
|
117
|
-
assert_equal [
|
118
|
-
"tom@mojombo.com", "schacon@gmail.com", "rtomayko@gmail.com"
|
119
|
-
], authors.collect { |author| author.id }
|
120
|
-
end
|
121
|
-
|
122
|
-
should 'know the most significant commits of the repository' do
|
123
|
-
commits = @repo.significant_commits('master', 8)
|
124
|
-
assert_equal 8, commits.size
|
125
|
-
assert commits.all? { |commit| commit.is_a? Metior::Commit }
|
126
|
-
|
127
|
-
assert_equal %w{
|
128
|
-
c0f0b4f 47ab25c f3a24ae 18ec70e 242253b c87612b 6bb41e4 4d9c7be
|
129
|
-
}, commits.collect { |commit| commit.id }
|
130
|
-
|
131
|
-
modifications = commits.first.modifications
|
132
|
-
commits[1..-1].each do |commit|
|
133
|
-
assert modifications >= commit.modifications
|
134
|
-
modifications = commit.modifications
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
should 'know the top authors of the repository' do
|
139
|
-
authors = @repo.top_authors
|
140
|
-
assert_equal 3, authors.size
|
141
|
-
assert authors.all? { |author| author.is_a? Metior::Actor }
|
142
|
-
|
143
|
-
assert_equal [
|
144
|
-
"tom@mojombo.com", "schacon@gmail.com", "technoweenie@gmail.com"
|
145
|
-
], authors.collect { |author| author.id }
|
146
|
-
end
|
147
|
-
|
148
|
-
end
|
149
|
-
|
150
46
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metior
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sebastian Staudt
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-13 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
type: :runtime
|
@@ -165,11 +165,9 @@ files:
|
|
165
165
|
- lib/metior/vcs.rb
|
166
166
|
- lib/metior/version.rb
|
167
167
|
- metior.gemspec
|
168
|
+
- test/fixtures.rb
|
168
169
|
- test/fixtures/mojombo-grit-master-1b2fe77.txt
|
169
170
|
- test/helper.rb
|
170
|
-
- test/mock_vcs/actor.rb
|
171
|
-
- test/mock_vcs/commit.rb
|
172
|
-
- test/mock_vcs/repository.rb
|
173
171
|
- test/test_class_loading.rb
|
174
172
|
- test/test_git.rb
|
175
173
|
- test/test_github.rb
|
@@ -210,11 +208,9 @@ signing_key:
|
|
210
208
|
specification_version: 3
|
211
209
|
summary: A source code history analyzer API
|
212
210
|
test_files:
|
211
|
+
- test/fixtures.rb
|
213
212
|
- test/fixtures/mojombo-grit-master-1b2fe77.txt
|
214
213
|
- test/helper.rb
|
215
|
-
- test/mock_vcs/actor.rb
|
216
|
-
- test/mock_vcs/commit.rb
|
217
|
-
- test/mock_vcs/repository.rb
|
218
214
|
- test/test_class_loading.rb
|
219
215
|
- test/test_git.rb
|
220
216
|
- test/test_github.rb
|
data/test/mock_vcs/actor.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# This code is free software; you can redistribute it and/or modify it under
|
2
|
-
# the terms of the new BSD License.
|
3
|
-
#
|
4
|
-
# Copyright (c) 2011, Sebastian Staudt
|
5
|
-
|
6
|
-
require 'metior/actor'
|
7
|
-
|
8
|
-
module Metior
|
9
|
-
|
10
|
-
module MockVCS
|
11
|
-
|
12
|
-
class Actor < Metior::Actor
|
13
|
-
|
14
|
-
def self.id_for(actor)
|
15
|
-
actor.last
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize(repo, actor)
|
19
|
-
super repo
|
20
|
-
|
21
|
-
@id = actor.last
|
22
|
-
@name = actor.first
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
data/test/mock_vcs/commit.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# This code is free software; you can redistribute it and/or modify it under
|
2
|
-
# the terms of the new BSD License.
|
3
|
-
#
|
4
|
-
# Copyright (c) 2011, Sebastian Staudt
|
5
|
-
|
6
|
-
require 'mock_vcs/actor'
|
7
|
-
require 'metior/commit'
|
8
|
-
|
9
|
-
module Metior
|
10
|
-
|
11
|
-
module MockVCS
|
12
|
-
|
13
|
-
class Commit < Metior::Commit
|
14
|
-
|
15
|
-
def initialize(repo, range, commit)
|
16
|
-
super repo, range
|
17
|
-
|
18
|
-
@additions = commit[:impact].first.to_i
|
19
|
-
@authored_date = Time.at commit[:info][6].to_i
|
20
|
-
@committed_date = Time.at commit[:info][3].to_i
|
21
|
-
@deletions = commit[:impact].last.to_i
|
22
|
-
@id = commit[:ids].first
|
23
|
-
@message = commit[:info].first
|
24
|
-
|
25
|
-
authors = repo.authors range
|
26
|
-
@author = authors[Actor.id_for commit[:info][4..5]]
|
27
|
-
@author = Actor.new repo, commit[:info][4..5] if author.nil?
|
28
|
-
@author.add_commit self
|
29
|
-
|
30
|
-
committers = repo.committers range
|
31
|
-
@committer = committers[Actor.id_for commit[:info][1..2]]
|
32
|
-
@committer = Actor.new repo, commit[:info][1..2] if @committer.nil?
|
33
|
-
@committer.add_commit self
|
34
|
-
|
35
|
-
@added_files = []
|
36
|
-
@modified_files = []
|
37
|
-
@deleted_files = []
|
38
|
-
commit[:files].each do |file|
|
39
|
-
if file.first == 'A'
|
40
|
-
@added_files << file.last
|
41
|
-
elsif file.first == 'A'
|
42
|
-
@deleted_files << file.last
|
43
|
-
else
|
44
|
-
@modified_files << file.last
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
data/test/mock_vcs/repository.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
# This code is free software; you can redistribute it and/or modify it under
|
2
|
-
# the terms of the new BSD License.
|
3
|
-
#
|
4
|
-
# Copyright (c) 2011, Sebastian Staudt
|
5
|
-
|
6
|
-
require 'metior/repository'
|
7
|
-
require 'mock_vcs/commit'
|
8
|
-
|
9
|
-
module Metior
|
10
|
-
|
11
|
-
module MockVCS
|
12
|
-
|
13
|
-
NAME = :mock
|
14
|
-
|
15
|
-
include VCS
|
16
|
-
|
17
|
-
class Repository < Metior::Repository
|
18
|
-
|
19
|
-
DEFAULT_BRANCH = 'master'
|
20
|
-
|
21
|
-
include Metior::MockVCS
|
22
|
-
|
23
|
-
def initialize(path)
|
24
|
-
super path
|
25
|
-
|
26
|
-
@file = File.open(File.expand_path(path), 'r')
|
27
|
-
@file.set_encoding 'utf-8' if @file.respond_to? :set_encoding
|
28
|
-
end
|
29
|
-
|
30
|
-
def load_commits(range)
|
31
|
-
commits = []
|
32
|
-
|
33
|
-
commit = {}
|
34
|
-
@file.lines.each do |line|
|
35
|
-
line.strip!
|
36
|
-
|
37
|
-
next if line.empty?
|
38
|
-
|
39
|
-
if line.match /^[AMD]\0/
|
40
|
-
commit[:files] = [] unless commit.key? :files
|
41
|
-
commit[:files] << line.split("\0")
|
42
|
-
elsif line.match /\d+\0\d+$/
|
43
|
-
commit[:impact] = line.split("\0")
|
44
|
-
|
45
|
-
if commits.empty?
|
46
|
-
if range.first != '' && !commit[:ids].include?(range.last)
|
47
|
-
commit = {}
|
48
|
-
next
|
49
|
-
end
|
50
|
-
elsif commit[:ids].include? range.first
|
51
|
-
break
|
52
|
-
end
|
53
|
-
|
54
|
-
commits << commit
|
55
|
-
commit = {}
|
56
|
-
else
|
57
|
-
line = line.split("\0")
|
58
|
-
ids = [line[0]]
|
59
|
-
ids += line[1][2..-2].split(', ') unless line[1].empty?
|
60
|
-
commit[:ids] = ids
|
61
|
-
commit[:info] = line[2..-1]
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
commits
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|