octocat_herder 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +38 -0
- data/LICENSE.txt +26 -0
- data/README.rdoc +19 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/octocat_herder/base.rb +88 -0
- data/lib/octocat_herder/connection.rb +55 -0
- data/lib/octocat_herder/pull_request/repo.rb +37 -0
- data/lib/octocat_herder/pull_request.rb +171 -0
- data/lib/octocat_herder/repository.rb +92 -0
- data/lib/octocat_herder/user.rb +36 -0
- data/lib/octocat_herder.rb +14 -0
- data/octocat_herder.gemspec +79 -0
- data/spec/octocat_herder/connection_spec.rb +75 -0
- data/spec/octocat_herder_spec.rb +35 -0
- data/spec/spec_helper.rb +14 -0
- metadata +210 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "httparty", "~> 0.7.8"
|
4
|
+
gem "link_header", "~> 0.0.5"
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem "rspec", "~> 2.6.0"
|
8
|
+
gem "mocha", "~> 0.9.12"
|
9
|
+
gem "bundler", "~> 1.0.0"
|
10
|
+
gem "jeweler", "~> 1.6.4"
|
11
|
+
gem "rcov", ">= 0"
|
12
|
+
gem "rdoc", ">= 2.4.2"
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
crack (0.1.8)
|
5
|
+
diff-lcs (1.1.2)
|
6
|
+
git (1.2.5)
|
7
|
+
httparty (0.7.8)
|
8
|
+
crack (= 0.1.8)
|
9
|
+
jeweler (1.6.4)
|
10
|
+
bundler (~> 1.0)
|
11
|
+
git (>= 1.2.5)
|
12
|
+
rake
|
13
|
+
link_header (0.0.5)
|
14
|
+
mocha (0.9.12)
|
15
|
+
rake (0.9.2)
|
16
|
+
rcov (0.9.9)
|
17
|
+
rdoc (3.8)
|
18
|
+
rspec (2.6.0)
|
19
|
+
rspec-core (~> 2.6.0)
|
20
|
+
rspec-expectations (~> 2.6.0)
|
21
|
+
rspec-mocks (~> 2.6.0)
|
22
|
+
rspec-core (2.6.4)
|
23
|
+
rspec-expectations (2.6.0)
|
24
|
+
diff-lcs (~> 1.1.2)
|
25
|
+
rspec-mocks (2.6.0)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
ruby
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
bundler (~> 1.0.0)
|
32
|
+
httparty (~> 0.7.8)
|
33
|
+
jeweler (~> 1.6.4)
|
34
|
+
link_header (~> 0.0.5)
|
35
|
+
mocha (~> 0.9.12)
|
36
|
+
rcov
|
37
|
+
rdoc (>= 2.4.2)
|
38
|
+
rspec (~> 2.6.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright (c) 2011, Jacob Helwig
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are
|
6
|
+
met:
|
7
|
+
|
8
|
+
* Redistributions of source code must retain the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
* Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
13
|
+
documentation and/or other materials provided with the
|
14
|
+
distribution.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
18
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
19
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
20
|
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
26
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= octocat_herder
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to octocat-herder
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 Jacob Helwig. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = 'octocat_herder'
|
18
|
+
gem.homepage = 'http://github.com/jhelwig/octocat_herder'
|
19
|
+
gem.license = 'BSD'
|
20
|
+
gem.summary = 'An interface to the v3 GitHub API'
|
21
|
+
gem.description = 'This gem provides Ruby bindings to the v3 GitHub API'
|
22
|
+
gem.email = 'jacob@technosorcery.net'
|
23
|
+
gem.authors = ['Jacob Helwig']
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rdoc/task'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "octocat_herder #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'link_header'
|
3
|
+
require 'parsedate'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
require 'octocat_herder/connection'
|
7
|
+
|
8
|
+
class OctocatHerder
|
9
|
+
class Base
|
10
|
+
attr_reader :raw, :connection
|
11
|
+
|
12
|
+
def initialize(raw_hash, conn = OctocatHerder::Connection.new)
|
13
|
+
@connection = conn
|
14
|
+
@raw = raw_hash
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(id, *args)
|
18
|
+
unless @raw and @raw.keys.include?(id.id2name)
|
19
|
+
raise NoMethodError.new("undefined method #{id.id2name} for #{self}:#{self.class}")
|
20
|
+
end
|
21
|
+
|
22
|
+
@raw[id.id2name]
|
23
|
+
end
|
24
|
+
|
25
|
+
def available_attributes
|
26
|
+
attrs = []
|
27
|
+
attrs += @raw.keys.reject do |k|
|
28
|
+
[
|
29
|
+
'id',
|
30
|
+
'type',
|
31
|
+
].include? k
|
32
|
+
end if @raw
|
33
|
+
|
34
|
+
(attrs + additional_attributes).uniq
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def self.raw_get(conn, end_point, options={})
|
40
|
+
paginated = options.delete(:paginated)
|
41
|
+
query_params = options.delete(:params) || {}
|
42
|
+
|
43
|
+
query_params[:per_page] = 100 if paginated and query_params[:per_page].nil?
|
44
|
+
query_string = query_string_from_params(query_params)
|
45
|
+
|
46
|
+
result = conn.get(end_point + query_string, options)
|
47
|
+
raise "Unable to retrieve #{end_point}" unless result
|
48
|
+
|
49
|
+
full_result = result.parsed_response
|
50
|
+
|
51
|
+
if paginated
|
52
|
+
if next_page = page_from_headers(result.headers, 'next')
|
53
|
+
query_params[:page] = next_page
|
54
|
+
|
55
|
+
new_options = options.merge(query_params)
|
56
|
+
new_options[:paginated] = true
|
57
|
+
|
58
|
+
full_result += raw_get(conn, end_point, new_options)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
full_result
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.page_from_headers(headers, type)
|
66
|
+
link = LinkHeader.parse(headers['link']).find_link(['rel', type])
|
67
|
+
return unless link
|
68
|
+
|
69
|
+
CGI.parse(URI.parse(link.href).query)['page'].first
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.query_string_from_params(params)
|
73
|
+
return '' if params.keys.empty?
|
74
|
+
|
75
|
+
'?' + params.map {|k,v| "#{URI.escape("#{k}")}=#{URI.escape("#{v}")}"}.join('&')
|
76
|
+
end
|
77
|
+
|
78
|
+
def additional_attributes
|
79
|
+
[]
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_date_time(date_time)
|
83
|
+
return nil unless date_time
|
84
|
+
|
85
|
+
Time.utc(*ParseDate.parsedate(date_time))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'link_header'
|
3
|
+
|
4
|
+
class OctocatHerder
|
5
|
+
class Connection
|
6
|
+
include HTTParty
|
7
|
+
base_uri 'https://api.github.com'
|
8
|
+
|
9
|
+
attr_reader :user_name, :password, :oauth2_token
|
10
|
+
|
11
|
+
def httparty_options
|
12
|
+
@httparty_options || {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(options={})
|
16
|
+
raise ArgumentError.new(
|
17
|
+
"OctocatHerder::Connection does not accept: #{options.class}"
|
18
|
+
) unless options.is_a? Hash
|
19
|
+
|
20
|
+
options.keys.each do |k|
|
21
|
+
raise ArgumentError.new("Unknown option: '#{k}'") unless [
|
22
|
+
:user_name, :password, :oauth2_token
|
23
|
+
].include? k
|
24
|
+
end
|
25
|
+
|
26
|
+
if options.keys.include?(:user_name) or options.keys.include?(:password)
|
27
|
+
raise ArgumentError.new("When providing :user_name or :password, both are required") unless
|
28
|
+
options.keys.include?(:user_name) and options.keys.include?(:password)
|
29
|
+
end
|
30
|
+
|
31
|
+
if options.keys.include?(:oauth2_token) and options.keys.include?(:user_name)
|
32
|
+
raise ArgumentError.new('Cannot provide both an OAuth2 Token, and a user name and password')
|
33
|
+
end
|
34
|
+
|
35
|
+
@user_name = options[:user_name]
|
36
|
+
@password = options[:password]
|
37
|
+
@oauth2_token = options[:oauth2_token]
|
38
|
+
|
39
|
+
if oauth2_token
|
40
|
+
@httparty_options = { :headers => { 'Authorization' => "token #{oauth2_token}" } }
|
41
|
+
elsif user_name
|
42
|
+
@httparty_options = { :basic_auth => { :username => user_name, :password => password } }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def get(end_point, options={})
|
47
|
+
request_options = options.merge(httparty_options)
|
48
|
+
if httparty_options.has_key?(:headers) and options.has_key(:headers)
|
49
|
+
request_options[:headers] = options[:headers].merge(httparty_options[:headers])
|
50
|
+
end
|
51
|
+
|
52
|
+
OctocatHerder::Connection.get(end_point, request_options)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'octocat_herder/base'
|
2
|
+
require 'octocat_herder/user'
|
3
|
+
require 'octocat_herder/repository'
|
4
|
+
|
5
|
+
class OctocatHerder
|
6
|
+
class PullRequest < Base
|
7
|
+
class Repo < ::OctocatHerder::Base
|
8
|
+
def user_login
|
9
|
+
@raw['user']['login']
|
10
|
+
end
|
11
|
+
|
12
|
+
def user_id
|
13
|
+
@raw['user']['id']
|
14
|
+
end
|
15
|
+
|
16
|
+
def user_avatar_url
|
17
|
+
@raw['user']['avatar_url']
|
18
|
+
end
|
19
|
+
|
20
|
+
def user_url
|
21
|
+
@raw['user']['url']
|
22
|
+
end
|
23
|
+
|
24
|
+
def user
|
25
|
+
@user = OctocatHerder::User.fetch(@raw['user'], connection)
|
26
|
+
end
|
27
|
+
|
28
|
+
def repo
|
29
|
+
@repo = OctocatHerder::Repository.new(@raw['repo'], connection)
|
30
|
+
end
|
31
|
+
|
32
|
+
def addtional_attributes
|
33
|
+
['user_login', 'user_id', 'user_avatar_url', 'user_url']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
require 'octocat_herder/base'
|
4
|
+
require 'octocat_herder/connection'
|
5
|
+
require 'octocat_herder/user'
|
6
|
+
require 'octocat_herder/pull_request/repo'
|
7
|
+
|
8
|
+
class OctocatHerder
|
9
|
+
class PullRequest < Base
|
10
|
+
def self.find_for_repository(owner_login, repository_name, status = 'open', conn = OctocatHerder::Connection.new)
|
11
|
+
raise ArgumentError.new("Unknown PullRequest status '#{status}'. Must be one of ['open', 'closed'].") unless
|
12
|
+
['open', 'closed'].include? status
|
13
|
+
|
14
|
+
pull_requests = raw_get(
|
15
|
+
conn,
|
16
|
+
"/repos/#{CGI.escape(owner_login.to_s)}/#{CGI.escape(repository_name.to_s)}/pulls",
|
17
|
+
:paginated => true,
|
18
|
+
:params => { :state => status },
|
19
|
+
:headers => { 'Accept' => 'application/vnd.github-pull.full+json' }
|
20
|
+
)
|
21
|
+
|
22
|
+
pull_requests.map do |pull|
|
23
|
+
new(pull, nil, conn)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.find_open_for_repository(owner_login, repository_name, conn = OctocatHerder::Connection.new)
|
28
|
+
OctocatHerder::PullRequest.find_for_repository(owner_login, repository_name, 'open', conn)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.find_closed_for_repository(owner_login, repository_name, conn = OctocatHerder::Connection.new)
|
32
|
+
OctocatHerder::PullRequest.find_for_repository(owner_login, repository_name, 'closed', conn)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.fetch(owner_login, repository_name, pull_request_number, conn = OctocatHerder::Connection.new)
|
36
|
+
request = raw_get(
|
37
|
+
conn,
|
38
|
+
"/repos/#{CGI.escape(owner_login.to_s)}/#{CGI.escape(repository_name.to_s)}/pulls/#{CGI.escape(pull_request_number.to_s)}",
|
39
|
+
:headers => { 'Accept' => 'application/vnd.github-pull.full+json' }
|
40
|
+
)
|
41
|
+
|
42
|
+
new(nil, request, conn)
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize(raw_hash, raw_detail_hash = nil, conn = OctocatHerder::Connection.new)
|
46
|
+
super raw_hash, conn
|
47
|
+
@raw_detail_hash = raw_detail_hash
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_detail
|
51
|
+
return if @raw_detail_hash
|
52
|
+
|
53
|
+
@raw_detail_hash = raw_get(
|
54
|
+
url,
|
55
|
+
:headers => { 'Accept' => 'application/vnd.github-pull.full+json' }
|
56
|
+
)
|
57
|
+
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def method_missing(id, *args)
|
62
|
+
super
|
63
|
+
rescue NoMethodError => e
|
64
|
+
get_detail
|
65
|
+
return @raw_detail_hash[id.id2name] if @raw_detail_hash and @raw_detail_hash.keys.include?(id.id2name)
|
66
|
+
|
67
|
+
raise e
|
68
|
+
end
|
69
|
+
|
70
|
+
# Nested data from the "overview" data.
|
71
|
+
def user_avatar_url
|
72
|
+
return @raw['user']['avatar_url'] if @raw
|
73
|
+
@raw_detail_hash['user']['avatar_url']
|
74
|
+
end
|
75
|
+
|
76
|
+
def user_url
|
77
|
+
return @raw['user']['url'] if @raw
|
78
|
+
@raw_detail_hash['user']['url']
|
79
|
+
end
|
80
|
+
|
81
|
+
def user_id
|
82
|
+
return @raw['user']['id'] if @raw
|
83
|
+
@raw_detail_hash['user']['id']
|
84
|
+
end
|
85
|
+
|
86
|
+
def user_login
|
87
|
+
return @raw['user']['login'] if @raw
|
88
|
+
@raw_detail_hash['user']['login']
|
89
|
+
end
|
90
|
+
|
91
|
+
# Return a real user, instead of a hash with the nested data.
|
92
|
+
def user
|
93
|
+
@user ||= OctocatHerder::User.fetch(user_login, connection)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Nested data from the "detail" data.
|
97
|
+
def merged_by_login
|
98
|
+
get_detail
|
99
|
+
|
100
|
+
@raw_detail_hash['merged_by']['login']
|
101
|
+
end
|
102
|
+
|
103
|
+
def merged_by_id
|
104
|
+
get_detail
|
105
|
+
|
106
|
+
@raw_detail_hash['merged_by']['id']
|
107
|
+
end
|
108
|
+
|
109
|
+
def merged_by_avatar_url
|
110
|
+
get_detail
|
111
|
+
|
112
|
+
@raw_detail_hash['merged_by']['avatar_url']
|
113
|
+
end
|
114
|
+
|
115
|
+
def merged_by_url
|
116
|
+
get_detail
|
117
|
+
|
118
|
+
@raw_detail_hash['merged_by']['url']
|
119
|
+
end
|
120
|
+
|
121
|
+
# Return a real user, instead of a hash with the nested data.
|
122
|
+
def merged_by
|
123
|
+
get_detail
|
124
|
+
|
125
|
+
@merged_by ||= OctocatHerder::User.fetch(merged_by_login, connection)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Convert a few things to more Ruby friendly Objects
|
129
|
+
def created_at
|
130
|
+
parse_date_time(@raw_detail_hash['created_at'])
|
131
|
+
end
|
132
|
+
|
133
|
+
def updated_at
|
134
|
+
parse_date_time(@raw_detail_hash['updated_at'])
|
135
|
+
end
|
136
|
+
|
137
|
+
def closed_at
|
138
|
+
parse_date_time(@raw_detail_hash['closed_at'])
|
139
|
+
end
|
140
|
+
|
141
|
+
def merged_at
|
142
|
+
parse_date_time(@raw_detail_hash['merged_at'])
|
143
|
+
end
|
144
|
+
|
145
|
+
def head
|
146
|
+
get_detail
|
147
|
+
|
148
|
+
@head_repo ||= OctocatHerder::PullRequest::Repo.new(@raw_detail_hash['head'], connection)
|
149
|
+
end
|
150
|
+
|
151
|
+
def base
|
152
|
+
get_detail
|
153
|
+
|
154
|
+
@base_repo ||= OctocatHerder::PullRequest::Repo.new(@raw_detail_hash['base'], connection)
|
155
|
+
end
|
156
|
+
|
157
|
+
def additional_attributes
|
158
|
+
attrs = ['user_avatar_url', 'user_url', 'user_id', 'user_login']
|
159
|
+
|
160
|
+
attrs += @raw_detail_hash.keys if @raw_detail_hash
|
161
|
+
attrs += ['merged_by_login', 'merged_by_id', 'merged_by_avatar_url', 'merged_by_url']
|
162
|
+
end
|
163
|
+
|
164
|
+
def to_hash
|
165
|
+
raw = @raw || {}
|
166
|
+
detail = @raw_detail_hash || {}
|
167
|
+
|
168
|
+
raw.merge(detail)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
require 'octocat_herder/base'
|
4
|
+
require 'octocat_herder/connection'
|
5
|
+
require 'octocat_herder/user'
|
6
|
+
|
7
|
+
class OctocatHerder
|
8
|
+
class Repository < Base
|
9
|
+
def self.method_missing(id, *args)
|
10
|
+
if id.id2name =~ /list_(.+)/
|
11
|
+
repository_type = Regexp.last_match(1)
|
12
|
+
if ['all', 'private', 'public', 'member'].include? repository_type
|
13
|
+
arguments = [args[0], args[1], repository_type]
|
14
|
+
arguments << args[2] unless args[2].nil?
|
15
|
+
|
16
|
+
return self.list(*arguments)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
raise NoMethodError.new("undefined method #{id.id2name} for #{self}:#{self.class}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def owner_login
|
24
|
+
@raw['owner']['login']
|
25
|
+
end
|
26
|
+
|
27
|
+
def owner_id
|
28
|
+
@raw['owner']['id']
|
29
|
+
end
|
30
|
+
|
31
|
+
def owner_avatar_url
|
32
|
+
@raw['owner']['avatar_url']
|
33
|
+
end
|
34
|
+
|
35
|
+
def owner_url
|
36
|
+
@raw['owner']['url']
|
37
|
+
end
|
38
|
+
|
39
|
+
def owner
|
40
|
+
OctocatHerder::User.fetch(owner_login, connection)
|
41
|
+
end
|
42
|
+
|
43
|
+
def open_pull_requests
|
44
|
+
OctocatHerder::PullRequest.find_for_repository(owner_login, name, 'open')
|
45
|
+
end
|
46
|
+
|
47
|
+
def closed_pull_requests
|
48
|
+
OctocatHerder::PullRequest.find_for_repository(owner_login, name, 'closed')
|
49
|
+
end
|
50
|
+
|
51
|
+
def source
|
52
|
+
return unless @raw['source']
|
53
|
+
|
54
|
+
OctocatHerder::Repository.new(@raw['source'], connection)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def self.list(login, account_type, repository_type, conn = OctocatHerder::Connection.new)
|
60
|
+
url_base = case account_type
|
61
|
+
when "User" then "users"
|
62
|
+
when "Organization" then "orgs"
|
63
|
+
else
|
64
|
+
raise ArgumentError.new("Unknown account type: #{account_type}")
|
65
|
+
end
|
66
|
+
|
67
|
+
repositories = raw_get(
|
68
|
+
conn,
|
69
|
+
"/#{url_base}/#{CGI.escape(login)}/repos",
|
70
|
+
:paginated => true,
|
71
|
+
:params => { :type => repository_type }
|
72
|
+
)
|
73
|
+
|
74
|
+
repositories.map do |repo|
|
75
|
+
new(repo, conn)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.fetch(login, repository_name, conn = OctocatHerder::Connection.new)
|
80
|
+
repo_data = raw_get(
|
81
|
+
conn,
|
82
|
+
"/repos/#{CGI.escape(login)}/#{CGI.escape(repository_name)}"
|
83
|
+
)
|
84
|
+
|
85
|
+
new(repo_data, conn)
|
86
|
+
end
|
87
|
+
|
88
|
+
def additional_attributes
|
89
|
+
['owner_login', 'owner_id', 'owner_avatar_url', 'owner_url']
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'octocat_herder/base'
|
2
|
+
require 'octocat_herder/connection'
|
3
|
+
require 'octocat_herder/repository'
|
4
|
+
|
5
|
+
class OctocatHerder
|
6
|
+
class User < Base
|
7
|
+
def self.fetch(user_name, conn = OctocatHerder::Connection.new)
|
8
|
+
user = raw_get(conn, "/users/#{user_name}")
|
9
|
+
|
10
|
+
OctocatHerder::User.new(user, conn)
|
11
|
+
end
|
12
|
+
|
13
|
+
def repositories
|
14
|
+
@repositories ||= OctocatHerder::Repository.list_all(login, user_type, connection)
|
15
|
+
end
|
16
|
+
|
17
|
+
# The user id can't be handled by the method_missing magic from
|
18
|
+
# OctocatHerder::Base, since the id method returns the object id.
|
19
|
+
def user_id
|
20
|
+
@raw['id']
|
21
|
+
end
|
22
|
+
|
23
|
+
# The user type can't be handled by the method_missing magic from
|
24
|
+
# OctocatHerder::Base, since 'type' is the deprecated form of the
|
25
|
+
# method 'class'.
|
26
|
+
def user_type
|
27
|
+
@raw['type']
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def additional_attributes
|
33
|
+
['user_id', 'user_type']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'octocat_herder/connection'
|
2
|
+
require 'octocat_herder/user'
|
3
|
+
|
4
|
+
class OctocatHerder
|
5
|
+
attr_reader :connection
|
6
|
+
|
7
|
+
def initialize(options={})
|
8
|
+
@connection = OctocatHerder::Connection.new options
|
9
|
+
end
|
10
|
+
|
11
|
+
def user(user_name)
|
12
|
+
OctocatHerder::User.fetch(user_name, connection)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{octocat_herder}
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jacob Helwig"]
|
12
|
+
s.date = %q{2011-07-20}
|
13
|
+
s.description = %q{This gem provides Ruby bindings to the v3 GitHub API}
|
14
|
+
s.email = %q{jacob@technosorcery.net}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/octocat_herder.rb",
|
28
|
+
"lib/octocat_herder/base.rb",
|
29
|
+
"lib/octocat_herder/connection.rb",
|
30
|
+
"lib/octocat_herder/pull_request.rb",
|
31
|
+
"lib/octocat_herder/pull_request/repo.rb",
|
32
|
+
"lib/octocat_herder/repository.rb",
|
33
|
+
"lib/octocat_herder/user.rb",
|
34
|
+
"octocat_herder.gemspec",
|
35
|
+
"spec/octocat_herder/connection_spec.rb",
|
36
|
+
"spec/octocat_herder_spec.rb",
|
37
|
+
"spec/spec_helper.rb"
|
38
|
+
]
|
39
|
+
s.homepage = %q{http://github.com/jhelwig/octocat_herder}
|
40
|
+
s.licenses = ["BSD"]
|
41
|
+
s.require_paths = ["lib"]
|
42
|
+
s.rubygems_version = %q{1.3.7}
|
43
|
+
s.summary = %q{An interface to the v3 GitHub API}
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
47
|
+
s.specification_version = 3
|
48
|
+
|
49
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
50
|
+
s.add_runtime_dependency(%q<httparty>, ["~> 0.7.8"])
|
51
|
+
s.add_runtime_dependency(%q<link_header>, ["~> 0.0.5"])
|
52
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
|
53
|
+
s.add_development_dependency(%q<mocha>, ["~> 0.9.12"])
|
54
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
55
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
56
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
57
|
+
s.add_development_dependency(%q<rdoc>, [">= 2.4.2"])
|
58
|
+
else
|
59
|
+
s.add_dependency(%q<httparty>, ["~> 0.7.8"])
|
60
|
+
s.add_dependency(%q<link_header>, ["~> 0.0.5"])
|
61
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
62
|
+
s.add_dependency(%q<mocha>, ["~> 0.9.12"])
|
63
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
64
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
65
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
66
|
+
s.add_dependency(%q<rdoc>, [">= 2.4.2"])
|
67
|
+
end
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<httparty>, ["~> 0.7.8"])
|
70
|
+
s.add_dependency(%q<link_header>, ["~> 0.0.5"])
|
71
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
72
|
+
s.add_dependency(%q<mocha>, ["~> 0.9.12"])
|
73
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
74
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
75
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
76
|
+
s.add_dependency(%q<rdoc>, [">= 2.4.2"])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe OctocatHerder::Connection do
|
4
|
+
it 'accepts an empty argument list (unauthenticated requests)' do
|
5
|
+
OctocatHerder::Connection.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'accepts a user name and password' do
|
9
|
+
OctocatHerder::Connection.new :user_name => 'bob', :password => 'pass'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'accepts an OAuth2 Token' do
|
13
|
+
OctocatHerder::Connection.new :oauth2_token => 'token goes here'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'requires a user name when given a password' do
|
17
|
+
expect { OctocatHerder::Connection.new :password => 'pass' }.to raise_error(
|
18
|
+
ArgumentError, 'When providing :user_name or :password, both are required'
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'requires a password when given a user name' do
|
23
|
+
expect { OctocatHerder::Connection.new :user_name => 'bob' }.to raise_error(
|
24
|
+
ArgumentError, 'When providing :user_name or :password, both are required'
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'raises an ArgumentError if given an OAuth2 Token and anything else' do
|
29
|
+
expect do
|
30
|
+
OctocatHerder::Connection.new :oauth2_token => 'token goes here', :invalid => 'argument'
|
31
|
+
end.to raise_error(ArgumentError, "Unknown option: 'invalid'")
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'raises an ArgumentError if given a user name, password, and anything else' do
|
35
|
+
expect do
|
36
|
+
OctocatHerder::Connection.new :user_name => 'bob', :password => 'pass', :also => 'invalid'
|
37
|
+
end.to raise_error(ArgumentError, "Unknown option: 'also'")
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'raises an ArgumentError if given anything other than a user name, password, or OAuth2 Token' do
|
41
|
+
expect { OctocatHerder::Connection.new :still => 'bad' }.to raise_error(
|
42
|
+
ArgumentError, "Unknown option: 'still'"
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'raises an ArgumentError if given anything other than a Hash' do
|
47
|
+
expect { OctocatHerder::Connection.new [] }.to raise_error(
|
48
|
+
ArgumentError, 'OctocatHerder::Connection does not accept: Array'
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'raises an ArgumentError if given an OAuth2 Token and a user name and password' do
|
53
|
+
expect do
|
54
|
+
OctocatHerder::Connection.new :user_name => 'bob', :password => 'pass', :oauth2_token => 'token'
|
55
|
+
end.to raise_error(ArgumentError, 'Cannot provide both an OAuth2 Token, and a user name and password')
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'sets the Authorization header when given an OAuth2 Token' do
|
59
|
+
conn = OctocatHerder::Connection.new :oauth2_token => 'my_token'
|
60
|
+
|
61
|
+
conn.httparty_options.should == { :headers => { 'Authorization' => 'token my_token' } }
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'uses basic auth when given a user name and password' do
|
65
|
+
conn = OctocatHerder::Connection.new :user_name => 'user', :password => 'pass'
|
66
|
+
|
67
|
+
conn.httparty_options.should == { :basic_auth => { :username => 'user', :password => 'pass' } }
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should not set any additional options when making unauthenticated requests' do
|
71
|
+
conn = OctocatHerder::Connection.new
|
72
|
+
|
73
|
+
conn.httparty_options.should == {}
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe OctocatHerder do
|
4
|
+
describe "without authentication information" do
|
5
|
+
it 'creates an unauthenticated connection' do
|
6
|
+
OctocatHerder::Connection.expects(:new).with({})
|
7
|
+
|
8
|
+
OctocatHerder.new
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "when provided a user name and password to authenticate" do
|
13
|
+
it 'creates a connection using the user name and password' do
|
14
|
+
OctocatHerder::Connection.expects(:new).with(:user_name => 'user', :password => 'pass')
|
15
|
+
|
16
|
+
OctocatHerder.new :user_name => 'user', :password => 'pass'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "when provided an OAuth2 to authenticate" do
|
21
|
+
it 'creates a connection using the OAuth2 Token' do
|
22
|
+
OctocatHerder::Connection.expects(:new).with(:oauth2_token => 'token')
|
23
|
+
|
24
|
+
OctocatHerder.new :oauth2_token => 'token'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'fetches the specified user using the current connection' do
|
29
|
+
conn = OctocatHerder::Connection.new
|
30
|
+
OctocatHerder.any_instance.stubs(:connection).returns conn
|
31
|
+
OctocatHerder::User.expects(:fetch).with('bob', conn)
|
32
|
+
|
33
|
+
OctocatHerder.new.user('bob')
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
require 'rspec/autorun'
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
require 'octocat_herder'
|
7
|
+
|
8
|
+
# Requires supporting files with custom matchers and macros, etc,
|
9
|
+
# in ./support/ and its subdirectories.
|
10
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.mock_with :mocha
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: octocat_herder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jacob Helwig
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-07-20 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
prerelease: false
|
23
|
+
name: httparty
|
24
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 19
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 7
|
33
|
+
- 8
|
34
|
+
version: 0.7.8
|
35
|
+
requirement: *id001
|
36
|
+
type: :runtime
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
prerelease: false
|
39
|
+
name: link_header
|
40
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 21
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 0
|
49
|
+
- 5
|
50
|
+
version: 0.0.5
|
51
|
+
requirement: *id002
|
52
|
+
type: :runtime
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
prerelease: false
|
55
|
+
name: rspec
|
56
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 23
|
62
|
+
segments:
|
63
|
+
- 2
|
64
|
+
- 6
|
65
|
+
- 0
|
66
|
+
version: 2.6.0
|
67
|
+
requirement: *id003
|
68
|
+
type: :development
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
prerelease: false
|
71
|
+
name: mocha
|
72
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 35
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
- 9
|
81
|
+
- 12
|
82
|
+
version: 0.9.12
|
83
|
+
requirement: *id004
|
84
|
+
type: :development
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
prerelease: false
|
87
|
+
name: bundler
|
88
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 23
|
94
|
+
segments:
|
95
|
+
- 1
|
96
|
+
- 0
|
97
|
+
- 0
|
98
|
+
version: 1.0.0
|
99
|
+
requirement: *id005
|
100
|
+
type: :development
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
prerelease: false
|
103
|
+
name: jeweler
|
104
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 7
|
110
|
+
segments:
|
111
|
+
- 1
|
112
|
+
- 6
|
113
|
+
- 4
|
114
|
+
version: 1.6.4
|
115
|
+
requirement: *id006
|
116
|
+
type: :development
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
prerelease: false
|
119
|
+
name: rcov
|
120
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
hash: 3
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
version: "0"
|
129
|
+
requirement: *id007
|
130
|
+
type: :development
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
prerelease: false
|
133
|
+
name: rdoc
|
134
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
hash: 27
|
140
|
+
segments:
|
141
|
+
- 2
|
142
|
+
- 4
|
143
|
+
- 2
|
144
|
+
version: 2.4.2
|
145
|
+
requirement: *id008
|
146
|
+
type: :development
|
147
|
+
description: This gem provides Ruby bindings to the v3 GitHub API
|
148
|
+
email: jacob@technosorcery.net
|
149
|
+
executables: []
|
150
|
+
|
151
|
+
extensions: []
|
152
|
+
|
153
|
+
extra_rdoc_files:
|
154
|
+
- LICENSE.txt
|
155
|
+
- README.rdoc
|
156
|
+
files:
|
157
|
+
- .document
|
158
|
+
- Gemfile
|
159
|
+
- Gemfile.lock
|
160
|
+
- LICENSE.txt
|
161
|
+
- README.rdoc
|
162
|
+
- Rakefile
|
163
|
+
- VERSION
|
164
|
+
- lib/octocat_herder.rb
|
165
|
+
- lib/octocat_herder/base.rb
|
166
|
+
- lib/octocat_herder/connection.rb
|
167
|
+
- lib/octocat_herder/pull_request.rb
|
168
|
+
- lib/octocat_herder/pull_request/repo.rb
|
169
|
+
- lib/octocat_herder/repository.rb
|
170
|
+
- lib/octocat_herder/user.rb
|
171
|
+
- octocat_herder.gemspec
|
172
|
+
- spec/octocat_herder/connection_spec.rb
|
173
|
+
- spec/octocat_herder_spec.rb
|
174
|
+
- spec/spec_helper.rb
|
175
|
+
has_rdoc: true
|
176
|
+
homepage: http://github.com/jhelwig/octocat_herder
|
177
|
+
licenses:
|
178
|
+
- BSD
|
179
|
+
post_install_message:
|
180
|
+
rdoc_options: []
|
181
|
+
|
182
|
+
require_paths:
|
183
|
+
- lib
|
184
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
hash: 3
|
190
|
+
segments:
|
191
|
+
- 0
|
192
|
+
version: "0"
|
193
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
194
|
+
none: false
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
hash: 3
|
199
|
+
segments:
|
200
|
+
- 0
|
201
|
+
version: "0"
|
202
|
+
requirements: []
|
203
|
+
|
204
|
+
rubyforge_project:
|
205
|
+
rubygems_version: 1.3.7
|
206
|
+
signing_key:
|
207
|
+
specification_version: 3
|
208
|
+
summary: An interface to the v3 GitHub API
|
209
|
+
test_files: []
|
210
|
+
|