gigest 1.0.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/.gitignore +19 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +22 -0
- data/README.markdown +70 -0
- data/Rakefile +11 -0
- data/gigest.gemspec +31 -0
- data/lib/gigest.rb +9 -0
- data/lib/gigest/analytics.rb +45 -0
- data/lib/gigest/github/github_connection.rb +41 -0
- data/lib/gigest/github/github_repo.rb +35 -0
- data/lib/gigest/version.rb +3 -0
- data/spec/fixtures/Gemfile +15 -0
- data/spec/fixtures/statistics.json +60 -0
- data/spec/fixtures/summary.json +60 -0
- data/spec/fixtures/vcr_cassettes/Gigest_Analytics/_statistics/when_repositories_exist/generates_a_summary_report.json +1 -0
- data/spec/fixtures/vcr_cassettes/Gigest_Analytics/_summary/when_repositories_exist/generates_a_summary_report.json +1 -0
- data/spec/fixtures/vcr_cassettes/Gigest_GithubConnection/_gemfile_for/when_Gemfile_does_not_exist/returns_nil.json +1 -0
- data/spec/fixtures/vcr_cassettes/Gigest_GithubConnection/_gemfile_for/when_Gemfile_exists/returns_the_Gemfile_contents.json +1 -0
- data/spec/fixtures/vcr_cassettes/Gigest_GithubConnection/_repositories_for/default/returns_an_array_of_Gigest_GithubRepo.json +1 -0
- data/spec/gigest/analytics_spec.rb +72 -0
- data/spec/gigest/github/github_connection_spec.rb +85 -0
- data/spec/gigest/github/github_repo_spec.rb +39 -0
- data/spec/spec_helper.rb +51 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4c72d8d8cb527ede3b858a34ef086ff08923c5ce
|
4
|
+
data.tar.gz: b9b44d3380cad5990be22693ec8d9a893710a344
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b7dabb8214a7b0be3ca9bb2046e373168ed07a3fdec12dbdd0b6f46fc1d9f44e8c3328b17bf037f142752d60a2ad85f1bf845f1fb38dd4354090cf17bca7a92f
|
7
|
+
data.tar.gz: 2609a9e2aae72c0d82fb8d187077858986da0fd1781b9f52e05ecebfed27cb9cf7662b88f697b97154f510aa9590a4cbcd03e7c07162baf2706a93065d5a4b3f
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gigest
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0-p247
|
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2013 Winston Teo Yong Wei
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person
|
6
|
+
obtaining a copy of this software and associated documentation files (the "Software"),
|
7
|
+
to deal in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
9
|
+
and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
16
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
19
|
+
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
22
|
+
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# GIGEST
|
2
|
+
|
3
|
+
**GI**tHub **GE**m **ST**ats. Discover Gems usage for a GitHub user or org!
|
4
|
+
|
5
|
+
Do you want to know which are the most/least frequently used Gems for a GitHub user or organization?
|
6
|
+
GIGEST gives you the ability to do that by inspecting the Gemfiles across all repos for a GitHub account.
|
7
|
+
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
gem install 'gigest'
|
12
|
+
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
1) Authenticate. You have [4 ways to do it](http://octokit.github.io/octokit.rb/#Authentication).
|
17
|
+
|
18
|
+
analytics = Gigest::Analytics.new(login: "winston", password: "secret")
|
19
|
+
|
20
|
+
Authenticating with your username and password will give GIGEST access to public and private repos within your GitHub account and organization/s.
|
21
|
+
|
22
|
+
Authenticating with an OAuth access token will give GIGEST access to repos depending on the [scopes
|
23
|
+
which the OAuth access token was granted](http://developer.github.com/v3/oauth/#scopes).
|
24
|
+
|
25
|
+
2) Process for a GitHub user or GitHub Organization.
|
26
|
+
|
27
|
+
analytics.process_for("winston")
|
28
|
+
|
29
|
+
This can take a while if the GitHub account contains A LOT of repos. Sit back and relax.
|
30
|
+
|
31
|
+
3) Get summary.
|
32
|
+
|
33
|
+
analytics.summary
|
34
|
+
|
35
|
+
Returns you a Hash in the format:
|
36
|
+
|
37
|
+
{
|
38
|
+
gem1: [repo1, repo2],
|
39
|
+
gem2: [repo1, repo2, repo3, repo4]
|
40
|
+
}
|
41
|
+
|
42
|
+
4) Get statistics.
|
43
|
+
|
44
|
+
analytics.statistics
|
45
|
+
|
46
|
+
Returns you a Hash in the format:
|
47
|
+
|
48
|
+
{
|
49
|
+
gem1: 2, # number of times seen
|
50
|
+
gem2: 4
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
## Contributing
|
55
|
+
|
56
|
+
Pull Requests are very welcomed (with specs, of course)!
|
57
|
+
|
58
|
+
To run all specs, just execute `rake` or `rspec`.
|
59
|
+
|
60
|
+
|
61
|
+
## Author
|
62
|
+
|
63
|
+
GIGEST is maintained by [Winston Teo](mailto:winstonyw+gigest@gmail.com).
|
64
|
+
|
65
|
+
[You should follow Winston on Twitter](http://www.twitter.com/winstonyw), or find out more on [WinstonYW](http://www.winstonyw.com) and [LinkedIn](http://sg.linkedin.com/in/winstonyw).
|
66
|
+
|
67
|
+
|
68
|
+
## License
|
69
|
+
|
70
|
+
Copyright © 2013 Winston Teo Yong Wei. Free software, released under the MIT license.
|
data/Rakefile
ADDED
data/gigest.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
# Maintain your gem's version:
|
7
|
+
require 'gigest/version'
|
8
|
+
|
9
|
+
Gem::Specification.new do |gem|
|
10
|
+
gem.name = "gigest"
|
11
|
+
gem.version = Gigest::VERSION
|
12
|
+
gem.authors = ["Winston Teo"]
|
13
|
+
gem.email = ["winston.yongwei+gigest@gmail.com"]
|
14
|
+
gem.homepage = "https://github.com/winston/gigest"
|
15
|
+
gem.summary = "GIthubGEmSTats. Discover Gems usage for a GitHub user or org."
|
16
|
+
gem.description = "Inspects Gemfiles across all repos for a GitHub user or org and generates Gem usage statistics."
|
17
|
+
|
18
|
+
gem.files = `git ls-files`.split($/)
|
19
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
20
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
21
|
+
gem.require_paths = ["lib"]
|
22
|
+
|
23
|
+
gem.add_dependency "octokit", "~> 2.0"
|
24
|
+
|
25
|
+
gem.add_development_dependency "rspec"
|
26
|
+
gem.add_development_dependency "vcr"
|
27
|
+
gem.add_development_dependency "webmock"
|
28
|
+
gem.add_development_dependency "multi_json"
|
29
|
+
|
30
|
+
gem.license = 'MIT'
|
31
|
+
end
|
data/lib/gigest.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Gigest
|
2
|
+
class Analytics
|
3
|
+
attr_reader :repositories, :repositories_with_gemfile
|
4
|
+
|
5
|
+
def initialize(auth_params={})
|
6
|
+
@connection = GithubConnection.new(auth_params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def process_for(account=nil, type=:user)
|
10
|
+
@repositories = @connection.repositories_for(account, type)
|
11
|
+
@repositories_with_gemfile = @repositories.select(&:has_gemfile?)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns summary
|
15
|
+
# {
|
16
|
+
# gem1: [repo1, repo2],
|
17
|
+
# gem2: [repo1, repo2]
|
18
|
+
# }
|
19
|
+
def summary
|
20
|
+
raise "Please specify GitHub account to analyse by invoking #process_for(account) method first!" if @repositories.nil?
|
21
|
+
|
22
|
+
@repositories_with_gemfile.inject({}) do |summary, repository|
|
23
|
+
repository.gems.each do |gem|
|
24
|
+
summary[gem] ||= []
|
25
|
+
summary[gem] << repository.name unless summary[gem].include?(repository.name)
|
26
|
+
end
|
27
|
+
|
28
|
+
summary
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns statistic (sorted desc)
|
33
|
+
# [
|
34
|
+
# [gem1, 2],
|
35
|
+
# [gem2, 1]
|
36
|
+
# ]
|
37
|
+
def statistics
|
38
|
+
summary.inject({}) do |summary, (gem, repos)|
|
39
|
+
summary[gem] = repos.count
|
40
|
+
summary
|
41
|
+
end
|
42
|
+
.sort_by { |gem, count| count }.reverse
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Gigest
|
2
|
+
class GithubConnection
|
3
|
+
def initialize(auth_params)
|
4
|
+
@connection = Octokit::Client.new(auth_params)
|
5
|
+
end
|
6
|
+
|
7
|
+
def repositories_for(account=nil, type=:user)
|
8
|
+
all_repositories = []
|
9
|
+
|
10
|
+
page = 0
|
11
|
+
loop do
|
12
|
+
repositories = @connection.send(repository_method(type), account, page: page+=1)
|
13
|
+
break if repositories.empty?
|
14
|
+
|
15
|
+
all_repositories += repositories.map { |repository| GithubRepo.new(repository, gemfile_for(repository.full_name)) }
|
16
|
+
end
|
17
|
+
|
18
|
+
all_repositories
|
19
|
+
end
|
20
|
+
|
21
|
+
def gemfile_for(repository_name)
|
22
|
+
decode(file_blob(repository_name, "Gemfile"))
|
23
|
+
rescue Octokit::NotFound
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def repository_method(type)
|
30
|
+
type == :user ? :repositories : :organization_repositories
|
31
|
+
end
|
32
|
+
|
33
|
+
def decode(blob)
|
34
|
+
Base64.decode64(blob)
|
35
|
+
end
|
36
|
+
|
37
|
+
def file_blob(repository_name, file)
|
38
|
+
@connection.contents(repository_name, path: file).content
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Gigest
|
2
|
+
class GithubRepo
|
3
|
+
def initialize(repository, gemfile)
|
4
|
+
@repository = repository
|
5
|
+
@gemfile = gemfile
|
6
|
+
end
|
7
|
+
|
8
|
+
def name
|
9
|
+
@repository.full_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_gemfile?
|
13
|
+
!@gemfile.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
def gems
|
17
|
+
return [] if !has_gemfile?
|
18
|
+
|
19
|
+
@gems ||= process_gemfile
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def process_gemfile
|
25
|
+
@gemfile.split("\n").map do |string|
|
26
|
+
string.start_with?("#") ? nil : find_gem_name(string)
|
27
|
+
end.compact
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_gem_name(string)
|
31
|
+
regex_match = string.match(/gem\s+(?<sdq>['"])(?<name>[a-zA-Z0-9\-_]+)\k<sdq>/)
|
32
|
+
regex_match.nil? ? nil : regex_match[:name]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rails', '3.2.14'
|
4
|
+
|
5
|
+
gem 'google_visualr', '~> 2.1.9'
|
6
|
+
|
7
|
+
group :assets do
|
8
|
+
gem 'compass-rails' , '~> 1.0.3'
|
9
|
+
gem 'sass-rails' , '~> 3.2.5'
|
10
|
+
gem 'uglifier'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :development do
|
14
|
+
gem 'heroku'
|
15
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
[
|
2
|
+
["uglifier", 4],
|
3
|
+
["sass-rails", 3],
|
4
|
+
["jquery-rails", 3],
|
5
|
+
["rails", 3],
|
6
|
+
["heroku", 3],
|
7
|
+
["rspec-rails", 2],
|
8
|
+
["capybara", 2],
|
9
|
+
["google_visualr", 2],
|
10
|
+
["bourbon", 2],
|
11
|
+
["mocha", 2],
|
12
|
+
["nokogiri", 2],
|
13
|
+
["haml", 2],
|
14
|
+
["mysql", 1],
|
15
|
+
["rdiscount", 1],
|
16
|
+
["sass", 1],
|
17
|
+
["jquery-ui-themes", 1],
|
18
|
+
["sinatra", 1],
|
19
|
+
["thin", 1],
|
20
|
+
["ruby-debug", 1],
|
21
|
+
["rspec", 1],
|
22
|
+
["ibm_db", 1],
|
23
|
+
["activerecord-oracle_enhanced-adapter", 1],
|
24
|
+
["ruby-oci8", 1],
|
25
|
+
["activerecord-jdbcpostgresql-adapter", 1],
|
26
|
+
["activerecord-jdbcmysql-adapter", 1],
|
27
|
+
["jruby-openssl", 1],
|
28
|
+
["activerecord-jdbcsqlite3-adapter", 1],
|
29
|
+
["mysql2", 1],
|
30
|
+
["foreman", 1],
|
31
|
+
["pg", 1],
|
32
|
+
["sqlite3", 1],
|
33
|
+
["rest-client", 1],
|
34
|
+
["yajl-ruby", 1],
|
35
|
+
["json", 1],
|
36
|
+
["ruby-prof", 1],
|
37
|
+
["memcache-client", 1],
|
38
|
+
["w3c_validators", 1],
|
39
|
+
["RedCloth", 1],
|
40
|
+
["sdoc", 1],
|
41
|
+
["pivotal_git_scripts", 1],
|
42
|
+
["rake", 1],
|
43
|
+
["journey", 1],
|
44
|
+
["bcrypt-ruby", 1],
|
45
|
+
["arel", 1],
|
46
|
+
["awesome_print", 1],
|
47
|
+
["compass-rails", 1],
|
48
|
+
["turn", 1],
|
49
|
+
["pry", 1],
|
50
|
+
["cactus", 1],
|
51
|
+
["webmock", 1],
|
52
|
+
["evergreen", 1],
|
53
|
+
["ruby-debug19", 1],
|
54
|
+
["factory_girl_rails", 1],
|
55
|
+
["coffee-rails", 1],
|
56
|
+
["timecop", 1],
|
57
|
+
["haml-rails", 1],
|
58
|
+
["rcov", 1],
|
59
|
+
["simplecov", 1]
|
60
|
+
]
|
@@ -0,0 +1,60 @@
|
|
1
|
+
{
|
2
|
+
"activerecord-jdbcmysql-adapter": ["winston/rails"],
|
3
|
+
"activerecord-jdbcpostgresql-adapter": ["winston/rails"],
|
4
|
+
"activerecord-jdbcsqlite3-adapter": ["winston/rails"],
|
5
|
+
"activerecord-oracle_enhanced-adapter": ["winston/rails"],
|
6
|
+
"arel": ["winston/rails"],
|
7
|
+
"awesome_print": ["winston/trackerstats"],
|
8
|
+
"bcrypt-ruby": ["winston/rails"],
|
9
|
+
"bourbon": ["winston/cactus_app", "winston/soloistrc_builder"],
|
10
|
+
"cactus": ["winston/cactus_app"],
|
11
|
+
"capybara": ["winston/cactus_app", "winston/trackerstats"],
|
12
|
+
"coffee-rails": ["winston/cactus_app"],
|
13
|
+
"compass-rails": ["winston/google_visualr_app"],
|
14
|
+
"evergreen": ["winston/trackerstats"],
|
15
|
+
"factory_girl_rails": ["winston/trackerstats"],
|
16
|
+
"foreman": ["winston/soloistrc_builder"],
|
17
|
+
"google_visualr": ["winston/google_visualr_app", "winston/trackerstats"],
|
18
|
+
"haml": ["winston/soloistrc_builder", "winston/trackerstats"],
|
19
|
+
"haml-rails": ["winston/cactus_app"],
|
20
|
+
"heroku": ["winston/google_visualr_app", "winston/soloistrc_builder", "winston/trackerstats"],
|
21
|
+
"ibm_db": ["winston/rails"],
|
22
|
+
"journey": ["winston/rails"],
|
23
|
+
"jquery-rails": ["winston/cactus_app", "winston/rails", "winston/trackerstats"],
|
24
|
+
"jquery-ui-themes": ["winston/trackerstats"],
|
25
|
+
"jruby-openssl": ["winston/rails"],
|
26
|
+
"json": ["winston/rails"],
|
27
|
+
"memcache-client": ["winston/rails"],
|
28
|
+
"mocha": ["winston/rails", "winston/simple_form"],
|
29
|
+
"mysql": ["winston/rails"],
|
30
|
+
"mysql2": ["winston/rails"],
|
31
|
+
"nokogiri": ["winston/rails", "winston/trackerstats"],
|
32
|
+
"pg": ["winston/rails"],
|
33
|
+
"pivotal_git_scripts": ["winston/trackerstats"],
|
34
|
+
"pry": ["winston/evergreen"],
|
35
|
+
"rails": ["winston/cactus_app", "winston/google_visualr_app", "winston/trackerstats"],
|
36
|
+
"rake": ["winston/rails"],
|
37
|
+
"rcov": ["winston/vestal_versions"],
|
38
|
+
"rdiscount": ["winston/soloistrc_builder"],
|
39
|
+
"RedCloth": ["winston/rails"],
|
40
|
+
"rest-client": ["winston/trackerstats"],
|
41
|
+
"rspec": ["winston/set-interview-ruby"],
|
42
|
+
"rspec-rails": ["winston/cactus_app", "winston/trackerstats"],
|
43
|
+
"ruby-debug": ["winston/simple_form"],
|
44
|
+
"ruby-debug19": ["winston/trackerstats"],
|
45
|
+
"ruby-oci8": ["winston/rails"],
|
46
|
+
"ruby-prof": ["winston/rails"],
|
47
|
+
"sass": ["winston/soloistrc_builder"],
|
48
|
+
"sass-rails": ["winston/cactus_app", "winston/google_visualr_app", "winston/trackerstats"],
|
49
|
+
"sdoc": ["winston/rails"],
|
50
|
+
"simplecov": ["winston/vestal_versions"],
|
51
|
+
"sinatra": ["winston/soloistrc_builder"],
|
52
|
+
"sqlite3": ["winston/rails"],
|
53
|
+
"thin": ["winston/soloistrc_builder"],
|
54
|
+
"timecop": ["winston/trackerstats"],
|
55
|
+
"turn": ["winston/trackerstats"],
|
56
|
+
"uglifier": ["winston/cactus_app", "winston/google_visualr_app", "winston/rails", "winston/trackerstats"],
|
57
|
+
"w3c_validators": ["winston/rails"],
|
58
|
+
"webmock": ["winston/trackerstats"],
|
59
|
+
"yajl-ruby": ["winston/rails"]
|
60
|
+
}
|