octokit 1.19.0 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
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