github_api 0.2.0 → 0.2.1

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.
Files changed (40) hide show
  1. data/README.rdoc +51 -20
  2. data/lib/github_api.rb +3 -1
  3. data/lib/github_api/api.rb +8 -2
  4. data/lib/github_api/authorization.rb +52 -0
  5. data/lib/github_api/cache_control.rb +19 -0
  6. data/lib/github_api/configuration.rb +8 -11
  7. data/lib/github_api/connection.rb +18 -36
  8. data/lib/github_api/gists/comments.rb +17 -5
  9. data/lib/github_api/issues.rb +9 -1
  10. data/lib/github_api/issues/comments.rb +15 -4
  11. data/lib/github_api/mime_type.rb +55 -0
  12. data/lib/github_api/pull_requests.rb +14 -0
  13. data/lib/github_api/pull_requests/comments.rb +10 -0
  14. data/lib/github_api/repos/collaborators.rb +41 -19
  15. data/lib/github_api/repos/commits.rb +108 -43
  16. data/lib/github_api/repos/forks.rb +32 -13
  17. data/lib/github_api/request.rb +12 -3
  18. data/lib/github_api/request/caching.rb +33 -0
  19. data/lib/github_api/version.rb +1 -1
  20. data/spec/fixtures/repos/collaborators.json +8 -0
  21. data/spec/fixtures/repos/commit.json +53 -0
  22. data/spec/fixtures/repos/commit_comment.json +16 -0
  23. data/spec/fixtures/repos/commit_comments.json +18 -0
  24. data/spec/fixtures/repos/commits.json +27 -0
  25. data/spec/fixtures/{repos_list.json → repos/fork.json} +0 -0
  26. data/spec/fixtures/repos/forks.json +29 -0
  27. data/spec/fixtures/repos/repo_comments.json +18 -0
  28. data/spec/github/authorization_spec.rb +71 -0
  29. data/spec/github/mime_type_spec.rb +70 -0
  30. data/spec/github/repos/collaborators_spec.rb +166 -3
  31. data/spec/github/repos/commits_spec.rb +421 -2
  32. data/spec/github/repos/forks_spec.rb +101 -3
  33. data/spec/github/repos/watching_spec.rb +6 -0
  34. data/spec/github_spec.rb +8 -4
  35. metadata +17 -9
  36. data/lib/github_api/api/extract_options.rb +0 -17
  37. data/lib/github_api/api/mime.rb +0 -5
  38. data/spec/fixtures/collaborators_list.json +0 -6
  39. data/spec/fixtures/commits_list.json +0 -25
  40. data/spec/fixtures/repos_branches_list.json +0 -7
data/README.rdoc CHANGED
@@ -12,7 +12,7 @@ Grab the gem by issuing
12
12
 
13
13
  or in your Gemfile
14
14
 
15
- gem "github_api", "~> 0.2.0"
15
+ gem "github_api", "~> 0.2.1"
16
16
 
17
17
  == Usage
18
18
 
@@ -20,20 +20,12 @@ Create a new client instance
20
20
 
21
21
  @github = Github.new
22
22
 
23
- At this stage you can also supply various configuration parameters, such as :user, :repo, :org, :oauth_token, :login, :password or :basic_auth
24
- which are used thoughtout the API
23
+ At this stage you can also supply various configuration parameters, such as :user, :repo, :org, :oauth_token, :login, :password or :basic_auth which are used thoughtout the API
25
24
 
26
25
  @github = Github.new :user => 'peter-murach', :repo => 'github-api'
27
26
 
28
- In order to authenticate the user through OAuth2 on GitHub you need to
29
-
30
- * visit https://github.com/account/applications/ and register your app
31
- * authorize your credentials https://github.com/login/oauth/authorize
32
- * get your token https://github.com/login/oauth/access_token
27
+ You can authenticate either using OAuth authentication convenience methods(see section OAuth) or through basic authentication by passing your login and password credentials
33
28
 
34
- Once you have your consumer and token keys, configure your github instance following instructions under Configuration.
35
-
36
- You can also use basic authentication by passing your login and password credentials
37
29
  @github = Github.new :login => 'peter-murach', :password => '...'
38
30
 
39
31
  or use convenience method:
@@ -85,7 +77,7 @@ All method calls form ruby like sentences and allow for intuitive api navigation
85
77
 
86
78
  @github = Github.new :oauth_token => '...'
87
79
  @github.users.following 'wycats' # => returns users that 'wycats' is following
88
- @github.users.following? 'wycats' # => returns true if following, otherwise false
80
+ @github.users.following 'wycats' # => returns true if following, otherwise false
89
81
 
90
82
  For specification on all available methods go to http://developer.github.com/v3/ or
91
83
  read the rdoc, all methods are documented there with examples of usage.
@@ -106,14 +98,35 @@ or organisation name, allow you to switch the way the data is returned to you, f
106
98
  puts file.path
107
99
  end
108
100
 
101
+ == OAuth
102
+
103
+ In order to authenticate the user through OAuth2 on GitHub you need to
104
+
105
+ * visit https://github.com/account/applications/ and register your app
106
+
107
+ * authorize your credentials https://github.com/login/oauth/authorize
108
+ You can use convenience methods to help you achieve this that come with this gem:
109
+
110
+ @github = Github.new :client_id => '...', :client_secret => '...'
111
+ @github.authorize_url :redirect_uri => 'http://localhost', :scope => 'repo'
112
+ # => "https://github.com/login/oauth/authorize?scope=repo&response_type=code&client_id='...'&redirect_uri=http%3A%2F%2Flocalhost"
113
+
114
+ After you get your authorization code, call to receive your access_token
115
+
116
+ token = github.get_token( authorization_code )
117
+
118
+ Once you have your access token, configure your github instance following instructions under Configuration.
119
+
109
120
  == MIME Types
110
121
 
111
- Provides support for the following mime types
122
+ Issues, PullRequests and few other API leverage custom mime types which are <tt>:json</tt>, <tt>:blob</tt>, <tt>:raw</tt>, <tt>:text</tt>, <tt>:html</tt>, <tt>:full</tt>. By default <tt>:raw</tt> is used.
112
123
 
113
124
  In order to pass a mime type with your request do
114
125
 
115
- @github = Github.new :oauth_token
116
- @github...
126
+ @github = Github.new
127
+ @github.pull_requests.pull_requests 'peter-murach', 'github', :mime_type => :full
128
+
129
+ Your header will contain 'Accept: "application/vnd.github-pull.full+json"' which in turn returns raw, text and html representations in response body.
117
130
 
118
131
  == Configuration
119
132
 
@@ -132,6 +145,12 @@ or
132
145
 
133
146
  All parameters can be overwirtten as per method call. By passing parameters hash...
134
147
 
148
+ == Caching
149
+
150
+ Each <tt>get</tt> request by default is not going to be cached. In order to set the cache do... If no cache type is provided a default memoization is done.
151
+
152
+ Github.cache do...
153
+
135
154
  == Examples
136
155
 
137
156
  Some api methods require input parameters, these are added simply as a hash properties, for instance
@@ -156,17 +175,29 @@ Query requests instead of http responses return boolean values
156
175
  @github = Github.new
157
176
  @github.orgs.public_member? 'github', 'technoweenie' # => true
158
177
 
159
- == Caching
178
+ == Rails Example
179
+
180
+ A Rails controller that allows a user to authorize their GitHub account and then perform request.
160
181
 
161
- Each call by default is not going to be cached. In order to set the inmemory cache do...
182
+ class GithubController < ApplicationController
183
+
184
+ def authorize
185
+ github = Github.new :client_id => '...', :client_secret => '...'
186
+ address = github.authorize_url :redirect_uri => 'http://...', :scope => 'repo'
187
+ redirect_to address
188
+ end
189
+
190
+ def callback
191
+ authorization_code = params[:code]
192
+ token = github.get_token authorization_code
193
+ access_token = token.token
194
+ end
195
+ end
162
196
 
163
197
  == TODO
164
198
 
165
- * Add support for mime types
166
199
  * Add request caching - local filestore?, http caching?.
167
- * Add oauth2 helper methods.
168
200
  * Add response processing methods
169
- * Add helper methods to return iterators over most common collections.
170
201
  * Add response set helper methods e.i. pagination.
171
202
  * Add DSL falvoured api access
172
203
 
data/lib/github_api.rb CHANGED
@@ -51,6 +51,8 @@ module Github
51
51
  :Orgs => 'orgs',
52
52
  :PullRequests => 'pull_requests',
53
53
  :Users => 'users',
54
- :CoreExt => 'core_ext'
54
+ :CoreExt => 'core_ext',
55
+ :MimeType => 'mime_type',
56
+ :Authorization => 'authorization'
55
57
 
56
58
  end # Github
@@ -3,12 +3,16 @@
3
3
  require 'github_api/configuration'
4
4
  require 'github_api/connection'
5
5
  require 'github_api/request'
6
+ require 'github_api/mime_type'
6
7
  require 'github_api/core_ext/hash'
7
8
  require 'github_api/core_ext/array'
8
9
 
9
10
  module Github
11
+
10
12
  # @private
11
13
  class API
14
+ include Authorization
15
+ include MimeType
12
16
  include Connection
13
17
  include Request
14
18
 
@@ -37,7 +41,7 @@ module Github
37
41
  send("#{key}=", options[key])
38
42
  end
39
43
  _process_basic_auth(options[:basic_auth])
40
- @cached = Hash.new
44
+ client if client_id? && client_secret?
41
45
  end
42
46
 
43
47
  private
@@ -143,7 +147,9 @@ module Github
143
147
  end
144
148
  end
145
149
 
146
- def _merge_parameters(params)
150
+ def _merge_mime_type(resource, params) # :nodoc:
151
+ params['resource'] = resource
152
+ params['mime_type'] = params['mime_type'] || :raw
147
153
  end
148
154
 
149
155
  # TODO add to core extensions
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+ module Authorization
5
+
6
+ attr_accessor :scopes
7
+
8
+ # Setup OAuth2 instance
9
+ def client
10
+ @client ||= ::OAuth2::Client.new(client_id, client_secret,
11
+ :site => 'https://github.com',
12
+ :authorize_url => 'login/oauth/authorize',
13
+ :token_url => 'login/oauth/access_token'
14
+ )
15
+ end
16
+
17
+ # Strategy token
18
+ def auth_code
19
+ _verify_client
20
+ @client.auth_code
21
+ end
22
+
23
+ # Sends authorization request to GitHub.
24
+ # = Parameters
25
+ # * <tt>:redirect_uri</tt> - Required string.
26
+ # * <tt>:scope</tt> - Optional string. Comma separated list of scopes.
27
+ # Available scopes:
28
+ # * (no scope) - public read-only access (includes public user profile info, public repo info, and gists).
29
+ # * <tt>user</tt> - DB read/write access to profile info only.
30
+ # * <tt>public_repo</tt> - DB read/write access, and Git read access to public repos.
31
+ # * <tt>repo</tt> - DB read/write access, and Git read access to public and private repos.
32
+ # * <tt>gist</tt> - write access to gists.
33
+ #
34
+ def authorize_url(params = {})
35
+ _verify_client
36
+ @client.auth_code.authorize_url(params)
37
+ end
38
+
39
+ # Makes request to token endpoint and retrieves access token value
40
+ def get_token(authorization_code, params = {})
41
+ _verify_client
42
+ @client.auth_code.get_token(authorization_code, params)
43
+ end
44
+
45
+ private
46
+
47
+ def _verify_client # :nodoc:
48
+ raise ArgumentError, 'Need to provide client_id and client_secret' unless client_id? && client_secret?
49
+ end
50
+
51
+ end # Authorization
52
+ end # Github
@@ -0,0 +1,19 @@
1
+ module Github
2
+ module CacheOptions
3
+ extend self
4
+
5
+ def self.option_accessor(key)
6
+ defined_method("#{key}=") { |value| }
7
+ end
8
+
9
+ private
10
+
11
+ def initialize_options(options={})
12
+ @default_options = {
13
+ 'type' => :memoization,
14
+
15
+ }
16
+ end
17
+
18
+ end
19
+ end
@@ -9,10 +9,9 @@ module Github
9
9
  :client_secret,
10
10
  :oauth_token,
11
11
  :endpoint,
12
- :format,
13
- :resource,
12
+ :mime_type,
14
13
  :user_agent,
15
- :faraday_options,
14
+ :connection_options,
16
15
  :repo,
17
16
  :user,
18
17
  :login,
@@ -47,12 +46,11 @@ module Github
47
46
  # The value sent in the http header for 'User-Agent' if none is set
48
47
  DEFAULT_USER_AGENT = "Github Ruby Gem #{Github::VERSION::STRING}".freeze
49
48
 
50
- DEFAULT_FORMAT = :json
49
+ # By default the <tt>Accept</tt> header will make a request for <tt>JSON</tt>
50
+ DEFAULT_MIME_TYPE = :json
51
51
 
52
- # By default,
53
- DEFAULT_RESOURCE = nil
54
-
55
- DEFAULT_FARADAY_OPTIONS = {}
52
+ # By default uses the Faraday connection options if none is set
53
+ DEFAULT_CONNECTION_OPTIONS = {}
56
54
 
57
55
  # By default, don't set user name
58
56
  DEFAULT_USER = nil
@@ -84,9 +82,8 @@ module Github
84
82
  self.oauth_token = DEFAULT_OAUTH_TOKEN
85
83
  self.endpoint = DEFAULT_ENDPOINT
86
84
  self.user_agent = DEFAULT_USER_AGENT
87
- self.faraday_options = DEFAULT_FARADAY_OPTIONS
88
- self.format = DEFAULT_FORMAT
89
- self.resource = DEFAULT_RESOURCE
85
+ self.connection_options = DEFAULT_CONNECTION_OPTIONS
86
+ self.mime_type = DEFAULT_MIME_TYPE
90
87
  self.user = DEFAULT_USER
91
88
  self.repo = DEFAULT_REPO
92
89
  self.login = DEFAULT_LOGIN
@@ -11,55 +11,38 @@ require 'github_api/request/basic_auth'
11
11
  module Github
12
12
  module Connection
13
13
 
14
- # Available resources
15
- RESOURCES = {
16
- :issue => 'vnd.github-issue.',
17
- :issuecomment => 'vnd.github-issuecomment.',
18
- :commitcomment => 'vnd.github-commitcomment',
19
- :pull => 'vnd.github-pull.',
20
- :pullcomment => 'vnd.github-pullcomment.',
21
- :gistcomment => 'vnd.github-gistcomment.'
22
- }
23
-
24
- # Mime types used by resources
25
- RESOURCE_MIME_TYPES = {
26
- :raw => 'raw+json',
27
- :text => 'text+json',
28
- :html => 'html+json',
29
- :full => 'html+full'
30
- }
31
-
32
- BLOB_MIME_TYPES = {
33
- :raw => 'vnd.github-blob.raw',
34
- :json => 'json'
35
- }
36
-
37
- def default_faraday_options()
14
+ private
15
+
16
+ def header_options() # :nodoc:
38
17
  {
39
18
  :headers => {
40
- 'Accept' => "application/#{resource}#{format}",
41
- 'User-Agent' => user_agent
19
+ 'Accept' => '*/*', #accepts,
20
+ 'User-Agent' => user_agent,
21
+ 'Content-Type' => 'application/x-www-form-urlencoded'
42
22
  },
43
23
  :ssl => { :verify => false },
44
24
  :url => endpoint
45
25
  }
46
26
  end
47
27
 
48
- # TODO Write mime format conversion
49
-
50
- # Create cache hash and store connection there and then pass it to @connection
51
- # add method to invalidate it if previous options are different from current
52
-
53
- def clear_cache
28
+ def clear_cache # :nodoc:
54
29
  @connection = nil
55
30
  end
56
31
 
57
- def caching?
32
+ def caching? # :nodoc:
58
33
  !@connection.nil?
59
34
  end
60
35
 
61
- def connection(options = {})
62
- merged_options = faraday_options.merge(default_faraday_options)
36
+ def connection(options = {}) # :nodoc:
37
+
38
+ # parse(options['resource'], options['mime_type'] || mime_type) if options['mime_type']
39
+ debugger
40
+
41
+ merged_options = if connection_options.empty?
42
+ header_options
43
+ else
44
+ connection_options.merge(header_options)
45
+ end
63
46
 
64
47
  clear_cache unless options.empty?
65
48
 
@@ -89,4 +72,3 @@ module Github
89
72
 
90
73
  end # Connection
91
74
  end # Github
92
-
@@ -4,8 +4,12 @@ module Github
4
4
  class Gists
5
5
  module Comments
6
6
 
7
- REQUIRED_GIST_COMMENT_INPUTS = %w[ body ]
8
-
7
+ REQUIRED_GIST_COMMENT_INPUTS = %w[
8
+ body
9
+ mime_type
10
+ resource
11
+ ].freeze
12
+
9
13
  # List comments on a gist
10
14
  #
11
15
  # = Examples
@@ -14,6 +18,8 @@ module Github
14
18
  #
15
19
  def gist_comments(gist_id, params={})
16
20
  _normalize_params_keys(params)
21
+ _merge_mime_type(:gist_comment, params)
22
+
17
23
  get("/gists/#{gist_id}/comments", params)
18
24
  end
19
25
 
@@ -25,6 +31,8 @@ module Github
25
31
  #
26
32
  def gist_comment(comment_id, params={})
27
33
  _normalize_params_keys(params)
34
+ _merge_mime_type(:gist_comment, params)
35
+
28
36
  get("/gists/comments/#{comment_id}", params)
29
37
  end
30
38
 
@@ -36,8 +44,9 @@ module Github
36
44
  #
37
45
  def create_gist_comment(gist_id, params={})
38
46
  _normalize_params_keys(params)
47
+ _merge_mime_type(:gist_comment, params)
39
48
  _filter_params_keys(REQUIRED_GIST_COMMENT_INPUTS, params)
40
-
49
+
41
50
  raise ArgumentError, "Required inputs are: :body" unless _validate_inputs(REQUIRED_GIST_COMMENT_INPUTS, params)
42
51
 
43
52
  post("/gists/#{gist_id}/comments", params)
@@ -51,8 +60,9 @@ module Github
51
60
  #
52
61
  def edit_gist_comment(comment_id, params={})
53
62
  _normalize_params_keys(params)
63
+ _merge_mime_type(:gist_comment, params)
54
64
  _filter_params_keys(REQUIRED_GIST_COMMENT_INPUTS, params)
55
-
65
+
56
66
  raise ArgumentError, "Required inputs are: :body" unless _validate_inputs(REQUIRED_GIST_COMMENT_INPUTS, params)
57
67
 
58
68
  patch("/gists/comments/#{comment_id}", params)
@@ -66,9 +76,11 @@ module Github
66
76
  #
67
77
  def delete_gist_comment(comment_id, params={})
68
78
  _normalize_params_keys(params)
79
+ _merge_mime_type(:gist_comment, params)
80
+
69
81
  delete("/gists/comments/#{comment_id}", params)
70
82
  end
71
-
83
+
72
84
  end # Comments
73
85
  end # Gists
74
86
  end # Github
@@ -27,6 +27,8 @@ module Github
27
27
  mentioned
28
28
  title
29
29
  body
30
+ resource
31
+ mime_type
30
32
  ]
31
33
 
32
34
  VALID_ISSUE_PARAM_VALUES = {
@@ -58,7 +60,7 @@ module Github
58
60
  #
59
61
  # = Examples
60
62
  # @github = Github.new :oauth_token => '...'
61
- # @github.issues.issues :since => '2011-04-12312:12:121',
63
+ # @github.issues.issues :since => '2011-04-12312:12:121',
62
64
  # :filter => 'created',
63
65
  # :state => 'open',
64
66
  # :labels => "bug,ui,bla",
@@ -68,6 +70,7 @@ module Github
68
70
  def issues(params={})
69
71
  _normalize_params_keys(params)
70
72
  _filter_params_keys(VALID_ISSUE_PARAM_NAMES, params)
73
+ _merge_mime_type(:issue, params)
71
74
  _validate_params_values(VALID_ISSUE_PARAM_VALUES, params)
72
75
 
73
76
  response = get("/issues", params)
@@ -111,6 +114,7 @@ module Github
111
114
 
112
115
  _normalize_params_keys(params)
113
116
  _filter_params_keys(VALID_ISSUE_PARAM_NAMES, params)
117
+ _merge_mime_type(:issue, params)
114
118
  _validate_params_values(VALID_ISSUE_PARAM_VALUES, params)
115
119
 
116
120
  response = get("/repos/#{user}/#{repo}/issues", params)
@@ -127,7 +131,9 @@ module Github
127
131
  def get_issue(user_name, repo_name, issue_id, params={})
128
132
  _update_user_repo_params(user_name, repo_name)
129
133
  _validate_user_repo_params(user, repo) unless user? && repo?
134
+
130
135
  _normalize_params_keys(params)
136
+ _merge_mime_type(:issue, params)
131
137
 
132
138
  get("/repos/#{user}/#{repo}/issues/#{issue_id}")
133
139
  end
@@ -157,6 +163,7 @@ module Github
157
163
  _validate_user_repo_params(user, repo) unless user? && repo?
158
164
 
159
165
  _normalize_params_keys(params)
166
+ _merge_mime_type(:issue, params)
160
167
  _filter_params_keys(VALID_MILESTONE_INPUTS, params)
161
168
 
162
169
  raise ArgumentError, "Required params are: :title" unless _validate_inputs(%w[ title ], params)
@@ -192,6 +199,7 @@ module Github
192
199
  _validate_presence_of issue_id
193
200
 
194
201
  _normalize_params_keys(params)
202
+ _merge_mime_type(:issue, params)
195
203
  _filter_params_keys(VALID_MILESTONE_INPUTS, params)
196
204
 
197
205
  patch("/repos/#{user}/#{repo}/issues/#{issue_id}", params)