octokit 1.19.0 → 1.20.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.
Files changed (51) hide show
  1. data/.travis.yml +2 -0
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +35 -1
  4. data/lib/faraday/response/raise_octokit_error.rb +15 -22
  5. data/lib/octokit.rb +2 -1
  6. data/lib/octokit/authentication.rb +15 -0
  7. data/lib/octokit/client.rb +4 -0
  8. data/lib/octokit/client/authorizations.rb +1 -1
  9. data/lib/octokit/client/commits.rb +15 -14
  10. data/lib/octokit/client/contents.rb +42 -42
  11. data/lib/octokit/client/downloads.rb +5 -1
  12. data/lib/octokit/client/gists.rb +6 -12
  13. data/lib/octokit/client/gitignore.rb +41 -0
  14. data/lib/octokit/client/issues.rb +30 -1
  15. data/lib/octokit/client/labels.rb +2 -2
  16. data/lib/octokit/client/milestones.rb +1 -1
  17. data/lib/octokit/client/notifications.rb +1 -5
  18. data/lib/octokit/client/organizations.rb +11 -15
  19. data/lib/octokit/client/pulls.rb +33 -7
  20. data/lib/octokit/client/refs.rb +1 -1
  21. data/lib/octokit/client/repositories.rb +27 -40
  22. data/lib/octokit/client/users.rb +25 -13
  23. data/lib/octokit/configuration.rb +4 -2
  24. data/lib/octokit/connection.rb +6 -4
  25. data/lib/octokit/request.rb +9 -0
  26. data/lib/octokit/version.rb +1 -1
  27. data/octokit.gemspec +2 -1
  28. data/spec/fixtures/.netrc +2 -0
  29. data/spec/fixtures/all_repositories.json +122 -0
  30. data/spec/fixtures/all_users.json +34 -0
  31. data/spec/fixtures/gitignore_template_ruby.json +4 -0
  32. data/spec/fixtures/gitignore_templates.json +78 -0
  33. data/spec/fixtures/pull_requests_comments.json +82 -0
  34. data/spec/fixtures/repository_issues_comments.json +52 -0
  35. data/spec/octokit/client/authorizations_spec.rb +1 -1
  36. data/spec/octokit/client/commits_spec.rb +1 -1
  37. data/spec/octokit/client/downloads_spec.rb +1 -1
  38. data/spec/octokit/client/gists_spec.rb +6 -6
  39. data/spec/octokit/client/gitignore_spec.rb +29 -0
  40. data/spec/octokit/client/issues_spec.rb +12 -1
  41. data/spec/octokit/client/labels_spec.rb +2 -2
  42. data/spec/octokit/client/milestones_spec.rb +1 -1
  43. data/spec/octokit/client/notifications_spec.rb +10 -10
  44. data/spec/octokit/client/organizations_spec.rb +10 -10
  45. data/spec/octokit/client/pulls_spec.rb +13 -2
  46. data/spec/octokit/client/refs_spec.rb +1 -1
  47. data/spec/octokit/client/repositories_spec.rb +25 -14
  48. data/spec/octokit/client/users_spec.rb +17 -6
  49. data/spec/octokit/client_spec.rb +47 -1
  50. data/spec/octokit_spec.rb +1 -1
  51. metadata +36 -3
data/.travis.yml CHANGED
@@ -7,3 +7,5 @@ rvm:
7
7
  - 1.9.2
8
8
  - 1.9.3
9
9
  - ruby-head
10
+ before_script:
11
+ - chmod 600 spec/fixtures/.netrc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # CHANGELOG
2
2
 
3
+ # 1.20.0
4
+
5
+ * [@joeyw](https://github.com/joeyw) added `.all_users` and `.all_repositories`
6
+ * [@joeyw](https://github.com/joeyw) added `.issues_comments` and `.pull_request_comments`
7
+ * [@x3ro](https://github.com/x3ro) added some date parsing to Commits API
8
+ * .netrc support
9
+
10
+ View [the full changelog][1.20.0].
11
+ [1.20.0]: https://github.com/pengwynn/octokit/compare/v1.19.0...v1.20.0
12
+
13
+
3
14
  # 1.19.0
4
15
 
5
16
  This version has some substantial rewiring internally to support non-JSON
data/README.md CHANGED
@@ -61,13 +61,30 @@ client = Octokit::Client.new(:login => "me", :password => "sekret")
61
61
  client.follow("sferik")
62
62
  ```
63
63
 
64
- Alternately, you can authenticate with a [GitHub OAuth2 token][oauth].
64
+ Alternately, you can authenticate with a [GitHub OAuth2 token][oauth].
65
65
 
66
66
  ```ruby
67
67
  client = Octokit::Client.new(:login => "me", :oauth_token => "oauth2token")
68
68
  client.follow("sferik")
69
69
  ```
70
70
 
71
+ ### Using `.netrc` for stored credentials
72
+
73
+ Octokit now supports [`.netrc`][netrc] files for storing your GitHub Basic Auth
74
+ credentials. Given a `~/.netrc` like the following
75
+
76
+ ```
77
+ machine api.github.com login pengwynn password 0ct0c4tz4ev3r!
78
+ ```
79
+
80
+ You can make authenticated calls by telling Octokit to use credentials from
81
+ this file:
82
+
83
+ ```ruby
84
+ Octokit.netrc => true # or /path/to/file
85
+ Octokit.user # authenticates as 'pengwynn' user
86
+ ```
87
+
71
88
  ## Requesting a specific media type
72
89
 
73
90
  You can pass an `:accept` option value to request a particular [media
@@ -130,6 +147,22 @@ implementation, you will be personally responsible for providing patches in a
130
147
  timely fashion. If critical issues for a particular implementation exist at the
131
148
  time of a major release, support for that Ruby version may be dropped.
132
149
 
150
+ ## Versioning
151
+
152
+ This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations
153
+ of this scheme should be reported as bugs. Specifically, if a minor or patch
154
+ version is released that breaks backward compatibility, that version should be
155
+ immediately yanked and/or a new version should be immediately released that
156
+ restores compatibility. Breaking changes to the public API will only be
157
+ introduced with new major versions. As a result of this policy, you can (and
158
+ should) specify a dependency on this gem using the [Pessimistic Version
159
+ Constraint][pvc] with two digits of precision. For example:
160
+
161
+ spec.add_dependency 'octokit', '~> 1.0'
162
+
163
+ [semver]: http://semver.org/
164
+ [pvc]: http://docs.rubygems.org/read/chapter/16#page74
165
+
133
166
  ### JSON dependency
134
167
 
135
168
  Since JSON is included in 1.9 now, we no longer include it as a hard
@@ -162,3 +195,4 @@ Copyright (c) 2011 Wynn Netherland, Adam Stacoviak, Erik Michaels-Ober. See
162
195
  [license]: https://github.com/pengwynn/octokit/blob/master/LICENSE.md
163
196
  [media-types]: http://developer.github.com/v3/media/
164
197
  [oauth]: http://developer.github.com/v3/oauth
198
+ [netrc]: http://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-File.html
@@ -4,29 +4,22 @@ require 'multi_json'
4
4
  # @api private
5
5
  module Faraday
6
6
  class Response::RaiseOctokitError < Response::Middleware
7
+ ERROR_MAP = {
8
+ 400 => Octokit::BadRequest,
9
+ 401 => Octokit::Unauthorized,
10
+ 403 => Octokit::Forbidden,
11
+ 404 => Octokit::NotFound,
12
+ 406 => Octokit::NotAcceptable,
13
+ 422 => Octokit::UnprocessableEntity,
14
+ 500 => Octokit::InternalServerError,
15
+ 501 => Octokit::NotImplemented,
16
+ 502 => Octokit::BadGateway,
17
+ 503 => Octokit::ServiceUnavailable
18
+ }
19
+
7
20
  def on_complete(response)
8
- case response[:status].to_i
9
- when 400
10
- raise Octokit::BadRequest, error_message(response)
11
- when 401
12
- raise Octokit::Unauthorized, error_message(response)
13
- when 403
14
- raise Octokit::Forbidden, error_message(response)
15
- when 404
16
- raise Octokit::NotFound, error_message(response)
17
- when 406
18
- raise Octokit::NotAcceptable, error_message(response)
19
- when 422
20
- raise Octokit::UnprocessableEntity, error_message(response)
21
- when 500
22
- raise Octokit::InternalServerError, error_message(response)
23
- when 501
24
- raise Octokit::NotImplemented, error_message(response)
25
- when 502
26
- raise Octokit::BadGateway, error_message(response)
27
- when 503
28
- raise Octokit::ServiceUnavailable, error_message(response)
29
- end
21
+ key = response[:status].to_i
22
+ raise ERROR_MAP[key], error_message(response) if ERROR_MAP.has_key? key
30
23
  end
31
24
 
32
25
  def error_message(response)
data/lib/octokit.rb CHANGED
@@ -1,6 +1,7 @@
1
+ require 'netrc'
1
2
  require 'octokit/configuration'
2
- require 'octokit/client'
3
3
  require 'octokit/error'
4
+ require 'octokit/client'
4
5
 
5
6
  module Octokit
6
7
  extend Configuration
@@ -26,5 +26,20 @@ module Octokit
26
26
  :client_secret => client_secret
27
27
  }
28
28
  end
29
+
30
+ def login_and_password_from_netrc(rc = false)
31
+ return unless rc
32
+
33
+ info = case rc
34
+ when TrueClass
35
+ Netrc.read
36
+ when String
37
+ Netrc.read rc
38
+ end
39
+ netrc_host = URI.parse(api_endpoint).host
40
+ creds = info[netrc_host]
41
+ self.login = creds.shift
42
+ self.password = creds.shift
43
+ end
29
44
  end
30
45
  end
@@ -27,6 +27,7 @@ require 'octokit/client/emojis'
27
27
  require 'octokit/client/statuses'
28
28
  require 'octokit/client/say'
29
29
  require 'octokit/client/rate_limit'
30
+ require 'octokit/client/gitignore'
30
31
 
31
32
  module Octokit
32
33
  class Client
@@ -37,6 +38,8 @@ module Octokit
37
38
  Configuration::VALID_OPTIONS_KEYS.each do |key|
38
39
  send("#{key}=", options[key])
39
40
  end
41
+
42
+ login_and_password_from_netrc(options[:netrc])
40
43
  end
41
44
 
42
45
  include Octokit::Authentication
@@ -66,5 +69,6 @@ module Octokit
66
69
  include Octokit::Client::Statuses
67
70
  include Octokit::Client::Say
68
71
  include Octokit::Client::RateLimit
72
+ include Octokit::Client::Gitignore
69
73
  end
70
74
  end
@@ -93,7 +93,7 @@ module Octokit
93
93
  # client = Octokit::Client.new(:login => 'ctshryock', :password => 'secret')
94
94
  # client.delete_authorization(999999)
95
95
  def delete_authorization(number, option={})
96
- request(:delete, "authorizations/#{number}").status == 204
96
+ boolean_from_response(:delete, "authorizations/#{number}")
97
97
  end
98
98
 
99
99
  # Check scopes for a token
@@ -136,7 +136,7 @@ module Octokit
136
136
  # @return [nil] nil
137
137
  # @see http://developer.github.com/v3/repos/comments/
138
138
  def delete_commit_comment(repo, id, options={})
139
- request(:delete, "repos/#{Repository.new(repo)}/comments/#{id}", options).status == 204
139
+ boolean_from_response(:delete, "repos/#{Repository.new(repo)}/comments/#{id}", options)
140
140
  end
141
141
 
142
142
  # Compare two commits
@@ -178,13 +178,7 @@ module Octokit
178
178
  # @example
179
179
  # Octokit.commits_since('pengwynn/octokit', '2012-10-01')
180
180
  def commits_since(repo, date, sha_or_branch="master", options={})
181
- begin
182
- date = DateTime.parse(date)
183
- rescue ArgumentError
184
- raise ArgumentError, "#{date} is not a valid date"
185
- end
186
-
187
- params = {:since => iso8601(date) }
181
+ params = {:since => iso8601(parse_date(date))}
188
182
  commits(repo, sha_or_branch, params.merge(options))
189
183
  end
190
184
 
@@ -198,12 +192,7 @@ module Octokit
198
192
  # @example
199
193
  # Octokit.commits_before('pengwynn/octokit', '2012-10-01')
200
194
  def commits_before(repo, date, sha_or_branch="master", options={})
201
- begin
202
- date = DateTime.parse(date)
203
- rescue ArgumentError
204
- raise ArgumentError, "#{date} is not a valid date"
205
- end
206
- params = {:until => iso8601(date)}
195
+ params = {:until => iso8601(parse_date(date))}
207
196
  commits(repo, sha_or_branch, params.merge(options))
208
197
  end
209
198
 
@@ -272,6 +261,18 @@ module Octokit
272
261
  end
273
262
  end
274
263
 
264
+ # Parses the given string representation of a date, throwing a meaningful exception
265
+ # (containing the date that failed to parse) in case of failure.
266
+ #
267
+ # @param date [String] String representation of a date
268
+ # @return [DateTime]
269
+ def parse_date(date)
270
+ begin
271
+ date = DateTime.parse(date)
272
+ rescue ArgumentError
273
+ raise ArgumentError, "#{date} is not a valid date"
274
+ end
275
+ end
275
276
  end
276
277
  end
277
278
  end
@@ -2,49 +2,49 @@ module Octokit
2
2
  class Client
3
3
  module Contents
4
4
 
5
- # Receive the default Readme for a repository
6
- #
7
- # @param repo [String, Repository, Hash] A GitHub repository
8
- # @param ref [String] The String name of the Commit/Branch/Tag. Defaults to “master”.
9
- # @option options [String] :ref name of the Commit/Branch/Tag. Defaults to “master”.
10
- # @return [Hash] The detail of the readme
11
- # @see http://developer.github.com/v3/repos/contents/
12
- # @example Get the readme file for a repo
13
- # Octokit.readme("pengwynn/octokit")
14
- def readme(repo, options={})
15
- get("repos/#{Repository.new repo}/readme", options)
16
- end
5
+ # Receive the default Readme for a repository
6
+ #
7
+ # @param repo [String, Repository, Hash] A GitHub repository
8
+ # @option options [String] :ref name of the Commit/Branch/Tag. Defaults to “master”.
9
+ # @return [Hash] The detail of the readme
10
+ # @see http://developer.github.com/v3/repos/contents/
11
+ # @example Get the readme file for a repo
12
+ # Octokit.readme("pengwynn/octokit")
13
+ def readme(repo, options={})
14
+ get("repos/#{Repository.new repo}/readme", options)
15
+ end
17
16
 
18
- # Receive a listing of a repository folder or the contents of a file
19
- #
20
- # @param repo [String, Repository, Hash] A GitHub repository
21
- # @option options [String] :path A folder or file path
22
- # @option options [String] :ref name of the Commit/Branch/Tag. Defaults to “master”.
23
- # @return [Hash] The contents of a file or list of the files in the folder
24
- # @see http://developer.github.com/v3/repos/contents/
25
- # @example List the contents of lib/octokit.rb
26
- # Octokit.contents("pengwynn/octokit", :path => 'lib/octokit.rb')
27
- def contents(repo, options={})
28
- repo_path = options.delete :path
29
- url = "repos/#{Repository.new repo}/contents/#{repo_path}"
30
- get(url, options)
31
- end
17
+ # Receive a listing of a repository folder or the contents of a file
18
+ #
19
+ # @param repo [String, Repository, Hash] A GitHub repository
20
+ # @option options [String] :path A folder or file path
21
+ # @option options [String] :ref name of the Commit/Branch/Tag. Defaults to “master”.
22
+ # @return [Hash] The contents of a file or list of the files in the folder
23
+ # @see http://developer.github.com/v3/repos/contents/
24
+ # @example List the contents of lib/octokit.rb
25
+ # Octokit.contents("pengwynn/octokit", :path => 'lib/octokit.rb')
26
+ def contents(repo, options={})
27
+ repo_path = options.delete :path
28
+ url = "repos/#{Repository.new repo}/contents/#{repo_path}"
29
+ get(url, options)
30
+ end
32
31
 
33
- # This method will provide a URL to download a tarball or zipball archive for a repository.
34
- #
35
- # @param repo [String, Repository, Hash] A GitHub repository.
36
- # @option options format [String] Either tarball (default) or zipball.
37
- # @option options [String] :ref Optional valid Git reference, defaults to master.
38
- # @return [String] Location of the download
39
- # @see http://developer.github.com/v3/repos/contents/
40
- # @example Get archive link for pengwynn/octokit
41
- # Octokit.archive_link("pengwynn/octokit")
42
- def archive_link(repo, options={})
43
- repo_ref = options.delete :ref
44
- format = (options.delete :format) || 'tarball'
45
- url = "repos/#{Repository.new repo}/#{format}/#{repo_ref}"
46
- request(:head, url, options).env[:url].to_s
47
- end
32
+ # This method will provide a URL to download a tarball or zipball archive for a repository.
33
+ #
34
+ # @param repo [String, Repository, Hash] A GitHub repository.
35
+ # @option options format [String] Either tarball (default) or zipball.
36
+ # @option options [String] :ref Optional valid Git reference, defaults to master.
37
+ # @return [String] Location of the download
38
+ # @see http://developer.github.com/v3/repos/contents/
39
+ # @example Get archive link for pengwynn/octokit
40
+ # Octokit.archive_link("pengwynn/octokit")
41
+ def archive_link(repo, options={})
42
+ repo_ref = options.delete :ref
43
+ format = (options.delete :format) || 'tarball'
44
+ url = "repos/#{Repository.new repo}/#{format}/#{repo_ref}"
45
+ request(:head, url, options).env[:url].to_s
46
+ end
47
+
48
+ end
48
49
  end
49
50
  end
50
- end
@@ -6,6 +6,7 @@ module Octokit
6
6
  #
7
7
  # @param repo [String, Repository, Hash] A Github Repository
8
8
  # @return [Array] A list of available downloads
9
+ # @deprecated As of December 11th, 2012: https://github.com/blog/1302-goodbye-uploads
9
10
  # @see http://developer.github.com/v3/repos/downloads/#list-downloads-for-a-repository
10
11
  # @example List all downloads for Github/Hubot
11
12
  # Octokit.downloads("github/hubot")
@@ -19,6 +20,7 @@ module Octokit
19
20
  # @param repo [String, Repository, Hash] A GitHub repository
20
21
  # @param id [Integer] ID of the download
21
22
  # @return [Download] A single download from the repository
23
+ # @deprecated As of December 11th, 2012: https://github.com/blog/1302-goodbye-uploads
22
24
  # @see http://developer.github.com/v3/repos/downloads/#get-a-single-download
23
25
  # @example Get the "Robawt" download from Github/Hubot
24
26
  # Octokit.download("github/hubot")
@@ -33,6 +35,7 @@ module Octokit
33
35
  # @option options [String] :description The download description
34
36
  # @option options [String] :content_type The content type. Defaults to 'text/plain'
35
37
  # @return [Download] A single download from the repository
38
+ # @deprecated As of December 11th, 2012: https://github.com/blog/1302-goodbye-uploads
36
39
  # @see http://developer.github.com/v3/repos/downloads/#create-a-new-download-part-1-create-the-resource
37
40
  # @example Create the "Robawt" download on Github/Hubot
38
41
  # Octokit.create_download("github/hubot", 'Robawt')
@@ -67,12 +70,13 @@ module Octokit
67
70
  #
68
71
  # @param repo [String, Repository, Hash] A GitHub repository
69
72
  # @param id [Integer] ID of the download
73
+ # @deprecated As of December 11th, 2012: https://github.com/blog/1302-goodbye-uploads
70
74
  # @see http://developer.github.com/v3/repos/downloads/#delete-a-single-download
71
75
  # @return [Boolean] Status
72
76
  # @example Get the "Robawt" download from Github/Hubot
73
77
  # Octokit.delete_download("github/hubot", 1234)
74
78
  def delete_download(repo, id)
75
- request(:delete, "repos/#{Repository.new(repo)}/downloads/#{id}").status == 204
79
+ boolean_from_response(:delete, "repos/#{Repository.new(repo)}/downloads/#{id}")
76
80
  end
77
81
 
78
82
  private
@@ -86,7 +86,7 @@ module Octokit
86
86
  # @return [Boolean] Indicates if gist is starred successfully
87
87
  # @see http://developer.github.com/v3/gists/#star-a-gist
88
88
  def star_gist(gist, options={})
89
- request(:put, "gists/#{Gist.new gist}/star", options).status == 204
89
+ boolean_from_response(:put, "gists/#{Gist.new gist}/star", options)
90
90
  end
91
91
 
92
92
  # Unstar a gist
@@ -95,7 +95,7 @@ module Octokit
95
95
  # @return [Boolean] Indicates if gist is unstarred successfully
96
96
  # @see http://developer.github.com/v3/gists/#unstar-a-gist
97
97
  def unstar_gist(gist, options={})
98
- request(:delete, "gists/#{Gist.new gist}/star", options).status == 204
98
+ boolean_from_response(:delete, "gists/#{Gist.new gist}/star", options)
99
99
  end
100
100
 
101
101
  # Check if a gist is starred
@@ -104,12 +104,7 @@ module Octokit
104
104
  # @return [Boolean] Indicates if gist is starred
105
105
  # @see http://developer.github.com/v3/gists/#check-if-a-gist-is-starred
106
106
  def gist_starred?(gist, options={})
107
- begin
108
- get("gists/#{Gist.new gist}/star", options)
109
- return true
110
- rescue Octokit::NotFound
111
- return false
112
- end
107
+ boolean_from_response(:get, "gists/#{Gist.new gist}/star", options)
113
108
  end
114
109
 
115
110
  # Fork a gist
@@ -118,7 +113,7 @@ module Octokit
118
113
  # @return [Hashie::Mash] Data for the new gist
119
114
  # @see http://developer.github.com/v3/gists/#fork-a-gist
120
115
  def fork_gist(gist, options={})
121
- post "gists/#{Gist.new gist}/fork", options
116
+ post "gists/#{Gist.new gist}/forks", options
122
117
  end
123
118
 
124
119
  # Delete a gist
@@ -127,8 +122,7 @@ module Octokit
127
122
  # @return [Boolean] Indicating success of deletion
128
123
  # @see http://developer.github.com/v3/gists/#delete-a-gist
129
124
  def delete_gist(gist, options={})
130
- response = request(:delete, "gists/#{Gist.new gist}", options)
131
- response.status == 204
125
+ boolean_from_response(:delete, "gists/#{Gist.new gist}", options)
132
126
  end
133
127
 
134
128
  # List gist comments
@@ -199,7 +193,7 @@ module Octokit
199
193
  # @example
200
194
  # @client.delete_gist_comment('208sdaz3', '586399')
201
195
  def delete_gist_comment(gist_id, gist_comment_id, options={})
202
- request(:delete, "gists/#{gist_id}/comments/#{gist_comment_id}", options).status == 204
196
+ boolean_from_response(:delete, "gists/#{gist_id}/comments/#{gist_comment_id}", options)
203
197
  end
204
198
 
205
199
  end
@@ -0,0 +1,41 @@
1
+ module Octokit
2
+ class Client
3
+ module Gitignore
4
+
5
+ # Listing available gitignore templates.
6
+ #
7
+ # These templates can be passed option when creating a repository.
8
+ #
9
+ # @see http://developer.github.com/v3/gitignore/#listing-available-templates
10
+ # @see http://developer.github.com/v3/repos/#create
11
+ #
12
+ # @return [Array<String>] List of templates.
13
+ #
14
+ # @example Git all the gitignore templates
15
+ # @client.gitignore_templates
16
+ def gitignore_templates(options={})
17
+ get "/gitignore/templates", options
18
+ end
19
+
20
+ # Get a gitignore template.
21
+ #
22
+ # Use the raw {http://developer.github.com/v3/media/ media type} to get
23
+ # the raw contents.
24
+ #
25
+ # @param template_name [String] Name of the template. Template names are
26
+ # case sensitive, make sure to use a valid name from the
27
+ # .gitignore_templates list.
28
+ #
29
+ # @see http://developer.github.com/v3/gitignore/#get-a-single-template
30
+ #
31
+ # @return [Hash] Gitignore template
32
+ #
33
+ # @example Get the Ruby gitignore template
34
+ # @client.gitignore_template('Ruby')
35
+ def gitignore_template(template_name, options={})
36
+ get "/gitignore/templates/#{template_name}", options
37
+ end
38
+
39
+ end
40
+ end
41
+ end