octokit 2.1.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 45f3f29fd88cdbbacdaee29a925b50d458d2557b
4
+ data.tar.gz: 3ddfd44d5073cefef0c7944568cd06f5ece20db3
5
+ SHA512:
6
+ metadata.gz: 8350be3c9efbd2eb298d4322f37986f2a4c7edb4e4a84e66995f501cae68335fb2d826aaaea87eb78268722d60b23f1f77fcc01f786961c91639e0ddc0989f1e
7
+ data.tar.gz: d02327fef9bdad88627bf29a49b130e9c865b4661cc1704582aef7f692565b9886ebd60f97bc6b4a9729eddb02aae16a91054cde76e3430fececee80a63bd982
data/README.md CHANGED
@@ -190,6 +190,37 @@ user = client.users 'defunkt'
190
190
  [access scopes]: http://developer.github.com/v3/oauth/#scopes
191
191
  [app-creds]: http://developer.github.com/v3/#unauthenticated-rate-limited-requests
192
192
 
193
+ ## Pagination
194
+
195
+ Many GitHub API resources are [paginated][]. While you may be tempted to start
196
+ adding `:page` parameters to your calls, the API returns links to the next,
197
+ previous, and last pages for you in the `Link` response header as [Hypermedia
198
+ link relations](docs/hypermedia.md).
199
+
200
+ ```ruby
201
+ issues = Octokit.issues 'rails/rails', :per_page => 100
202
+ issues.concat Octokit.last_response.rels[:next].get.data
203
+ ```
204
+
205
+ ### Auto pagination
206
+
207
+ For smallish resource lists, Octokit provides auto pagination. When this is
208
+ enabled, calls for paginated resources will fetch and concatenate the results
209
+ from every page into a single array:
210
+
211
+ ```ruby
212
+ Octokit.auto_paginate = true
213
+ issues = Octokit.issues 'rails/rails'
214
+ issues.length
215
+
216
+ # => 702
217
+ ```
218
+
219
+ **Note:** While Octokit auto pagination will set the page size to the maximum
220
+ `100`, and seek to not overstep your rate limit, you probably want to use a
221
+ custom pattern for traversing large lists.
222
+
223
+ [paginated]: http://developer.github.com/v3/#pagination
193
224
 
194
225
  ## Configuration and defaults
195
226
 
@@ -21,7 +21,6 @@ module Octokit
21
21
  paginate 'authorizations', options
22
22
  end
23
23
 
24
-
25
24
  # Get a single authorization for the authenticated user.
26
25
  #
27
26
  # You can only access your own tokens, and only through
@@ -90,7 +90,6 @@ module Octokit
90
90
  def delete_commit_comment(repo, id, options = {})
91
91
  boolean_from_response :delete, "repos/#{Repository.new(repo)}/comments/#{id}", options
92
92
  end
93
-
94
93
  end
95
94
  end
96
95
  end
@@ -31,7 +31,7 @@ module Octokit
31
31
  alias :list_commits :commits
32
32
 
33
33
  # Get commits after a specified date
34
-
34
+ #
35
35
  # @overload commits_since(repo, date, options = {})
36
36
  # @param repo [String, Hash, Repository] A GitHub repository
37
37
  # @param date [String] Date on which we want to compare
@@ -311,7 +311,6 @@ module Octokit
311
311
  rescue ArgumentError
312
312
  raise ArgumentError, "#{date} is not a valid date"
313
313
  end
314
-
315
314
  end
316
315
  end
317
316
  end
@@ -155,7 +155,6 @@ module Octokit
155
155
 
156
156
  last_response.headers['Location']
157
157
  end
158
-
159
158
  end
160
159
  end
161
160
  end
@@ -84,6 +84,7 @@ module Octokit
84
84
  end
85
85
 
86
86
  private
87
+
87
88
  def create_download_resource(repo, name, size, options={})
88
89
  post "repos/#{Repository.new(repo)}/downloads", options.merge({:name => name, :size => size})
89
90
  end
@@ -3,6 +3,7 @@ module Octokit
3
3
 
4
4
  # Methods for the the unpublished Emojis API
5
5
  module Emojis
6
+
6
7
  # List all emojis used on GitHub
7
8
  #
8
9
  # @return [Sawyer::Resource] A list of all emojis on GitHub
@@ -6,6 +6,7 @@ module Octokit
6
6
  # @see http://developer.github.com/v3/activity/events/
7
7
  # @see http://developer.github.com/v3/issues/events/
8
8
  module Events
9
+
9
10
  # List all public events for GitHub
10
11
  #
11
12
  # @return [Array<Sawyer::Resource>] A list of all public events from GitHub
@@ -141,7 +142,6 @@ module Octokit
141
142
  def issue_event(repo, number, options = {})
142
143
  paginate "repos/#{Repository.new(repo)}/issues/events/#{number}", options
143
144
  end
144
-
145
145
  end
146
146
  end
147
147
  end
@@ -200,7 +200,6 @@ module Octokit
200
200
  def delete_gist_comment(gist_id, gist_comment_id, options = {})
201
201
  boolean_from_response(:delete, "gists/#{gist_id}/comments/#{gist_comment_id}", options)
202
202
  end
203
-
204
203
  end
205
204
  end
206
205
  end
@@ -27,7 +27,7 @@ module Octokit
27
27
  # the raw contents.
28
28
  #
29
29
  # @param template_name [String] Name of the template. Template names are
30
- # case sensitive, make sure to use a valid name from the
30
+ # case sensitive, make sure to use a valid name from the
31
31
  # .gitignore_templates list.
32
32
  #
33
33
  # @see http://developer.github.com/v3/gitignore/#get-a-single-template
@@ -39,7 +39,6 @@ module Octokit
39
39
  def gitignore_template(template_name, options = {})
40
40
  get "gitignore/templates/#{template_name}", options
41
41
  end
42
-
43
42
  end
44
43
  end
45
44
  end
@@ -151,7 +151,6 @@ module Octokit
151
151
  def labels_for_milestone(repo, number, options = {})
152
152
  get "repos/#{Repository.new(repo)}/milestones/#{number}/labels", options
153
153
  end
154
-
155
154
  end
156
155
  end
157
156
  end
@@ -37,7 +37,6 @@ module Octokit
37
37
  def legacy_search_users(search, options = {})
38
38
  get("legacy/user/search/#{search}", options)['users']
39
39
  end
40
-
41
40
  end
42
41
  end
43
42
  end
@@ -22,7 +22,6 @@ module Octokit
22
22
 
23
23
  post "markdown", options
24
24
  end
25
-
26
25
  end
27
26
  end
28
27
  end
@@ -85,7 +85,6 @@ module Octokit
85
85
  def delete_milestone(repository, number, options = {})
86
86
  boolean_from_response :delete, "repos/#{Repository.new(repository)}/milestones/#{number}", options
87
87
  end
88
-
89
88
  end
90
89
  end
91
90
  end
@@ -166,7 +166,6 @@ module Octokit
166
166
  def delete_thread_subscription(thread_id, options = {})
167
167
  boolean_from_response :delete, "notifications/threads/#{thread_id}/subscription", options
168
168
  end
169
-
170
169
  end
171
170
  end
172
171
  end
@@ -5,6 +5,7 @@ module Octokit
5
5
  #
6
6
  # @see http://developer.github.com/v3/git/
7
7
  module Objects
8
+
8
9
  # Get a single tree, fetching information about its root-level objects
9
10
  #
10
11
  # Pass <tt>:recursive => true</tt> in <tt>options</tt> to fetch information about all of the tree's objects, including those in subdirectories.
@@ -5,6 +5,7 @@ module Octokit
5
5
  #
6
6
  # @see http://developer.github.com/v3/orgs/
7
7
  module Organizations
8
+
8
9
  # Get an organization
9
10
  #
10
11
  # @param org [String] Organization GitHub username.
@@ -57,7 +58,7 @@ module Octokit
57
58
  #
58
59
  # Calling this method on a `@client` will return that users organizations.
59
60
  # Private organizations are included only if the `@client` is authenticated.
60
- #
61
+ #
61
62
  # @param user [String] Username of the user to get list of organizations.
62
63
  # @return [Array<Sawyer::Resource>] Array of hashes representing organizations.
63
64
  # @see http://developer.github.com/v3/orgs/#list-user-organizations
@@ -193,17 +194,17 @@ module Octokit
193
194
 
194
195
  # Create team
195
196
  #
196
- # Requires authenticated organization owner.
197
+ # Requires authenticated organization owner.
197
198
  #
198
199
  # @param org [String] Organization GitHub username.
199
200
  # @option options [String] :name Team name.
200
201
  # @option options [Array<String>] :repo_names Repositories for the team.
201
202
  # @option options [String, optional] :permission ('pull') Permissions the
202
- # team has for team repositories.
203
+ # team has for team repositories.
203
204
  #
204
- # `pull` - team members can pull, but not push to or administer these repositories.
205
- # `push` - team members can pull and push, but not administer these repositories.
206
- # `admin` - team members can pull, push and administer these repositories.
205
+ # `pull` - team members can pull, but not push to or administer these repositories.
206
+ # `push` - team members can pull and push, but not administer these repositories.
207
+ # `admin` - team members can pull, push and administer these repositories.
207
208
  # @return [Sawyer::Resource] Hash representing new team.
208
209
  # @see http://developer.github.com/v3/orgs/teams/#create-team
209
210
  # @example
@@ -235,10 +236,10 @@ module Octokit
235
236
  #
236
237
  # @param team_id [Integer] Team id.
237
238
  # @option options [String] :name Team name.
238
- # @option options [String] :permission Permissions the team has for team repositories.
239
+ # @option options [String] :permission Permissions the team has for team repositories.
239
240
  #
240
- # `pull` - team members can pull, but not push to or administer these repositories.
241
- # `push` - team members can pull and push, but not administer these repositories.
241
+ # `pull` - team members can pull, but not push to or administer these repositories.
242
+ # `push` - team members can pull and push, but not administer these repositories.
242
243
  # `admin` - team members can pull, push and administer these repositories.
243
244
  # @return [Sawyer::Resource] Hash representing updated team.
244
245
  # @see http://developer.github.com/v3/orgs/teams/#edit-team
@@ -279,7 +280,7 @@ module Octokit
279
280
 
280
281
  # Add team member
281
282
  #
282
- # Requires authenticated organization owner or member with team
283
+ # Requires authenticated organization owner or member with team
283
284
  # `admin` permission.
284
285
  #
285
286
  # @param team_id [Integer] Team id.
@@ -297,7 +298,7 @@ module Octokit
297
298
 
298
299
  # Remove team member
299
300
  #
300
- # Requires authenticated organization owner or member with team
301
+ # Requires authenticated organization owner or member with team
301
302
  # `admin` permission.
302
303
  #
303
304
  # @param team_id [Integer] Team id.
@@ -5,6 +5,7 @@ module Octokit
5
5
  #
6
6
  # @see http://developer.github.com/v3/repos/hooks/#pubsubhubbub
7
7
  module PubSubHubbub
8
+
8
9
  # Subscribe to a pubsub topic
9
10
  #
10
11
  # @param topic [String] A recoginized and supported pubsub topic
@@ -55,7 +56,7 @@ module Octokit
55
56
  # client.subscribe_service_hook('joshk/device_imapable', 'Travis', { :token => "test", :domain => "domain", :user => "user" })
56
57
  def subscribe_service_hook(repo, service_name, service_arguments = {})
57
58
  topic = "#{Octokit.web_endpoint}#{Repository.new(repo)}/events/push"
58
- callback = "github://#{service_name}?#{service_arguments.collect{ |k,v| [ k,v ].join("=") }.join("&") }"
59
+ callback = "github://#{service_name}?#{service_arguments.collect{ |k,v| [ k,v ].map{ |p| URI.encode_www_form_component(p) }.join("=") }.join("&") }"
59
60
  subscribe(topic, callback)
60
61
  end
61
62
 
@@ -76,7 +77,7 @@ module Octokit
76
77
  private
77
78
 
78
79
  def pub_sub_hubbub_request(options = {})
79
- # This method is janky, bypass normal stack so we don'tl
80
+ # This method is janky, bypass normal stack so we don'tl
80
81
  # serialize request as JSON
81
82
  conn = Faraday.new(:url => @api_endpoint) do |http|
82
83
  http.headers[:user_agent] = user_agent
@@ -5,6 +5,7 @@ module Octokit
5
5
  #
6
6
  # @see http://developer.github.com/v3/pulls/
7
7
  module PullRequests
8
+
8
9
  # List pull requests for a repository
9
10
  #
10
11
  # @see http://developer.github.com/v3/pulls/#list-pull-requests
@@ -6,7 +6,6 @@ module Octokit
6
6
  # @see http://developer.github.com/v3/repos/
7
7
  module Repositories
8
8
 
9
-
10
9
  # Check if a repository exists
11
10
  #
12
11
  # @see http://developer.github.com/v3/repos/#get
@@ -647,7 +646,6 @@ module Octokit
647
646
  def delete_subscription(repo, options = {})
648
647
  boolean_from_response :delete, "repos/#{Repository.new repo}/subscription", options
649
648
  end
650
-
651
649
  end
652
650
  end
653
651
  end
@@ -33,7 +33,6 @@ module Octokit
33
33
  def github_status_messages
34
34
  get(STATUS_ROOT).rels[:messages].get.data
35
35
  end
36
-
37
36
  end
38
37
  end
39
38
  end
@@ -6,82 +6,81 @@ module Octokit
6
6
  # @see http://developer.github.com/v3/repos/statistics/
7
7
  module Stats
8
8
 
9
- # Get contributors list with additions, deletions, and commit counts
10
- #
11
- # @param repo [String, Hash, Repository] A GitHub repository
12
- # @return [Array<Sawyer::Resource>] Array of contributor stats
13
- # @see http://developer.github.com/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts
14
- # @example Get contributor stats for octokit
15
- # @client.contributors_stats('octokit/octokit.rb')
16
- def contributors_stats(repo, options = {})
17
- get_stats(repo, "contributors", options)
18
- end
19
- alias :contributor_stats :contributors_stats
9
+ # Get contributors list with additions, deletions, and commit counts
10
+ #
11
+ # @param repo [String, Hash, Repository] A GitHub repository
12
+ # @return [Array<Sawyer::Resource>] Array of contributor stats
13
+ # @see http://developer.github.com/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts
14
+ # @example Get contributor stats for octokit
15
+ # @client.contributors_stats('octokit/octokit.rb')
16
+ def contributors_stats(repo, options = {})
17
+ get_stats(repo, "contributors", options)
18
+ end
19
+ alias :contributor_stats :contributors_stats
20
20
 
21
- # Get the last year of commit activity data
22
- #
23
- # @param repo [String, Hash, Repository] A GitHub repository
24
- # @return [Array<Sawyer::Resource>] The last year of commit activity grouped by
25
- # week. The days array is a group of commits per day, starting on Sunday.
26
- # @see http://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity-data
27
- # @example Get commit activity for octokit
28
- # @client.commit_activity_stats('octokit/octokit.rb')
29
- def commit_activity_stats(repo, options = {})
30
- get_stats(repo, "commit_activity", options)
31
- end
21
+ # Get the last year of commit activity data
22
+ #
23
+ # @param repo [String, Hash, Repository] A GitHub repository
24
+ # @return [Array<Sawyer::Resource>] The last year of commit activity grouped by
25
+ # week. The days array is a group of commits per day, starting on Sunday.
26
+ # @see http://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity-data
27
+ # @example Get commit activity for octokit
28
+ # @client.commit_activity_stats('octokit/octokit.rb')
29
+ def commit_activity_stats(repo, options = {})
30
+ get_stats(repo, "commit_activity", options)
31
+ end
32
32
 
33
- # Get the number of additions and deletions per week
34
- #
35
- # @param repo [String, Hash, Repository] A GitHub repository
36
- # @return [Array<Sawyer::Resource>] Weekly aggregate of the number of additions
37
- # and deletions pushed to a repository.
38
- # @see http://developer.github.com/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week
39
- # @example Get code frequency stats for octokit
40
- # @client.code_frequency_stats('octokit/octokit.rb')
41
- def code_frequency_stats(repo, options = {})
42
- get_stats(repo, "code_frequency", options)
43
- end
33
+ # Get the number of additions and deletions per week
34
+ #
35
+ # @param repo [String, Hash, Repository] A GitHub repository
36
+ # @return [Array<Sawyer::Resource>] Weekly aggregate of the number of additions
37
+ # and deletions pushed to a repository.
38
+ # @see http://developer.github.com/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week
39
+ # @example Get code frequency stats for octokit
40
+ # @client.code_frequency_stats('octokit/octokit.rb')
41
+ def code_frequency_stats(repo, options = {})
42
+ get_stats(repo, "code_frequency", options)
43
+ end
44
44
 
45
- # Get the weekly commit count for the repo owner and everyone else
46
- #
47
- # @param repo [String, Hash, Repository] A GitHub repository
48
- # @return [Sawyer::Resource] Total commit counts for the owner and total commit
49
- # counts in all. all is everyone combined, including the owner in the last
50
- # 52 weeks. If you’d like to get the commit counts for non-owners, you can
51
- # subtract all from owner.
52
- # @see http://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repo-owner-and-everyone-else
53
- # @example Get weekly commit counts for octokit
54
- # @client.participation_stats("octokit/octokit.rb")
55
- def participation_stats(repo, options = {})
56
- get_stats(repo, "participation", options)
57
- end
58
-
59
- # Get the number of commits per hour in each day
60
- #
61
- # @param repo [String, Hash, Repository] A GitHub repository
62
- # @return [Array<Array>] Arrays containing the day number, hour number, and
63
- # number of commits
64
- # @see http://developer.github.com/v3/repos/statistics/#get-the-number-of-commits-per-hour-in-each-day
65
- # @example Get octokit punch card
66
- # @octokit.punch_card_stats
67
- def punch_card_stats(repo, options = {})
68
- get_stats(repo, "punch_card", options)
69
- end
70
- alias :punch_card :punch_card_stats
45
+ # Get the weekly commit count for the repo owner and everyone else
46
+ #
47
+ # @param repo [String, Hash, Repository] A GitHub repository
48
+ # @return [Sawyer::Resource] Total commit counts for the owner and total commit
49
+ # counts in all. all is everyone combined, including the owner in the last
50
+ # 52 weeks. If you’d like to get the commit counts for non-owners, you can
51
+ # subtract all from owner.
52
+ # @see http://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repo-owner-and-everyone-else
53
+ # @example Get weekly commit counts for octokit
54
+ # @client.participation_stats("octokit/octokit.rb")
55
+ def participation_stats(repo, options = {})
56
+ get_stats(repo, "participation", options)
57
+ end
71
58
 
72
- private
59
+ # Get the number of commits per hour in each day
60
+ #
61
+ # @param repo [String, Hash, Repository] A GitHub repository
62
+ # @return [Array<Array>] Arrays containing the day number, hour number, and
63
+ # number of commits
64
+ # @see http://developer.github.com/v3/repos/statistics/#get-the-number-of-commits-per-hour-in-each-day
65
+ # @example Get octokit punch card
66
+ # @octokit.punch_card_stats
67
+ def punch_card_stats(repo, options = {})
68
+ get_stats(repo, "punch_card", options)
69
+ end
70
+ alias :punch_card :punch_card_stats
73
71
 
74
- # @private Get stats for a repository
75
- #
76
- # @param repo [String, Hash, Repository] A GitHub repository
77
- # @param metric [String] The metrics you are looking for
78
- # @return [Array<Sawyer::Resource>] Magical unicorn stats
79
- def get_stats(repo, metric, options = {})
80
- data = get("repos/#{Repository.new repo}/stats/#{metric}", options)
72
+ private
81
73
 
82
- last_response.status == 202 ? nil : data
83
- end
74
+ # @private Get stats for a repository
75
+ #
76
+ # @param repo [String, Hash, Repository] A GitHub repository
77
+ # @param metric [String] The metrics you are looking for
78
+ # @return [Array<Sawyer::Resource>] Magical unicorn stats
79
+ def get_stats(repo, metric, options = {})
80
+ data = get("repos/#{Repository.new repo}/stats/#{metric}", options)
84
81
 
82
+ last_response.status == 202 ? nil : data
83
+ end
85
84
  end
86
85
  end
87
86
  end
@@ -110,7 +110,7 @@ module Octokit
110
110
  get "users/#{user}/following", options
111
111
  end
112
112
 
113
- # Check if you are following a user. Alternatively, check if a given user
113
+ # Check if you are following a user. Alternatively, check if a given user
114
114
  # is following a target user.
115
115
  #
116
116
  # Requries an authenticated client.
@@ -182,14 +182,21 @@ module Octokit
182
182
  #
183
183
  # Requires authenticated client.
184
184
  #
185
- # @param user [String] Username of repository owner.
186
- # @param repo [String] Name of the repository.
185
+ # @param args [String, Hash, Repository] A GitHub repository
187
186
  # @return [Boolean] True if you are following the repo, false otherwise.
188
187
  # @see http://developer.github.com/v3/repos/starring/#check-if-you-are-starring-a-repository
189
188
  # @example
190
- # @client.starred?('pengwynn', 'octokit')
191
- def starred?(user, repo, options = {})
192
- boolean_from_response :get, "user/starred/#{user}/#{repo}", options
189
+ # @client.starred?('pengwynn/octokit')
190
+ # @client.starred?('pengwynn', 'octokit') # deprecated
191
+ def starred?(*args)
192
+ arguments = Octokit::Arguments.new(args)
193
+ options = arguments.options
194
+ name = name_with_owner = arguments.shift
195
+ if repo = arguments.shift
196
+ name_with_owner = "#{name}/#{repo}"
197
+ warn "`.starred?('#{name}', '#{repo}')` is deprecated. Please use `.starred?('#{name_with_owner}')` instead."
198
+ end
199
+ boolean_from_response :get, "user/starred/#{Repository.new name_with_owner}", options
193
200
  end
194
201
 
195
202
  # Get a public key.
@@ -13,28 +13,19 @@ module Octokit
13
13
  headers = response[:response_headers]
14
14
 
15
15
  if klass = case status
16
- when 400 then Octokit::BadRequest
17
- when 401
18
- if Octokit::OneTimePasswordRequired.required_header(headers)
19
- Octokit::OneTimePasswordRequired
20
- else
21
- Octokit::Unauthorized
22
- end
23
- when 403
24
- if body =~ /rate limit exceeded/i
25
- Octokit::TooManyRequests
26
- elsif body =~ /login attempts exceeded/i
27
- Octokit::TooManyLoginAttempts
28
- else
29
- Octokit::Forbidden
30
- end
31
- when 404 then Octokit::NotFound
32
- when 406 then Octokit::NotAcceptable
33
- when 422 then Octokit::UnprocessableEntity
34
- when 500 then Octokit::InternalServerError
35
- when 501 then Octokit::NotImplemented
36
- when 502 then Octokit::BadGateway
37
- when 503 then Octokit::ServiceUnavailable
16
+ when 400 then Octokit::BadRequest
17
+ when 401 then error_for_401(headers)
18
+ when 403 then error_for_403(body)
19
+ when 404 then Octokit::NotFound
20
+ when 406 then Octokit::NotAcceptable
21
+ when 415 then Octokit::UnsupportedMediaType
22
+ when 422 then Octokit::UnprocessableEntity
23
+ when 400..499 then Octokit::ClientError
24
+ when 500 then Octokit::InternalServerError
25
+ when 501 then Octokit::NotImplemented
26
+ when 502 then Octokit::BadGateway
27
+ when 503 then Octokit::ServiceUnavailable
28
+ when 500..599 then Octokit::ServerError
38
29
  end
39
30
  klass.new(response)
40
31
  end
@@ -45,6 +36,35 @@ module Octokit
45
36
  super(build_error_message)
46
37
  end
47
38
 
39
+ # Documentation URL returned by the API for some errors
40
+ #
41
+ # @return [String]
42
+ def documentation_url
43
+ data[:documentation_url] if data
44
+ end
45
+
46
+ # Returns most appropriate error for 401 HTTP status code
47
+ # @private
48
+ def self.error_for_401(headers)
49
+ if Octokit::OneTimePasswordRequired.required_header(headers)
50
+ Octokit::OneTimePasswordRequired
51
+ else
52
+ Octokit::Unauthorized
53
+ end
54
+ end
55
+
56
+ # Returns most appropriate error for 403 HTTP status code
57
+ # @private
58
+ def self.error_for_403(body)
59
+ if body =~ /rate limit exceeded/i
60
+ Octokit::TooManyRequests
61
+ elsif body =~ /login attempts exceeded/i
62
+ Octokit::TooManyLoginAttempts
63
+ else
64
+ Octokit::Forbidden
65
+ end
66
+ end
67
+
48
68
  private
49
69
 
50
70
  def data
@@ -96,32 +116,41 @@ module Octokit
96
116
  message << "#{response_message}" unless response_message.nil?
97
117
  message << "#{response_error}" unless response_error.nil?
98
118
  message << "#{response_error_summary}" unless response_error_summary.nil?
119
+ message << " // See: #{documentation_url}" unless documentation_url.nil?
99
120
  message
100
121
  end
101
122
  end
102
123
 
124
+ # Raised on errors in the 400-499 range
125
+ class ClientError < Error; end
126
+
103
127
  # Raised when GitHub returns a 400 HTTP status code
104
- class BadRequest < Error; end
128
+ class BadRequest < ClientError; end
105
129
 
106
130
  # Raised when GitHub returns a 401 HTTP status code
107
- class Unauthorized < Error; end
131
+ class Unauthorized < ClientError; end
108
132
 
109
133
  # Raised when GitHub returns a 401 HTTP status code
110
134
  # and headers include "X-GitHub-OTP"
111
- class OneTimePasswordRequired < Error
135
+ class OneTimePasswordRequired < ClientError
136
+ #@private
112
137
  HEADER = /required; (?<delivery>\w+)/i
113
138
 
139
+ #@private
114
140
  def self.required_header(headers)
115
141
  HEADER.match headers['X-GitHub-OTP'].to_s
116
142
  end
117
143
 
144
+ # Delivery method for the user's OTP
145
+ #
146
+ # @return [String]
118
147
  def password_delivery
119
148
  @password_delivery ||= self.class.required_header(@response[:response_headers])[:delivery]
120
149
  end
121
150
  end
122
151
 
123
152
  # Raised when GitHub returns a 403 HTTP status code
124
- class Forbidden < Error; end
153
+ class Forbidden < ClientError; end
125
154
 
126
155
  # Raised when GitHub returns a 403 HTTP status code
127
156
  # and body matches 'rate limit exceeded'
@@ -132,23 +161,29 @@ module Octokit
132
161
  class TooManyLoginAttempts < Forbidden; end
133
162
 
134
163
  # Raised when GitHub returns a 404 HTTP status code
135
- class NotFound < Error; end
164
+ class NotFound < ClientError; end
136
165
 
137
166
  # Raised when GitHub returns a 406 HTTP status code
138
- class NotAcceptable < Error; end
167
+ class NotAcceptable < ClientError; end
168
+
169
+ # Raised when GitHub returns a 414 HTTP status code
170
+ class UnsupportedMediaType < ClientError; end
139
171
 
140
172
  # Raised when GitHub returns a 422 HTTP status code
141
- class UnprocessableEntity < Error; end
173
+ class UnprocessableEntity < ClientError; end
174
+
175
+ # Raised on errors in the 500-599 range
176
+ class ServerError < Error; end
142
177
 
143
178
  # Raised when GitHub returns a 500 HTTP status code
144
- class InternalServerError < Error; end
179
+ class InternalServerError < ServerError; end
145
180
 
146
181
  # Raised when GitHub returns a 501 HTTP status code
147
- class NotImplemented < Error; end
182
+ class NotImplemented < ServerError; end
148
183
 
149
184
  # Raised when GitHub returns a 502 HTTP status code
150
- class BadGateway < Error; end
185
+ class BadGateway < ServerError; end
151
186
 
152
187
  # Raised when GitHub returns a 503 HTTP status code
153
- class ServiceUnavailable < Error; end
188
+ class ServiceUnavailable < ServerError; end
154
189
  end
@@ -2,6 +2,6 @@ module Octokit
2
2
 
3
3
  # Current version
4
4
  # @return [String]
5
- VERSION = "2.1.1".freeze
5
+ VERSION = "2.1.2".freeze
6
6
 
7
7
  end
@@ -5,7 +5,7 @@ require 'octokit/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.add_development_dependency 'bundler', '~> 1.0'
8
- spec.add_dependency 'sawyer', '~> 0.3.0'
8
+ spec.add_dependency 'sawyer', '~> 0.5.0'
9
9
  spec.authors = ["Wynn Netherland", "Erik Michaels-Ober", "Clint Shryock"]
10
10
  spec.description = %q{Simple wrapper for the GitHub API}
11
11
  spec.email = ['wynn.netherland@gmail.com', 'sferik@gmail.com', 'clint@ctshryock.com']
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"get","uri":"https://api.github.com/user/starred/sferik/rails_admin","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["application/vnd.github.beta+json"],"User-Agent":["Octokit Ruby Gem 2.1.1"],"Authorization":["token <<ACCESS_TOKEN>>"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":404,"message":"Not Found"},"headers":{"Server":["GitHub.com"],"Date":["Sun, 08 Sep 2013 15:01:28 GMT"],"Content-Type":["application/json; charset=utf-8"],"Transfer-Encoding":["chunked"],"Status":["404 Not Found"],"X-Ratelimit-Limit":["5000"],"X-Ratelimit-Remaining":["4995"],"X-Ratelimit-Reset":["1378654817"],"X-Oauth-Scopes":["user, public_repo, repo, gist"],"X-Accepted-Oauth-Scopes":["repo, public_repo, repo:status, repo:deployment, delete_repo, site_admin"],"X-Github-Media-Type":["github.beta; format=json"],"X-Content-Type-Options":["nosniff"],"Access-Control-Allow-Credentials":["true"],"Access-Control-Expose-Headers":["ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes"],"Access-Control-Allow-Origin":["*"],"X-Github-Request-Id":["fec2764a-0d89-4c63-8645-0c8f89a4294b"]},"body":{"encoding":"UTF-8","base64_string":"eyJtZXNzYWdlIjoiTm90IEZvdW5kIn0=\n"},"http_version":null},"recorded_at":"Sun, 08 Sep 2013 15:01:28 GMT"}],"recorded_with":"VCR 2.4.0"}
@@ -60,6 +60,18 @@ describe Octokit::Client::PubSubHubbub do
60
60
  assert_requested :post, github_url("/hub"), :body => subscribe_request_body, :times => 1,
61
61
  :headers => {'Content-type' => 'application/x-www-form-urlencoded'}
62
62
  end
63
+ it "encodes URL parameters" do
64
+ irc_request_body = {
65
+ :"hub.callback" => 'github://irc?server=chat.freenode.org&room=%23myproject',
66
+ :"hub.mode" => 'subscribe',
67
+ :"hub.topic" => 'https://github.com/joshk/completeness-fu/events/push'
68
+ }
69
+ stub_post("/hub").
70
+ with(irc_request_body).
71
+ to_return(:status => 204)
72
+ expect(@client.subscribe_service_hook("joshk/completeness-fu", "irc", { :server => "chat.freenode.org", :room => "#myproject"})).to eql(true)
73
+ assert_requested :post, "https://api.github.com/hub", :body => irc_request_body, :times => 1
74
+ end
63
75
  end # .subscribe_service_hook
64
76
 
65
77
  describe "unsubscribe_service_hook", :vcr do
@@ -93,6 +93,10 @@ describe Octokit::Client::Users do
93
93
 
94
94
  describe ".starred?", :vcr do
95
95
  it "checks if the authenticated user has starred a repository" do
96
+ starred = @client.starred?("sferik/rails_admin")
97
+ assert_requested :get, github_url("/user/starred/sferik/rails_admin")
98
+ end
99
+ it "checks if the authenticated user has starred a repository (deprecated)" do
96
100
  starred = @client.starred?("sferik", "rails_admin")
97
101
  assert_requested :get, github_url("/user/starred/sferik/rails_admin")
98
102
  end
@@ -478,6 +478,45 @@ describe Octokit::Client do
478
478
  :body => {:message => "Maximum number of login attempts exceeded"}.to_json
479
479
  expect { Octokit.get('/user') }.to raise_error Octokit::TooManyLoginAttempts
480
480
  end
481
+
482
+ it "raises on unknown client errors" do
483
+ stub_get('/user').to_return \
484
+ :status => 418,
485
+ :headers => {
486
+ :content_type => "application/json",
487
+ },
488
+ :body => {:message => "I'm a teapot"}.to_json
489
+ expect { Octokit.get('/user') }.to raise_error Octokit::ClientError
490
+ end
491
+
492
+ it "raises on unknown server errors" do
493
+ stub_get('/user').to_return \
494
+ :status => 509,
495
+ :headers => {
496
+ :content_type => "application/json",
497
+ },
498
+ :body => {:message => "Bandwidth exceeded"}.to_json
499
+ expect { Octokit.get('/user') }.to raise_error Octokit::ServerError
500
+ end
501
+
502
+ it "handles documentation URLs in error messages" do
503
+ stub_get('/user').to_return \
504
+ :status => 415,
505
+ :headers => {
506
+ :content_type => "application/json",
507
+ },
508
+ :body => {
509
+ :message => "Unsupported Media Type",
510
+ :documentation_url => "http://developer.github.com/v3"
511
+ }.to_json
512
+ begin
513
+ Octokit.get('/user')
514
+ rescue Octokit::UnsupportedMediaType => e
515
+ msg = "415 - Unsupported Media Type"
516
+ expect(e.message).to include(msg)
517
+ expect(e.documentation_url).to eq("http://developer.github.com/v3")
518
+ end
519
+ end
481
520
  end
482
521
 
483
522
  it "knows the difference between unauthorized and needs OTP" do
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octokit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
5
- prerelease:
4
+ version: 2.1.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Wynn Netherland
@@ -11,12 +10,11 @@ authors:
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2013-09-03 00:00:00.000000000 Z
13
+ date: 2013-09-22 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: bundler
18
17
  requirement: !ruby/object:Gem::Requirement
19
- none: false
20
18
  requirements:
21
19
  - - ~>
22
20
  - !ruby/object:Gem::Version
@@ -24,7 +22,6 @@ dependencies:
24
22
  type: :development
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
25
  requirements:
29
26
  - - ~>
30
27
  - !ruby/object:Gem::Version
@@ -32,19 +29,17 @@ dependencies:
32
29
  - !ruby/object:Gem::Dependency
33
30
  name: sawyer
34
31
  requirement: !ruby/object:Gem::Requirement
35
- none: false
36
32
  requirements:
37
33
  - - ~>
38
34
  - !ruby/object:Gem::Version
39
- version: 0.3.0
35
+ version: 0.5.0
40
36
  type: :runtime
41
37
  prerelease: false
42
38
  version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
39
  requirements:
45
40
  - - ~>
46
41
  - !ruby/object:Gem::Version
47
- version: 0.3.0
42
+ version: 0.5.0
48
43
  description: Simple wrapper for the GitHub API
49
44
  email:
50
45
  - wynn.netherland@gmail.com
@@ -370,6 +365,7 @@ files:
370
365
  - spec/cassettes/Octokit_Client_Users/_starred/returns_starred_repositories_for_a_user.json
371
366
  - spec/cassettes/Octokit_Client_Users/_starred/returns_starred_repositories_for_the_authenticated_user.json
372
367
  - spec/cassettes/Octokit_Client_Users/_starred_/checks_if_the_authenticated_user_has_starred_a_repository.json
368
+ - spec/cassettes/Octokit_Client_Users/_starred_/checks_if_the_authenticated_user_has_starred_a_repository_deprecated_.json
373
369
  - spec/cassettes/Octokit_Client_Users/_subscriptions/returns_the_repositories_a_user_watches_for_notifications.json
374
370
  - spec/cassettes/Octokit_Client_Users/_subscriptions/returns_the_repositories_the_authenticated_user_watches_for_notifications.json
375
371
  - spec/cassettes/Octokit_Client_Users/_unfollow/unfollows_a_user.json
@@ -426,27 +422,26 @@ files:
426
422
  homepage: https://github.com/octokit/octokit.rb
427
423
  licenses:
428
424
  - MIT
425
+ metadata: {}
429
426
  post_install_message:
430
427
  rdoc_options: []
431
428
  require_paths:
432
429
  - lib
433
430
  required_ruby_version: !ruby/object:Gem::Requirement
434
- none: false
435
431
  requirements:
436
- - - ! '>='
432
+ - - '>='
437
433
  - !ruby/object:Gem::Version
438
434
  version: '0'
439
435
  required_rubygems_version: !ruby/object:Gem::Requirement
440
- none: false
441
436
  requirements:
442
- - - ! '>='
437
+ - - '>='
443
438
  - !ruby/object:Gem::Version
444
439
  version: 1.3.5
445
440
  requirements: []
446
441
  rubyforge_project:
447
- rubygems_version: 1.8.23
442
+ rubygems_version: 2.0.3
448
443
  signing_key:
449
- specification_version: 3
444
+ specification_version: 4
450
445
  summary: Ruby toolkit for working with the GitHub API
451
446
  test_files:
452
447
  - spec/cassettes/delete_authorization.json
@@ -717,6 +712,7 @@ test_files:
717
712
  - spec/cassettes/Octokit_Client_Users/_starred/returns_starred_repositories_for_a_user.json
718
713
  - spec/cassettes/Octokit_Client_Users/_starred/returns_starred_repositories_for_the_authenticated_user.json
719
714
  - spec/cassettes/Octokit_Client_Users/_starred_/checks_if_the_authenticated_user_has_starred_a_repository.json
715
+ - spec/cassettes/Octokit_Client_Users/_starred_/checks_if_the_authenticated_user_has_starred_a_repository_deprecated_.json
720
716
  - spec/cassettes/Octokit_Client_Users/_subscriptions/returns_the_repositories_a_user_watches_for_notifications.json
721
717
  - spec/cassettes/Octokit_Client_Users/_subscriptions/returns_the_repositories_the_authenticated_user_watches_for_notifications.json
722
718
  - spec/cassettes/Octokit_Client_Users/_unfollow/unfollows_a_user.json