metior 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.travis.yml +7 -0
- data/.yardopts +4 -0
- data/Changelog.md +22 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +25 -0
- data/README.md +117 -0
- data/Rakefile +48 -0
- data/lib/core_ext/object.rb +25 -0
- data/lib/metior.rb +50 -0
- data/lib/metior/actor.rb +85 -0
- data/lib/metior/commit.rb +118 -0
- data/lib/metior/errors.rb +19 -0
- data/lib/metior/git.rb +25 -0
- data/lib/metior/git/actor.rb +43 -0
- data/lib/metior/git/commit.rb +68 -0
- data/lib/metior/git/repository.rb +72 -0
- data/lib/metior/github.rb +27 -0
- data/lib/metior/github/actor.rb +43 -0
- data/lib/metior/github/commit.rb +55 -0
- data/lib/metior/github/repository.rb +99 -0
- data/lib/metior/repository.rb +273 -0
- data/lib/metior/vcs.rb +150 -0
- data/lib/metior/version.rb +11 -0
- data/metior.gemspec +26 -0
- data/test/fixtures/mojombo-grit-master-1b2fe77.txt +0 -0
- data/test/helper.rb +26 -0
- data/test/mock_vcs/actor.rb +28 -0
- data/test/mock_vcs/commit.rb +53 -0
- data/test/mock_vcs/repository.rb +72 -0
- data/test/test_class_loading.rb +61 -0
- data/test/test_git.rb +22 -0
- data/test/test_github.rb +43 -0
- data/test/test_metior.rb +34 -0
- data/test/test_repository.rb +150 -0
- data/test/test_vcs.rb +40 -0
- metadata +223 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Changelog.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## Version 0.1.1
|
4
|
+
|
5
|
+
**June 8<sup>th</sup>, 2011**
|
6
|
+
|
7
|
+
* Fixed gem dependencies
|
8
|
+
|
9
|
+
See the
|
10
|
+
[Git history](https://github.com/koraktor/metior/compare/0.1.0...0.1.1) for
|
11
|
+
version 0.1.1
|
12
|
+
|
13
|
+
## Version 0.1.0
|
14
|
+
|
15
|
+
**June 8<sup>th</sup>, 2011**
|
16
|
+
|
17
|
+
* Support for Git and GitHub repositories
|
18
|
+
* Basic loading of commits, authors and committers
|
19
|
+
* Simple statistics
|
20
|
+
|
21
|
+
See the [Git history](https://github.com/koraktor/metior/commits/0.1.0) for
|
22
|
+
version 0.1.0
|
data/Gemfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'bundler', '~> 1.0.14'
|
4
|
+
|
5
|
+
group :git do
|
6
|
+
gem 'grit', '~> 2.4.1'
|
7
|
+
end
|
8
|
+
|
9
|
+
group :github do
|
10
|
+
gem 'octokit', '~> 0.6.3'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :development do
|
14
|
+
gem 'rake', '~> 0.9.1'
|
15
|
+
gem 'yard', '~> 0.7.1'
|
16
|
+
end
|
17
|
+
|
18
|
+
group :test do
|
19
|
+
gem 'mocha', '~> 0.9.12'
|
20
|
+
gem 'shoulda', '~> 2.11.3'
|
21
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.2.6)
|
5
|
+
diff-lcs (1.1.2)
|
6
|
+
faraday (0.6.1)
|
7
|
+
addressable (~> 2.2.4)
|
8
|
+
multipart-post (~> 1.1.0)
|
9
|
+
rack (< 2, >= 1.1.0)
|
10
|
+
faraday_middleware (0.6.3)
|
11
|
+
faraday (~> 0.6.0)
|
12
|
+
grit (2.4.1)
|
13
|
+
diff-lcs (~> 1.1)
|
14
|
+
mime-types (~> 1.15)
|
15
|
+
hashie (1.0.0)
|
16
|
+
mime-types (1.16)
|
17
|
+
mocha (0.9.12)
|
18
|
+
multi_json (1.0.2)
|
19
|
+
multipart-post (1.1.1)
|
20
|
+
octokit (0.6.3)
|
21
|
+
addressable (~> 2.2.4)
|
22
|
+
faraday (~> 0.6.0)
|
23
|
+
faraday_middleware (~> 0.6.0)
|
24
|
+
hashie (~> 1.0.0)
|
25
|
+
multi_json (~> 1.0.0)
|
26
|
+
rash (~> 0.3.0)
|
27
|
+
rack (1.2.2)
|
28
|
+
rake (0.9.1)
|
29
|
+
rash (0.3.0)
|
30
|
+
hashie (~> 1.0.0)
|
31
|
+
shoulda (2.11.3)
|
32
|
+
yard (0.7.1)
|
33
|
+
|
34
|
+
PLATFORMS
|
35
|
+
ruby
|
36
|
+
|
37
|
+
DEPENDENCIES
|
38
|
+
bundler (~> 1.0.14)
|
39
|
+
grit (~> 2.4.1)
|
40
|
+
mocha (~> 0.9.12)
|
41
|
+
octokit (~> 0.6.3)
|
42
|
+
rake (~> 0.9.1)
|
43
|
+
shoulda (~> 2.11.3)
|
44
|
+
yard (~> 0.7.1)
|
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Copyright (c) 2011, Sebastian Staudt
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice,
|
8
|
+
this list of conditions and the following disclaimer.
|
9
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
11
|
+
and/or other materials provided with the distribution.
|
12
|
+
* Neither the name of the author nor the names of its contributors
|
13
|
+
may be used to endorse or promote products derived from this software
|
14
|
+
without specific prior written permission.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
17
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
20
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
21
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
22
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
23
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
24
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
25
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
Metior
|
2
|
+
======
|
3
|
+
|
4
|
+
Metior is a source code history analyzer API that provides various statistics
|
5
|
+
about a source code repository and its change over time.
|
6
|
+
|
7
|
+
Currently Metior provides basic support for Git repositories.
|
8
|
+
|
9
|
+
If you're interested in Metior, feel free to join the discussion on Convore in
|
10
|
+
[Metior's group](https://convore.com/metior).
|
11
|
+
|
12
|
+
## Examples
|
13
|
+
|
14
|
+
### One-liner for some basic statistics
|
15
|
+
|
16
|
+
Metior.simple_stats :git, '~/open-source/metior'
|
17
|
+
|
18
|
+
### More fine-grained access to repository statistics
|
19
|
+
|
20
|
+
repo = Metior::Git::Repository.new '~/open-source/metior'
|
21
|
+
repo.commits 'development' # Get all commits in development
|
22
|
+
repo.file_stats # Basic statistics about the files
|
23
|
+
# contained in a repository
|
24
|
+
repo.line_history # Quick access to lines added and
|
25
|
+
# removed in each commit
|
26
|
+
repo.significant_authors # Get up to 3 of the most important
|
27
|
+
# authors
|
28
|
+
repo.significant_commits, 20 # Get up to 20 of the commits changing
|
29
|
+
# the most lines
|
30
|
+
repo.top_authors 'master', 5 # Get the top 5 authors in master
|
31
|
+
|
32
|
+
### Get statistics about a set of commits
|
33
|
+
|
34
|
+
Metior::Commit.activity repo.commits
|
35
|
+
Metior::Commit.activity repo.authors[author_id].commits
|
36
|
+
|
37
|
+
## Advanced usage
|
38
|
+
|
39
|
+
### Specifying commit ranges
|
40
|
+
|
41
|
+
Sometimes it's more useful to not analyze the whole history of a repository's
|
42
|
+
branch. For example when analyzing the changes from one branch to another, or
|
43
|
+
from the last released version to the latest code. In that case you will have
|
44
|
+
to specify a commit range. Specifying a commit range works just like in Git:
|
45
|
+
|
46
|
+
'master..development'
|
47
|
+
'master'..'development'
|
48
|
+
'master..HEAD'
|
49
|
+
'master'..'HEAD'
|
50
|
+
'deadbeef..HEAD'
|
51
|
+
|
52
|
+
Given that your currently checked out branch is `development` and `master`
|
53
|
+
points to commit `deadbeef`, the above statements are equal. Please also note
|
54
|
+
the different syntaxes: The first, third and fifth example are standards string
|
55
|
+
which will be parsed by Metior. The second and fourth example are Ruby `Range`
|
56
|
+
objects which can be used by Metior right away.
|
57
|
+
|
58
|
+
## Requirements
|
59
|
+
|
60
|
+
* Grit — a Ruby API for Git
|
61
|
+
* [Git](http://git-scm.com) >= 1.6
|
62
|
+
* Octokit — a Ruby wrapper for the GitHub API
|
63
|
+
|
64
|
+
## Documentation
|
65
|
+
|
66
|
+
The documentation of the Ruby API can be seen at [RubyDoc.info][1]. The API
|
67
|
+
documentation of the current development version is also available [there][5].
|
68
|
+
|
69
|
+
## Future plans
|
70
|
+
|
71
|
+
* More statistics and analyses
|
72
|
+
* Generation of reports in HTML or other formats
|
73
|
+
* Support for creating graphs
|
74
|
+
* Console and web application to accompany this API
|
75
|
+
* More supported VCSs, like Subversion or Mercurial
|
76
|
+
* Code analysis to show programming languages, effective lines of code, etc.
|
77
|
+
|
78
|
+
## Contribute
|
79
|
+
|
80
|
+
Metior is a open-source project. Therefore you are free to help improving it.
|
81
|
+
There are several ways of contributing to Metior's development:
|
82
|
+
|
83
|
+
* Build apps using it and spread the word.
|
84
|
+
* Report problems and request features using the [issue tracker][2].
|
85
|
+
* Write patches yourself to fix bugs and implement new functionality.
|
86
|
+
* Create a Metior fork on [GitHub][1] and start hacking. Extra points for using
|
87
|
+
Metior pull requests and feature branches.
|
88
|
+
|
89
|
+
## About the name
|
90
|
+
|
91
|
+
The latin word "metior" means "I measure". That's just what Metior does –
|
92
|
+
measuring source code histories.
|
93
|
+
|
94
|
+
## License
|
95
|
+
|
96
|
+
This code is free software; you can redistribute it and/or modify it under the
|
97
|
+
terms of the new BSD License. A copy of this license can be found in the
|
98
|
+
LICENSE file.
|
99
|
+
|
100
|
+
## Credits
|
101
|
+
|
102
|
+
* Sebastian Staudt – koraktor(at)gmail.com
|
103
|
+
|
104
|
+
## See Also
|
105
|
+
|
106
|
+
* [API documentation][1]
|
107
|
+
* [Metior's homepage][2]
|
108
|
+
* [GitHub project page][3]
|
109
|
+
* [GitHub issue tracker][4]
|
110
|
+
|
111
|
+
Follow Metior on Twitter [@metiorstats](http://twitter.com/metiorstats).
|
112
|
+
|
113
|
+
[1]: http://rubydoc.info/gems/metior/frames
|
114
|
+
[2]: http://koraktor.de/metior
|
115
|
+
[3]: http://github.com/koraktor/metior
|
116
|
+
[4]: http://github.com/koraktor/metior/issues
|
117
|
+
[5]: http://rubydoc.info/github/koraktor/metior/master/frames
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# This code is free software; you can redistribute it and/or modify it under
|
4
|
+
# the terms of the new BSD License.
|
5
|
+
#
|
6
|
+
# Copyright (c) 2011, Sebastian Staudt
|
7
|
+
|
8
|
+
require 'rake/testtask'
|
9
|
+
require 'rubygems/package_task'
|
10
|
+
|
11
|
+
task :default => :test
|
12
|
+
|
13
|
+
# Rake tasks for building the gem
|
14
|
+
spec = Gem::Specification.load('metior.gemspec')
|
15
|
+
Gem::PackageTask.new(spec) do |pkg|
|
16
|
+
end
|
17
|
+
|
18
|
+
# Rake task for running the test suite
|
19
|
+
Rake::TestTask.new do |t|
|
20
|
+
t.libs << 'lib' << 'test'
|
21
|
+
t.test_files = FileList['test/**/test_*.rb']
|
22
|
+
t.verbose = true
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if YARD is installed
|
26
|
+
begin
|
27
|
+
require 'yard'
|
28
|
+
|
29
|
+
# Create a rake task +:doc+ to build the documentation using YARD
|
30
|
+
YARD::Rake::YardocTask.new do |yardoc|
|
31
|
+
yardoc.name = 'doc'
|
32
|
+
yardoc.files = [ 'lib/**/*.rb', 'LICENSE', 'README.md' ]
|
33
|
+
yardoc.options = [ '--private', '--title', 'Metior — API Documentation' ]
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
# Create a rake task +:doc+ to show that YARD is not installed
|
37
|
+
desc 'Generate YARD Documentation (not available)'
|
38
|
+
task :doc do
|
39
|
+
$stderr.puts 'You need YARD to build the documentation. Install it using `gem install yard`.'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Task for cleaning documentation and package directories
|
44
|
+
desc 'Clean documentation and package directories'
|
45
|
+
task :clean do
|
46
|
+
FileUtils.rm_rf 'doc'
|
47
|
+
FileUtils.rm_rf 'pkg'
|
48
|
+
end
|
@@ -0,0 +1,25 @@
|
|
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
|
+
unless Object.method_defined? :singleton_class
|
7
|
+
|
8
|
+
# Provides the `singleton_class` method for Ruby implementations not
|
9
|
+
# supporting it
|
10
|
+
#
|
11
|
+
# @author Sebastian Staudt
|
12
|
+
class Object
|
13
|
+
|
14
|
+
# Returns the singleton class (also known as eigenclass) of this object
|
15
|
+
#
|
16
|
+
# @return [Class] The singleton class of this object
|
17
|
+
def singleton_class
|
18
|
+
class << self
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/metior.rb
ADDED
@@ -0,0 +1,50 @@
|
|
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
|
+
libdir = File.dirname(__FILE__)
|
7
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
8
|
+
|
9
|
+
require 'bundler'
|
10
|
+
|
11
|
+
require 'core_ext/object'
|
12
|
+
require 'metior/git'
|
13
|
+
require 'metior/github'
|
14
|
+
require 'metior/version'
|
15
|
+
|
16
|
+
# Metior is a source code history analyzer that provides various statistics
|
17
|
+
# about a source code repository and its change over time.
|
18
|
+
#
|
19
|
+
# @author Sebastian Staudt
|
20
|
+
module Metior
|
21
|
+
|
22
|
+
# Creates a new repository for the given repository type and path
|
23
|
+
#
|
24
|
+
# @param [Symbol] type The type of the repository, e.g. `:git`
|
25
|
+
# @param [Array<Object>] options The options to use for creating the new
|
26
|
+
# repository, e.g. a file system path
|
27
|
+
# @return [Repository] A VCS specific `Repository` instance
|
28
|
+
def self.repository(type, *options)
|
29
|
+
vcs(type)::Repository.new *options
|
30
|
+
end
|
31
|
+
|
32
|
+
# Calculates simplistic stats for the given repository and branch
|
33
|
+
#
|
34
|
+
# @param [Symbol] type The type of the repository, e.g. `:git`
|
35
|
+
# @param [String] path The file system path of the repository
|
36
|
+
# @param [String] branch The repository's 'branch to analyze. `nil` will use
|
37
|
+
# the VCS's default branch
|
38
|
+
# @return [Hash] The calculated stats for the given repository and branch
|
39
|
+
def self.simple_stats(type, path, branch = nil)
|
40
|
+
repo = repository type, path
|
41
|
+
branch ||= vcs::DEFAULT_BRANCH
|
42
|
+
|
43
|
+
{
|
44
|
+
:authors => repo.authors(branch).values,
|
45
|
+
:commit_count => repo.commits(branch).size,
|
46
|
+
:top_committers => repo.top_contributors(branch, 3)
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/metior/actor.rb
ADDED
@@ -0,0 +1,85 @@
|
|
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
|
+
module Metior
|
7
|
+
|
8
|
+
# Represents an actor in a source code repository
|
9
|
+
#
|
10
|
+
# Depending on the repository's VCS this may be for example an author or
|
11
|
+
# committer.
|
12
|
+
#
|
13
|
+
# @abstract It has to be subclassed to implement a actor representation for a
|
14
|
+
# specific VCS.
|
15
|
+
# @author Sebastian Staudt
|
16
|
+
class Actor
|
17
|
+
|
18
|
+
# @return [Fixnum] The lines of code that have been added by this actor
|
19
|
+
attr_reader :additions
|
20
|
+
|
21
|
+
# @return [Array<Commit>] The list of commits this actor has contributed to
|
22
|
+
# the source code repository
|
23
|
+
attr_reader :commits
|
24
|
+
|
25
|
+
# @return [Fixnum] The lines of code that have been deleted by this actor
|
26
|
+
attr_reader :deletions
|
27
|
+
|
28
|
+
# @return [String] The full name of the actor
|
29
|
+
attr_reader :name
|
30
|
+
|
31
|
+
# @return [String] A unqiue identifier for the actor
|
32
|
+
attr_reader :id
|
33
|
+
|
34
|
+
# Extracts a unique identifier from the given, VCS dependent actor object
|
35
|
+
#
|
36
|
+
# @abstract Different VCSs use different identifiers for users, so this
|
37
|
+
# method must be implemented for each supported VCS.
|
38
|
+
# @param [Object] actor The actor object retrieved from the VCS
|
39
|
+
# @return [String] A unique identifier for the given actor
|
40
|
+
def self.id_for(actor)
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
# Creates a new actor linked to the given source code repository
|
45
|
+
#
|
46
|
+
# @param [Repository] repo The repository this actor belongs to
|
47
|
+
def initialize(repo)
|
48
|
+
@additions = 0
|
49
|
+
@commits = []
|
50
|
+
@deletions = 0
|
51
|
+
@repo = repo
|
52
|
+
end
|
53
|
+
|
54
|
+
# Adds a new commit to the list of commits this actor has contributed to
|
55
|
+
# the analyzed source code repository
|
56
|
+
#
|
57
|
+
# @param [Commit] commit The commit to add to the list
|
58
|
+
def add_commit(commit)
|
59
|
+
@additions += commit.additions
|
60
|
+
@commits << commit
|
61
|
+
@deletions += commit.deletions
|
62
|
+
end
|
63
|
+
|
64
|
+
# Creates a string representation for this actor without recursing into
|
65
|
+
# commit and repository details
|
66
|
+
#
|
67
|
+
# @return [String] A minimal string representation for this actor
|
68
|
+
def inspect
|
69
|
+
'<#%s:0x%x: @commits=%d @id="%s" @name="%s" @repo=<#%s:0x%x ...>>' %
|
70
|
+
[
|
71
|
+
self.class.name, __id__ * 2, @commits.size, @id, @name,
|
72
|
+
@repo.class.name, @repo.__id__ * 2
|
73
|
+
]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the total of changed lines in all commits of this actor
|
77
|
+
#
|
78
|
+
# @return [Fixnum] The total number of changed lines
|
79
|
+
def modifications
|
80
|
+
additions + deletions
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|