octokit 4.6.2 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTING.md +14 -13
  3. data/LICENSE.md +1 -1
  4. data/README.md +239 -118
  5. data/Rakefile +12 -12
  6. data/lib/ext/sawyer/relation.rb +4 -2
  7. data/lib/octokit/arguments.rb +2 -2
  8. data/lib/octokit/authentication.rb +20 -14
  9. data/lib/octokit/client/actions_artifacts.rb +71 -0
  10. data/lib/octokit/client/actions_secrets.rb +59 -0
  11. data/lib/octokit/client/actions_workflow_jobs.rb +65 -0
  12. data/lib/octokit/client/actions_workflow_runs.rb +125 -0
  13. data/lib/octokit/client/actions_workflows.rb +68 -0
  14. data/lib/octokit/client/apps.rb +222 -0
  15. data/lib/octokit/client/checks.rb +200 -0
  16. data/lib/octokit/client/commit_branches.rb +20 -0
  17. data/lib/octokit/client/commit_comments.rb +8 -8
  18. data/lib/octokit/client/commit_pulls.rb +20 -0
  19. data/lib/octokit/client/commits.rb +31 -34
  20. data/lib/octokit/client/community_profile.rb +21 -0
  21. data/lib/octokit/client/contents.rb +25 -20
  22. data/lib/octokit/client/deployments.rb +25 -5
  23. data/lib/octokit/client/downloads.rb +5 -6
  24. data/lib/octokit/client/emojis.rb +3 -3
  25. data/lib/octokit/client/environments.rb +55 -0
  26. data/lib/octokit/client/events.rb +4 -4
  27. data/lib/octokit/client/feeds.rb +4 -5
  28. data/lib/octokit/client/gists.rb +7 -6
  29. data/lib/octokit/client/gitignore.rb +3 -3
  30. data/lib/octokit/client/hooks.rb +9 -19
  31. data/lib/octokit/client/issues.rb +60 -14
  32. data/lib/octokit/client/labels.rb +17 -17
  33. data/lib/octokit/client/legacy_search.rb +3 -3
  34. data/lib/octokit/client/licenses.rb +4 -7
  35. data/lib/octokit/client/markdown.rb +3 -3
  36. data/lib/octokit/client/marketplace.rb +56 -0
  37. data/lib/octokit/client/meta.rb +4 -5
  38. data/lib/octokit/client/milestones.rb +5 -5
  39. data/lib/octokit/client/notifications.rb +6 -10
  40. data/lib/octokit/client/oauth_applications.rb +116 -0
  41. data/lib/octokit/client/objects.rb +14 -14
  42. data/lib/octokit/client/organizations.rb +238 -61
  43. data/lib/octokit/client/pages.rb +5 -7
  44. data/lib/octokit/client/projects.rb +50 -70
  45. data/lib/octokit/client/pub_sub_hubbub.rb +16 -16
  46. data/lib/octokit/client/pull_requests.rb +58 -46
  47. data/lib/octokit/client/rate_limit.rb +11 -13
  48. data/lib/octokit/client/reactions.rb +6 -11
  49. data/lib/octokit/client/refs.rb +32 -19
  50. data/lib/octokit/client/releases.rb +14 -13
  51. data/lib/octokit/client/repositories.rb +195 -54
  52. data/lib/octokit/client/repository_invitations.rb +4 -11
  53. data/lib/octokit/client/reviews.rb +227 -0
  54. data/lib/octokit/client/say.rb +4 -5
  55. data/lib/octokit/client/search.rb +46 -17
  56. data/lib/octokit/client/service_status.rb +19 -9
  57. data/lib/octokit/client/source_import.rb +8 -13
  58. data/lib/octokit/client/stats.rb +12 -9
  59. data/lib/octokit/client/statuses.rb +6 -6
  60. data/lib/octokit/client/tokens.rb +31 -0
  61. data/lib/octokit/client/traffic.rb +6 -11
  62. data/lib/octokit/client/users.rb +106 -25
  63. data/lib/octokit/client.rb +66 -17
  64. data/lib/octokit/configurable.rb +42 -30
  65. data/lib/octokit/connection.rb +43 -21
  66. data/lib/octokit/default.rb +63 -34
  67. data/lib/octokit/enterprise_admin_client/admin_stats.rb +14 -15
  68. data/lib/octokit/enterprise_admin_client/license.rb +4 -5
  69. data/lib/octokit/enterprise_admin_client/orgs.rb +5 -6
  70. data/lib/octokit/enterprise_admin_client/search_indexing.rb +8 -9
  71. data/lib/octokit/enterprise_admin_client/users.rb +17 -16
  72. data/lib/octokit/enterprise_admin_client.rb +9 -3
  73. data/lib/octokit/enterprise_management_console_client/management_console.rb +33 -33
  74. data/lib/octokit/enterprise_management_console_client.rb +9 -3
  75. data/lib/octokit/error.rb +107 -26
  76. data/lib/octokit/gist.rb +4 -5
  77. data/lib/octokit/middleware/follow_redirects.rb +17 -13
  78. data/lib/octokit/organization.rb +3 -1
  79. data/lib/octokit/rate_limit.rb +11 -9
  80. data/lib/octokit/repo_arguments.rb +2 -3
  81. data/lib/octokit/repository.rb +27 -25
  82. data/lib/octokit/response/base_middleware.rb +10 -0
  83. data/lib/octokit/response/feed_parser.rb +5 -9
  84. data/lib/octokit/response/raise_error.rb +4 -6
  85. data/lib/octokit/user.rb +4 -2
  86. data/lib/octokit/version.rb +5 -3
  87. data/lib/octokit/warnable.rb +4 -5
  88. data/lib/octokit.rb +15 -8
  89. data/octokit.gemspec +13 -10
  90. metadata +55 -22
  91. data/lib/octokit/client/authorizations.rb +0 -244
  92. data/lib/octokit/preview.rb +0 -35
@@ -1,28 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Octokit
2
4
  class EnterpriseAdminClient
3
-
4
5
  # Methods for the Enterprise User Administration API
5
6
  #
6
- # @see https://developer.github.com/v3/users/administration/
7
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/
7
8
  module Users
8
9
  # Create a new user.
9
10
  #
10
11
  # @param login [String] The user's username.
11
12
  # @param email [String] The user's email address.
12
- # @see https://developer.github.com/v3/users/administration/#create-a-new-user
13
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users#create-a-new-user
13
14
  # @example
14
15
  # @admin_client.create_user('foobar', 'notreal@foo.bar')
15
16
  def create_user(login, email, options = {})
16
17
  options[:login] = login
17
18
  options[:email] = email
18
- post "admin/users", options
19
+ post 'admin/users', options
19
20
  end
20
21
 
21
22
  # Promote an ordinary user to a site administrator
22
23
  #
23
24
  # @param user [String] Username of the user to promote.
24
25
  # @return [Boolean] True if promote was successful, false otherwise.
25
- # @see https://developer.github.com/v3/users/administration/#promote-an-ordinary-user-to-a-site-administrator
26
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#promote-an-ordinary-user-to-a-site-administrator
26
27
  # @example
27
28
  # @admin_client.promote('holman')
28
29
  def promote(user, options = {})
@@ -33,7 +34,7 @@ module Octokit
33
34
  #
34
35
  # @param user [String] Username of the user to demote.
35
36
  # @return [Boolean] True if demote was successful, false otherwise.
36
- # @see https://developer.github.com/v3/users/administration/#demote-a-site-administrator-to-an-ordinary-user
37
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#demote-a-site-administrator-to-an-ordinary-user
37
38
  # @example
38
39
  # @admin_client.demote('holman')
39
40
  def demote(user, options = {})
@@ -44,7 +45,7 @@ module Octokit
44
45
  #
45
46
  # @param old_login [String] The user's old username.
46
47
  # @param new_login [String] The user's new username.
47
- # @see https://developer.github.com/v3/users/administration/#rename-an-existing-user
48
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#rename-an-existing-user
48
49
  # @example
49
50
  # @admin_client.rename_user('foobar', 'foofoobar')
50
51
  def rename_user(old_login, new_login, options = {})
@@ -55,7 +56,7 @@ module Octokit
55
56
  # Deletes a user.
56
57
  #
57
58
  # @param username [String] The username to delete.
58
- # @see https://developer.github.com/v3/users/administration/#delete-a-user
59
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-a-user
59
60
  # @example
60
61
  # @admin_client.delete_key(1)
61
62
  def delete_user(username, options = {})
@@ -66,7 +67,7 @@ module Octokit
66
67
  #
67
68
  # @param user [String] Username of the user to suspend.
68
69
  # @return [Boolean] True if suspend was successful, false otherwise.
69
- # @see https://developer.github.com/v3/users/administration/#suspend-a-user
70
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#suspend-a-user
70
71
  # @example
71
72
  # @admin_client.suspend('holman')
72
73
  def suspend(user, options = {})
@@ -77,7 +78,7 @@ module Octokit
77
78
  #
78
79
  # @param user [String] Username of the user to unsuspend.
79
80
  # @return [Boolean] True if unsuspend was successful, false otherwise.
80
- # @see https://developer.github.com/v3/users/administration/#unsuspend-a-user
81
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#unsuspend-a-user
81
82
  # @example
82
83
  # @admin_client.unsuspend('holman')
83
84
  def unsuspend(user, options = {})
@@ -88,7 +89,7 @@ module Octokit
88
89
  #
89
90
  # @param login [String] The user to create a token for.
90
91
  # @param options [Array<String>] :scopes The scopes to apply.
91
- # @see https://developer.github.com/v3/users/administration/#create-an-impersonation-oauth-token
92
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token
92
93
  # @example
93
94
  # @admin_client.create_impersonation_token('foobar', {:scopes => ['repo:write']})
94
95
  def create_impersonation_token(login, options = {})
@@ -98,7 +99,7 @@ module Octokit
98
99
  # Deletes an impersonation OAuth token.
99
100
  #
100
101
  # @param login [String] The user whose token should be deleted.
101
- # @see https://developer.github.com/v3/users/administration/#delete-an-impersonation-oauth-token
102
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-an-impersonation-oauth-token
102
103
  # @example
103
104
  # @admin_client.delete_impersonation_token('foobar')
104
105
  def delete_impersonation_token(login, options = {})
@@ -107,21 +108,21 @@ module Octokit
107
108
 
108
109
  # Lists all the public SSH keys.
109
110
  #
110
- # @see https://developer.github.com/v3/users/administration/#list-all-public-keys
111
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#list-all-public-keys
111
112
  # @example
112
113
  # @admin_client.list_all_keys
113
114
  def list_all_keys(options = {})
114
- get "admin/keys", options
115
+ get 'admin/keys', options
115
116
  end
116
117
 
117
118
  # Deletes a public SSH keys.
118
119
  #
119
120
  # @param id [Number] The ID of the key to delete.
120
- # @see https://developer.github.com/v3/users/administration/#delete-a-public-key
121
+ # @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-a-public-key
121
122
  # @example
122
123
  # @admin_client.delete_key(1)
123
124
  def delete_key(id, options = {})
124
- boolean_from_response :delete, "admin/keys/#{id}", options
125
+ boolean_from_response :delete, "admin/keys/#{id}", options
125
126
  end
126
127
  end
127
128
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'octokit/connection'
2
4
  require 'octokit/configurable'
3
5
  require 'octokit/warnable'
@@ -8,7 +10,6 @@ require 'octokit/enterprise_admin_client/search_indexing'
8
10
  require 'octokit/enterprise_admin_client/users'
9
11
 
10
12
  module Octokit
11
-
12
13
  # EnterpriseAdminClient is only meant to be used by GitHub Enterprise Admins
13
14
  # and provides access the Admin only API endpoints including Admin Stats,
14
15
  # Management Console, and the Search Indexing API.
@@ -17,7 +18,6 @@ module Octokit
17
18
  # and GitHub Enterprise.
18
19
  # @see https://developer.github.com/v3/enterprise/
19
20
  class EnterpriseAdminClient
20
-
21
21
  include Octokit::Configurable
22
22
  include Octokit::Connection
23
23
  include Octokit::Warnable
@@ -29,12 +29,18 @@ module Octokit
29
29
 
30
30
  def initialize(options = {})
31
31
  # Use options passed in, but fall back to module defaults
32
+ #
33
+ # rubocop:disable Style/HashEachMethods
34
+ #
35
+ # This may look like a `.keys.each` which should be replaced with `#each_key`, but
36
+ # this doesn't actually work, since `#keys` is just a method we've defined ourselves.
37
+ # The class doesn't fulfill the whole `Enumerable` contract.
32
38
  Octokit::Configurable.keys.each do |key|
39
+ # rubocop:enable Style/HashEachMethods
33
40
  instance_variable_set(:"@#{key}", options[key] || Octokit.instance_variable_get(:"@#{key}"))
34
41
  end
35
42
 
36
43
  login_from_netrc unless user_authenticated? || application_authenticated?
37
44
  end
38
-
39
45
  end
40
46
  end
@@ -1,34 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Octokit
2
4
  class EnterpriseManagementConsoleClient
3
-
4
5
  # Methods for the Enterprise Management Console API
5
6
  #
6
- # @see https://developer.github.com/v3/enterprise/management_console
7
+ # @see https://developer.github.com/v3/enterprise-admin/management_console/
7
8
  module ManagementConsole
8
-
9
9
  # Uploads a license for the first time
10
10
  #
11
11
  # @param license [String] The path to your .ghl license file.
12
12
  # @param settings [Hash] A hash configuration of the initial settings.
13
13
  #
14
- # @see http: //git.io/j5NT
14
+ # @see https://docs.github.com/en/enterprise-server@3.4/rest/enterprise-admin/management-console#create-a-github-license
15
15
  # @return nil
16
16
  def upload_license(license, settings = nil)
17
17
  conn = faraday_configuration
18
18
 
19
- params = { }
19
+ params = {}
20
20
  params[:license] = Faraday::UploadIO.new(license, 'binary')
21
21
  params[:password] = @management_console_password
22
- params[:settings] = "#{settings.to_json}" unless settings.nil?
22
+ params[:settings] = settings.to_json.to_s unless settings.nil?
23
23
 
24
- @last_response = conn.post("/setup/api/start", params)
24
+ @last_response = conn.post('/setup/api/start', params)
25
25
  end
26
26
 
27
27
  # Start a configuration process.
28
28
  #
29
29
  # @return nil
30
30
  def start_configuration
31
- post "/setup/api/configure", password_hash
31
+ post '/setup/api/configure', password_hash
32
32
  end
33
33
 
34
34
  # Upgrade an Enterprise installation
@@ -39,27 +39,27 @@ module Octokit
39
39
  def upgrade(license)
40
40
  conn = faraday_configuration
41
41
 
42
- params = { }
42
+ params = {}
43
43
  params[:license] = Faraday::UploadIO.new(license, 'binary')
44
44
  params[:api_key] = @management_console_password
45
- @last_response = conn.post("/setup/api/upgrade", params)
45
+ @last_response = conn.post('/setup/api/upgrade', params)
46
46
  end
47
47
 
48
48
  # Get information about the Enterprise installation
49
49
  #
50
50
  # @return [Sawyer::Resource] The installation information
51
51
  def config_status
52
- get "/setup/api/configcheck", password_hash
52
+ get '/setup/api/configcheck', password_hash
53
53
  end
54
- alias :config_check :config_status
54
+ alias config_check config_status
55
55
 
56
56
  # Get information about the Enterprise installation
57
57
  #
58
58
  # @return [Sawyer::Resource] The settings
59
59
  def settings
60
- get "/setup/api/settings", password_hash
60
+ get '/setup/api/settings', password_hash
61
61
  end
62
- alias :get_settings :settings
62
+ alias get_settings settings
63
63
 
64
64
  # Modify the Enterprise settings
65
65
  #
@@ -68,17 +68,17 @@ module Octokit
68
68
  # @return [nil]
69
69
  def edit_settings(settings)
70
70
  queries = password_hash
71
- queries[:query][:settings] = "#{settings.to_json}"
72
- put "/setup/api/settings", queries
71
+ queries[:query][:settings] = settings.to_json.to_s
72
+ put '/setup/api/settings', queries
73
73
  end
74
74
 
75
75
  # Get information about the Enterprise maintenance status
76
76
  #
77
77
  # @return [Sawyer::Resource] The maintenance status
78
78
  def maintenance_status
79
- get "/setup/api/maintenance", password_hash
79
+ get '/setup/api/maintenance', password_hash
80
80
  end
81
- alias :get_maintenance_status :maintenance_status
81
+ alias get_maintenance_status maintenance_status
82
82
 
83
83
  # Start (or turn off) the Enterprise maintenance mode
84
84
  #
@@ -86,18 +86,18 @@ module Octokit
86
86
  # @return [nil]
87
87
  def set_maintenance_status(maintenance)
88
88
  queries = password_hash
89
- queries[:query][:maintenance] = "#{maintenance.to_json}"
90
- post "/setup/api/maintenance", queries
89
+ queries[:query][:maintenance] = maintenance.to_json.to_s
90
+ post '/setup/api/maintenance', queries
91
91
  end
92
- alias :edit_maintenance_status :set_maintenance_status
92
+ alias edit_maintenance_status set_maintenance_status
93
93
 
94
94
  # Fetch the authorized SSH keys on the Enterprise install
95
95
  #
96
96
  # @return [Sawyer::Resource] An array of authorized SSH keys
97
97
  def authorized_keys
98
- get "/setup/api/settings/authorized-keys", password_hash
98
+ get '/setup/api/settings/authorized-keys', password_hash
99
99
  end
100
- alias :get_authorized_keys :authorized_keys
100
+ alias get_authorized_keys authorized_keys
101
101
 
102
102
  # Add an authorized SSH keys on the Enterprise install
103
103
  #
@@ -108,7 +108,7 @@ module Octokit
108
108
  case key
109
109
  when String
110
110
  if File.exist?(key)
111
- key = File.open(key, "r")
111
+ key = File.open(key, 'r')
112
112
  content = key.read.strip
113
113
  key.close
114
114
  else
@@ -120,7 +120,7 @@ module Octokit
120
120
  end
121
121
 
122
122
  queries[:query][:authorized_key] = content
123
- post "/setup/api/settings/authorized-keys", queries
123
+ post '/setup/api/settings/authorized-keys', queries
124
124
  end
125
125
 
126
126
  # Removes an authorized SSH keys from the Enterprise install
@@ -132,7 +132,7 @@ module Octokit
132
132
  case key
133
133
  when String
134
134
  if File.exist?(key)
135
- key = File.open(key, "r")
135
+ key = File.open(key, 'r')
136
136
  content = key.read.strip
137
137
  key.close
138
138
  else
@@ -144,27 +144,27 @@ module Octokit
144
144
  end
145
145
 
146
146
  queries[:query][:authorized_key] = content
147
- delete "/setup/api/settings/authorized-keys", queries
147
+ delete '/setup/api/settings/authorized-keys', queries
148
148
  end
149
- alias :delete_authorized_key :remove_authorized_key
150
-
149
+ alias delete_authorized_key remove_authorized_key
151
150
  end
151
+
152
152
  private
153
153
 
154
154
  def password_hash
155
- { :query => { :api_key => @management_console_password } }
155
+ { query: { api_key: @management_console_password } }
156
156
  end
157
157
 
158
158
  # We fall back to raw Faraday for handling the licenses because I'm suspicious
159
- # that Sawyer isn't handling binary POSTs correctly: http://git.io/jMir
159
+ # that Sawyer isn't handling binary POSTs correctly: https://github.com/lostisland/sawyer/blob/03fca4c020f465ec42856d0486ec3991859b0aed/lib/sawyer/agent.rb#L85
160
160
  def faraday_configuration
161
- @faraday_configuration ||= Faraday.new(:url => @management_console_endpoint) do |http|
161
+ @faraday_configuration ||= Faraday.new(url: @management_console_endpoint) do |http|
162
162
  http.headers[:user_agent] = user_agent
163
163
  http.request :multipart
164
164
  http.request :url_encoded
165
165
 
166
166
  # Disabling SSL is essential for certain self-hosted Enterprise instances
167
- if self.connection_options[:ssl] && !self.connection_options[:ssl][:verify]
167
+ if connection_options[:ssl] && !connection_options[:ssl][:verify]
168
168
  http.ssl[:verify] = false
169
169
  end
170
170
 
@@ -1,18 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'octokit/configurable'
2
4
  require 'octokit/connection'
3
5
  require 'octokit/warnable'
4
6
  require 'octokit/enterprise_management_console_client/management_console'
5
7
 
6
8
  module Octokit
7
-
8
9
  # EnterpriseManagementConsoleClient is only meant to be used by GitHub Enterprise Admins
9
10
  # and provides access to the management console API endpoints.
10
11
  #
11
12
  # @see Octokit::Client Use Octokit::Client for regular API use for GitHub
12
13
  # and GitHub Enterprise.
13
- # @see https://developer.github.com/v3/enterprise/management_console/
14
+ # @see https://developer.github.com/v3/enterprise-admin/management_console/
14
15
  class EnterpriseManagementConsoleClient
15
-
16
16
  include Octokit::Configurable
17
17
  include Octokit::Connection
18
18
  include Octokit::Warnable
@@ -20,7 +20,13 @@ module Octokit
20
20
 
21
21
  def initialize(options = {})
22
22
  # Use options passed in, but fall back to module defaults
23
+ # rubocop:disable Style/HashEachMethods
24
+ #
25
+ # This may look like a `.keys.each` which should be replaced with `#each_key`, but
26
+ # this doesn't actually work, since `#keys` is just a method we've defined ourselves.
27
+ # The class doesn't fulfill the whole `Enumerable` contract.
23
28
  Octokit::Configurable.keys.each do |key|
29
+ # rubocop:enable Style/HashEachMethods
24
30
  instance_variable_set(:"@#{key}", options[key] || Octokit.instance_variable_get(:"@#{key}"))
25
31
  end
26
32
  end
data/lib/octokit/error.rb CHANGED
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Octokit
2
4
  # Custom error class for rescuing from all GitHub errors
3
5
  class Error < StandardError
6
+ attr_reader :context
4
7
 
5
8
  # Returns the appropriate Octokit::Error subclass based
6
9
  # on status and response message
@@ -21,7 +24,7 @@ module Octokit
21
24
  when 406 then Octokit::NotAcceptable
22
25
  when 409 then Octokit::Conflict
23
26
  when 415 then Octokit::UnsupportedMediaType
24
- when 422 then Octokit::UnprocessableEntity
27
+ when 422 then error_for_422(body)
25
28
  when 451 then Octokit::UnavailableForLegalReasons
26
29
  when 400..499 then Octokit::ClientError
27
30
  when 500 then Octokit::InternalServerError
@@ -34,9 +37,16 @@ module Octokit
34
37
  end
35
38
  end
36
39
 
37
- def initialize(response=nil)
40
+ def build_error_context
41
+ if RATE_LIMITED_ERRORS.include?(self.class)
42
+ @context = Octokit::RateLimit.from_response(@response)
43
+ end
44
+ end
45
+
46
+ def initialize(response = nil)
38
47
  @response = response
39
48
  super(build_error_message)
49
+ build_error_context
40
50
  end
41
51
 
42
52
  # Documentation URL returned by the API for some errors
@@ -48,7 +58,9 @@ module Octokit
48
58
 
49
59
  # Returns most appropriate error for 401 HTTP status code
50
60
  # @private
61
+ # rubocop:disable Naming/VariableNumber
51
62
  def self.error_for_401(headers)
63
+ # rubocop:enbale Naming/VariableNumber
52
64
  if Octokit::OneTimePasswordRequired.required_header(headers)
53
65
  Octokit::OneTimePasswordRequired
54
66
  else
@@ -59,18 +71,28 @@ module Octokit
59
71
  # Returns most appropriate error for 403 HTTP status code
60
72
  # @private
61
73
  def self.error_for_403(body)
62
- if body =~ /rate limit exceeded/i
74
+ # rubocop:enable Naming/VariableNumber
75
+ case body
76
+ when /rate limit exceeded/i, /exceeded a secondary rate limit/i
63
77
  Octokit::TooManyRequests
64
- elsif body =~ /login attempts exceeded/i
78
+ when /login attempts exceeded/i
65
79
  Octokit::TooManyLoginAttempts
66
- elsif body =~ /abuse/i
80
+ when /(returns|for) blobs (up to|between) [0-9-]+ MB/i
81
+ Octokit::TooLargeContent
82
+ when /abuse/i
67
83
  Octokit::AbuseDetected
68
- elsif body =~ /repository access blocked/i
84
+ when /repository access blocked/i
69
85
  Octokit::RepositoryUnavailable
70
- elsif body =~ /email address must be verified/i
86
+ when /email address must be verified/i
71
87
  Octokit::UnverifiedEmail
72
- elsif body =~ /account was suspended/i
88
+ when /account was suspended/i
73
89
  Octokit::AccountSuspended
90
+ when /billing issue/i
91
+ Octokit::BillingIssue
92
+ when /Resource protected by organization SAML enforcement/i
93
+ Octokit::SAMLProtected
94
+ when /suspended your access|This installation has been suspended/i
95
+ Octokit::InstallationSuspended
74
96
  else
75
97
  Octokit::Forbidden
76
98
  end
@@ -78,7 +100,9 @@ module Octokit
78
100
 
79
101
  # Return most appropriate error for 404 HTTP status code
80
102
  # @private
103
+ # rubocop:disable Naming/VariableNumber
81
104
  def self.error_for_404(body)
105
+ # rubocop:enable Naming/VariableNumber
82
106
  if body =~ /Branch not protected/i
83
107
  Octokit::BranchNotProtected
84
108
  else
@@ -86,10 +110,24 @@ module Octokit
86
110
  end
87
111
  end
88
112
 
113
+ # Return most appropriate error for 422 HTTP status code
114
+ # @private
115
+ # rubocop:disable Naming/VariableNumber
116
+ def self.error_for_422(body)
117
+ # rubocop:enable Naming/VariableNumber
118
+ if body =~ /PullRequestReviewComment/i && body =~ /(commit_id|end_commit_oid) is not part of the pull request/i
119
+ Octokit::CommitIsNotPartOfPullRequest
120
+ elsif body =~ /Path diff too large/i
121
+ Octokit::PathDiffTooLarge
122
+ else
123
+ Octokit::UnprocessableEntity
124
+ end
125
+ end
126
+
89
127
  # Array of validation errors
90
128
  # @return [Array<Hash>] Error info
91
129
  def errors
92
- if data && data.is_a?(Hash)
130
+ if data.is_a?(Hash)
93
131
  data[:errors] || []
94
132
  else
95
133
  []
@@ -103,21 +141,33 @@ module Octokit
103
141
  @response[:status]
104
142
  end
105
143
 
144
+ # Headers returned by the GitHub server.
145
+ #
146
+ # @return [Hash]
147
+ def response_headers
148
+ @response[:response_headers]
149
+ end
150
+
151
+ # Body returned by the GitHub server.
152
+ #
153
+ # @return [String]
154
+ def response_body
155
+ @response[:body]
156
+ end
157
+
106
158
  private
107
159
 
108
160
  def data
109
161
  @data ||=
110
162
  if (body = @response[:body]) && !body.empty?
111
163
  if body.is_a?(String) &&
112
- @response[:response_headers] &&
113
- @response[:response_headers][:content_type] =~ /json/
164
+ @response[:response_headers] &&
165
+ @response[:response_headers][:content_type] =~ /json/
114
166
 
115
167
  Sawyer::Agent.serializer.decode(body)
116
168
  else
117
169
  body
118
170
  end
119
- else
120
- nil
121
171
  end
122
172
  end
123
173
 
@@ -137,9 +187,13 @@ module Octokit
137
187
  def response_error_summary
138
188
  return nil unless data.is_a?(Hash) && !Array(data[:errors]).empty?
139
189
 
140
- summary = "\nError summary:\n"
141
- summary << data[:errors].map do |hash|
142
- hash.map { |k,v| " #{k}: #{v}" }
190
+ summary = +"\nError summary:\n"
191
+ summary << data[:errors].map do |error|
192
+ if error.is_a? Hash
193
+ error.map { |k, v| " #{k}: #{v}" }
194
+ else
195
+ " #{error}"
196
+ end
143
197
  end.join("\n")
144
198
 
145
199
  summary
@@ -148,19 +202,21 @@ module Octokit
148
202
  def build_error_message
149
203
  return nil if @response.nil?
150
204
 
151
- message = "#{@response[:method].to_s.upcase} "
152
- message << redact_url(@response[:url].to_s) + ": "
205
+ message = +"#{@response[:method].to_s.upcase} "
206
+ message << "#{redact_url(@response[:url].to_s.dup)}: "
153
207
  message << "#{@response[:status]} - "
154
- message << "#{response_message}" unless response_message.nil?
155
- message << "#{response_error}" unless response_error.nil?
156
- message << "#{response_error_summary}" unless response_error_summary.nil?
208
+ message << response_message.to_s unless response_message.nil?
209
+ message << response_error.to_s unless response_error.nil?
210
+ message << response_error_summary.to_s unless response_error_summary.nil?
157
211
  message << " // See: #{documentation_url}" unless documentation_url.nil?
158
212
  message
159
213
  end
160
214
 
161
215
  def redact_url(url_string)
162
- %w[client_secret access_token].each do |token|
163
- url_string.gsub!(/#{token}=\S+/, "#{token}=(redacted)") if url_string.include? token
216
+ %w[client_secret access_token api_key].each do |token|
217
+ if url_string.include? token
218
+ url_string.gsub!(/#{token}=\S+/, "#{token}=(redacted)")
219
+ end
164
220
  end
165
221
  url_string
166
222
  end
@@ -178,10 +234,10 @@ module Octokit
178
234
  # Raised when GitHub returns a 401 HTTP status code
179
235
  # and headers include "X-GitHub-OTP"
180
236
  class OneTimePasswordRequired < ClientError
181
- #@private
182
- OTP_DELIVERY_PATTERN = /required; (\w+)/i
237
+ # @private
238
+ OTP_DELIVERY_PATTERN = /required; (\w+)/i.freeze
183
239
 
184
- #@private
240
+ # @private
185
241
  def self.required_header(headers)
186
242
  OTP_DELIVERY_PATTERN.match headers['X-GitHub-OTP'].to_s
187
243
  end
@@ -213,6 +269,10 @@ module Octokit
213
269
  # and body matches 'login attempts exceeded'
214
270
  class TooManyLoginAttempts < Forbidden; end
215
271
 
272
+ # Raised when GitHub returns a 403 HTTP status code
273
+ # and body matches 'returns blobs up to [0-9]+ MB'
274
+ class TooLargeContent < Forbidden; end
275
+
216
276
  # Raised when GitHub returns a 403 HTTP status code
217
277
  # and body matches 'abuse'
218
278
  class AbuseDetected < Forbidden; end
@@ -229,6 +289,18 @@ module Octokit
229
289
  # and body matches 'account was suspended'
230
290
  class AccountSuspended < Forbidden; end
231
291
 
292
+ # Raised when GitHub returns a 403 HTTP status code
293
+ # and body matches 'billing issue'
294
+ class BillingIssue < Forbidden; end
295
+
296
+ # Raised when GitHub returns a 403 HTTP status code
297
+ # and body matches 'Resource protected by organization SAML enforcement'
298
+ class SAMLProtected < Forbidden; end
299
+
300
+ # Raised when GitHub returns a 403 HTTP status code
301
+ # and body matches 'suspended your access'
302
+ class InstallationSuspended < Forbidden; end
303
+
232
304
  # Raised when GitHub returns a 404 HTTP status code
233
305
  class NotFound < ClientError; end
234
306
 
@@ -251,6 +323,14 @@ module Octokit
251
323
  # Raised when GitHub returns a 422 HTTP status code
252
324
  class UnprocessableEntity < ClientError; end
253
325
 
326
+ # Raised when GitHub returns a 422 HTTP status code
327
+ # and body matches 'PullRequestReviewComment' and 'commit_id (or end_commit_oid) is not part of the pull request'
328
+ class CommitIsNotPartOfPullRequest < UnprocessableEntity; end
329
+
330
+ # Raised when GitHub returns a 422 HTTP status code and body matches 'Path diff too large'.
331
+ # It could occur when attempting to post review comments on a "too large" file.
332
+ class PathDiffTooLarge < UnprocessableEntity; end
333
+
254
334
  # Raised when GitHub returns a 451 HTTP status code
255
335
  class UnavailableForLegalReasons < ClientError; end
256
336
 
@@ -279,4 +359,5 @@ module Octokit
279
359
  # Raised when a repository is created with an invalid format
280
360
  class InvalidRepository < ArgumentError; end
281
361
 
362
+ RATE_LIMITED_ERRORS = [Octokit::TooManyRequests, Octokit::AbuseDetected].freeze
282
363
  end
data/lib/octokit/gist.rb CHANGED
@@ -1,8 +1,8 @@
1
- module Octokit
1
+ # frozen_string_literal: true
2
2
 
3
+ module Octokit
3
4
  # Class to parse and create Gist URLs
4
5
  class Gist
5
-
6
6
  # !@attribute id
7
7
  # @return [String] Gist ID
8
8
  attr_accessor :id
@@ -10,12 +10,12 @@ module Octokit
10
10
  # Instantiate {Gist} object from Gist URL
11
11
  # @ return [Gist]
12
12
  def self.from_url(url)
13
- Gist.new(URI.parse(url).path[1..-1])
13
+ Gist.new(URI.parse(url).path[1..])
14
14
  end
15
15
 
16
16
  def initialize(gist)
17
17
  case gist
18
- when Fixnum, String
18
+ when Integer, String
19
19
  @id = gist.to_s
20
20
  end
21
21
  end
@@ -31,6 +31,5 @@ module Octokit
31
31
  def url
32
32
  "https://gist.github.com/#{@id}"
33
33
  end
34
-
35
34
  end
36
35
  end