octodoggy 4.6.2
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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/CONTRIBUTING.md +22 -0
- data/LICENSE.md +20 -0
- data/README.md +714 -0
- data/Rakefile +22 -0
- data/lib/ext/sawyer/relation.rb +10 -0
- data/lib/octokit.rb +59 -0
- data/lib/octokit/arguments.rb +14 -0
- data/lib/octokit/authentication.rb +82 -0
- data/lib/octokit/client.rb +238 -0
- data/lib/octokit/client/authorizations.rb +244 -0
- data/lib/octokit/client/commit_comments.rb +95 -0
- data/lib/octokit/client/commits.rb +239 -0
- data/lib/octokit/client/contents.rb +162 -0
- data/lib/octokit/client/deployments.rb +62 -0
- data/lib/octokit/client/downloads.rb +50 -0
- data/lib/octokit/client/emojis.rb +18 -0
- data/lib/octokit/client/events.rb +151 -0
- data/lib/octokit/client/feeds.rb +33 -0
- data/lib/octokit/client/gists.rb +233 -0
- data/lib/octokit/client/gitignore.rb +43 -0
- data/lib/octokit/client/hooks.rb +297 -0
- data/lib/octokit/client/integrations.rb +77 -0
- data/lib/octokit/client/issues.rb +321 -0
- data/lib/octokit/client/labels.rb +156 -0
- data/lib/octokit/client/legacy_search.rb +42 -0
- data/lib/octokit/client/licenses.rb +45 -0
- data/lib/octokit/client/markdown.rb +27 -0
- data/lib/octokit/client/meta.rb +21 -0
- data/lib/octokit/client/milestones.rb +87 -0
- data/lib/octokit/client/notifications.rb +171 -0
- data/lib/octokit/client/objects.rb +141 -0
- data/lib/octokit/client/organizations.rb +768 -0
- data/lib/octokit/client/pages.rb +63 -0
- data/lib/octokit/client/projects.rb +314 -0
- data/lib/octokit/client/pub_sub_hubbub.rb +111 -0
- data/lib/octokit/client/pull_requests.rb +301 -0
- data/lib/octokit/client/rate_limit.rb +54 -0
- data/lib/octokit/client/reactions.rb +158 -0
- data/lib/octokit/client/refs.rb +118 -0
- data/lib/octokit/client/releases.rb +163 -0
- data/lib/octokit/client/repositories.rb +654 -0
- data/lib/octokit/client/repository_invitations.rb +103 -0
- data/lib/octokit/client/reviews.rb +174 -0
- data/lib/octokit/client/say.rb +19 -0
- data/lib/octokit/client/search.rb +76 -0
- data/lib/octokit/client/service_status.rb +38 -0
- data/lib/octokit/client/source_import.rb +161 -0
- data/lib/octokit/client/stats.rb +105 -0
- data/lib/octokit/client/statuses.rb +47 -0
- data/lib/octokit/client/traffic.rb +69 -0
- data/lib/octokit/client/users.rb +354 -0
- data/lib/octokit/configurable.rb +147 -0
- data/lib/octokit/connection.rb +199 -0
- data/lib/octokit/default.rb +166 -0
- data/lib/octokit/enterprise_admin_client.rb +40 -0
- data/lib/octokit/enterprise_admin_client/admin_stats.rb +120 -0
- data/lib/octokit/enterprise_admin_client/license.rb +18 -0
- data/lib/octokit/enterprise_admin_client/orgs.rb +27 -0
- data/lib/octokit/enterprise_admin_client/search_indexing.rb +83 -0
- data/lib/octokit/enterprise_admin_client/users.rb +128 -0
- data/lib/octokit/enterprise_management_console_client.rb +50 -0
- data/lib/octokit/enterprise_management_console_client/management_console.rb +176 -0
- data/lib/octokit/error.rb +286 -0
- data/lib/octokit/gist.rb +36 -0
- data/lib/octokit/middleware/follow_redirects.rb +131 -0
- data/lib/octokit/organization.rb +17 -0
- data/lib/octokit/preview.rb +38 -0
- data/lib/octokit/rate_limit.rb +33 -0
- data/lib/octokit/repo_arguments.rb +19 -0
- data/lib/octokit/repository.rb +93 -0
- data/lib/octokit/response/feed_parser.rb +21 -0
- data/lib/octokit/response/raise_error.rb +21 -0
- data/lib/octokit/user.rb +19 -0
- data/lib/octokit/version.rb +17 -0
- data/lib/octokit/warnable.rb +17 -0
- data/octokit.gemspec +22 -0
- metadata +160 -0
@@ -0,0 +1,176 @@
|
|
1
|
+
module Octokit
|
2
|
+
class EnterpriseManagementConsoleClient
|
3
|
+
|
4
|
+
# Methods for the Enterprise Management Console API
|
5
|
+
#
|
6
|
+
# @see https://developer.github.com/v3/enterprise/management_console
|
7
|
+
module ManagementConsole
|
8
|
+
|
9
|
+
# Uploads a license for the first time
|
10
|
+
#
|
11
|
+
# @param license [String] The path to your .ghl license file.
|
12
|
+
# @param settings [Hash] A hash configuration of the initial settings.
|
13
|
+
#
|
14
|
+
# @see http: //git.io/j5NT
|
15
|
+
# @return nil
|
16
|
+
def upload_license(license, settings = nil)
|
17
|
+
conn = faraday_configuration
|
18
|
+
|
19
|
+
params = { }
|
20
|
+
params[:license] = Faraday::UploadIO.new(license, 'binary')
|
21
|
+
params[:password] = @management_console_password
|
22
|
+
params[:settings] = "#{settings.to_json}" unless settings.nil?
|
23
|
+
|
24
|
+
@last_response = conn.post("/setup/api/start", params)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Start a configuration process.
|
28
|
+
#
|
29
|
+
# @return nil
|
30
|
+
def start_configuration
|
31
|
+
post "/setup/api/configure", password_hash
|
32
|
+
end
|
33
|
+
|
34
|
+
# Upgrade an Enterprise installation
|
35
|
+
#
|
36
|
+
# @param license [String] The path to your .ghl license file.
|
37
|
+
#
|
38
|
+
# @return nil
|
39
|
+
def upgrade(license)
|
40
|
+
conn = faraday_configuration
|
41
|
+
|
42
|
+
params = { }
|
43
|
+
params[:license] = Faraday::UploadIO.new(license, 'binary')
|
44
|
+
params[:api_key] = @management_console_password
|
45
|
+
@last_response = conn.post("/setup/api/upgrade", params)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Get information about the Enterprise installation
|
49
|
+
#
|
50
|
+
# @return [Sawyer::Resource] The installation information
|
51
|
+
def config_status
|
52
|
+
get "/setup/api/configcheck", password_hash
|
53
|
+
end
|
54
|
+
alias :config_check :config_status
|
55
|
+
|
56
|
+
# Get information about the Enterprise installation
|
57
|
+
#
|
58
|
+
# @return [Sawyer::Resource] The settings
|
59
|
+
def settings
|
60
|
+
get "/setup/api/settings", password_hash
|
61
|
+
end
|
62
|
+
alias :get_settings :settings
|
63
|
+
|
64
|
+
# Modify the Enterprise settings
|
65
|
+
#
|
66
|
+
# @param settings [Hash] A hash configuration of the new settings
|
67
|
+
#
|
68
|
+
# @return [nil]
|
69
|
+
def edit_settings(settings)
|
70
|
+
queries = password_hash
|
71
|
+
queries[:query][:settings] = "#{settings.to_json}"
|
72
|
+
put "/setup/api/settings", queries
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get information about the Enterprise maintenance status
|
76
|
+
#
|
77
|
+
# @return [Sawyer::Resource] The maintenance status
|
78
|
+
def maintenance_status
|
79
|
+
get "/setup/api/maintenance", password_hash
|
80
|
+
end
|
81
|
+
alias :get_maintenance_status :maintenance_status
|
82
|
+
|
83
|
+
# Start (or turn off) the Enterprise maintenance mode
|
84
|
+
#
|
85
|
+
# @param maintenance [Hash] A hash configuration of the maintenance settings
|
86
|
+
# @return [nil]
|
87
|
+
def set_maintenance_status(maintenance)
|
88
|
+
queries = password_hash
|
89
|
+
queries[:query][:maintenance] = "#{maintenance.to_json}"
|
90
|
+
post "/setup/api/maintenance", queries
|
91
|
+
end
|
92
|
+
alias :edit_maintenance_status :set_maintenance_status
|
93
|
+
|
94
|
+
# Fetch the authorized SSH keys on the Enterprise install
|
95
|
+
#
|
96
|
+
# @return [Sawyer::Resource] An array of authorized SSH keys
|
97
|
+
def authorized_keys
|
98
|
+
get "/setup/api/settings/authorized-keys", password_hash
|
99
|
+
end
|
100
|
+
alias :get_authorized_keys :authorized_keys
|
101
|
+
|
102
|
+
# Add an authorized SSH keys on the Enterprise install
|
103
|
+
#
|
104
|
+
# @param key Either the file path to a key, a File handler to the key, or the contents of the key itself
|
105
|
+
# @return [Sawyer::Resource] An array of authorized SSH keys
|
106
|
+
def add_authorized_key(key)
|
107
|
+
queries = password_hash
|
108
|
+
case key
|
109
|
+
when String
|
110
|
+
if File.exist?(key)
|
111
|
+
key = File.open(key, "r")
|
112
|
+
content = key.read.strip
|
113
|
+
key.close
|
114
|
+
else
|
115
|
+
content = key
|
116
|
+
end
|
117
|
+
when File
|
118
|
+
content = key.read.strip
|
119
|
+
key.close
|
120
|
+
end
|
121
|
+
|
122
|
+
queries[:query][:authorized_key] = content
|
123
|
+
post "/setup/api/settings/authorized-keys", queries
|
124
|
+
end
|
125
|
+
|
126
|
+
# Removes an authorized SSH keys from the Enterprise install
|
127
|
+
#
|
128
|
+
# @param key Either the file path to a key, a File handler to the key, or the contents of the key itself
|
129
|
+
# @return [Sawyer::Resource] An array of authorized SSH keys
|
130
|
+
def remove_authorized_key(key)
|
131
|
+
queries = password_hash
|
132
|
+
case key
|
133
|
+
when String
|
134
|
+
if File.exist?(key)
|
135
|
+
key = File.open(key, "r")
|
136
|
+
content = key.read.strip
|
137
|
+
key.close
|
138
|
+
else
|
139
|
+
content = key
|
140
|
+
end
|
141
|
+
when File
|
142
|
+
content = key.read.strip
|
143
|
+
key.close
|
144
|
+
end
|
145
|
+
|
146
|
+
queries[:query][:authorized_key] = content
|
147
|
+
delete "/setup/api/settings/authorized-keys", queries
|
148
|
+
end
|
149
|
+
alias :delete_authorized_key :remove_authorized_key
|
150
|
+
|
151
|
+
end
|
152
|
+
private
|
153
|
+
|
154
|
+
def password_hash
|
155
|
+
{ :query => { :api_key => @management_console_password } }
|
156
|
+
end
|
157
|
+
|
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
|
160
|
+
def faraday_configuration
|
161
|
+
@faraday_configuration ||= Faraday.new(:url => @management_console_endpoint) do |http|
|
162
|
+
http.headers[:user_agent] = user_agent
|
163
|
+
http.request :multipart
|
164
|
+
http.request :url_encoded
|
165
|
+
|
166
|
+
# Disabling SSL is essential for certain self-hosted Enterprise instances
|
167
|
+
if self.connection_options[:ssl] && !self.connection_options[:ssl][:verify]
|
168
|
+
http.ssl[:verify] = false
|
169
|
+
end
|
170
|
+
|
171
|
+
http.use Octokit::Response::RaiseError
|
172
|
+
http.adapter Faraday.default_adapter
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
module Octokit
|
2
|
+
# Custom error class for rescuing from all GitHub errors
|
3
|
+
class Error < StandardError
|
4
|
+
|
5
|
+
# Returns the appropriate Octokit::Error subclass based
|
6
|
+
# on status and response message
|
7
|
+
#
|
8
|
+
# @param [Hash] response HTTP response
|
9
|
+
# @return [Octokit::Error]
|
10
|
+
def self.from_response(response)
|
11
|
+
status = response[:status].to_i
|
12
|
+
body = response[:body].to_s
|
13
|
+
headers = response[:response_headers]
|
14
|
+
|
15
|
+
if klass = case status
|
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 error_for_404(body)
|
20
|
+
when 405 then Octokit::MethodNotAllowed
|
21
|
+
when 406 then Octokit::NotAcceptable
|
22
|
+
when 409 then Octokit::Conflict
|
23
|
+
when 415 then Octokit::UnsupportedMediaType
|
24
|
+
when 422 then Octokit::UnprocessableEntity
|
25
|
+
when 451 then Octokit::UnavailableForLegalReasons
|
26
|
+
when 400..499 then Octokit::ClientError
|
27
|
+
when 500 then Octokit::InternalServerError
|
28
|
+
when 501 then Octokit::NotImplemented
|
29
|
+
when 502 then Octokit::BadGateway
|
30
|
+
when 503 then Octokit::ServiceUnavailable
|
31
|
+
when 500..599 then Octokit::ServerError
|
32
|
+
end
|
33
|
+
klass.new(response)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(response=nil)
|
38
|
+
@response = response
|
39
|
+
super(build_error_message)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Documentation URL returned by the API for some errors
|
43
|
+
#
|
44
|
+
# @return [String]
|
45
|
+
def documentation_url
|
46
|
+
data[:documentation_url] if data.is_a? Hash
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns most appropriate error for 401 HTTP status code
|
50
|
+
# @private
|
51
|
+
def self.error_for_401(headers)
|
52
|
+
if Octokit::OneTimePasswordRequired.required_header(headers)
|
53
|
+
Octokit::OneTimePasswordRequired
|
54
|
+
else
|
55
|
+
Octokit::Unauthorized
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns most appropriate error for 403 HTTP status code
|
60
|
+
# @private
|
61
|
+
def self.error_for_403(body)
|
62
|
+
if body =~ /rate limit exceeded/i
|
63
|
+
Octokit::TooManyRequests
|
64
|
+
elsif body =~ /login attempts exceeded/i
|
65
|
+
Octokit::TooManyLoginAttempts
|
66
|
+
elsif body =~ /abuse/i
|
67
|
+
Octokit::AbuseDetected
|
68
|
+
elsif body =~ /repository access blocked/i
|
69
|
+
Octokit::RepositoryUnavailable
|
70
|
+
elsif body =~ /email address must be verified/i
|
71
|
+
Octokit::UnverifiedEmail
|
72
|
+
elsif body =~ /account was suspended/i
|
73
|
+
Octokit::AccountSuspended
|
74
|
+
else
|
75
|
+
Octokit::Forbidden
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Return most appropriate error for 404 HTTP status code
|
80
|
+
# @private
|
81
|
+
def self.error_for_404(body)
|
82
|
+
if body =~ /Branch not protected/i
|
83
|
+
Octokit::BranchNotProtected
|
84
|
+
else
|
85
|
+
Octokit::NotFound
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Array of validation errors
|
90
|
+
# @return [Array<Hash>] Error info
|
91
|
+
def errors
|
92
|
+
if data && data.is_a?(Hash)
|
93
|
+
data[:errors] || []
|
94
|
+
else
|
95
|
+
[]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Status code returned by the GitHub server.
|
100
|
+
#
|
101
|
+
# @return [Integer]
|
102
|
+
def response_status
|
103
|
+
@response[:status]
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def data
|
109
|
+
@data ||=
|
110
|
+
if (body = @response[:body]) && !body.empty?
|
111
|
+
if body.is_a?(String) &&
|
112
|
+
@response[:response_headers] &&
|
113
|
+
@response[:response_headers][:content_type] =~ /json/
|
114
|
+
|
115
|
+
Sawyer::Agent.serializer.decode(body)
|
116
|
+
else
|
117
|
+
body
|
118
|
+
end
|
119
|
+
else
|
120
|
+
nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def response_message
|
125
|
+
case data
|
126
|
+
when Hash
|
127
|
+
data[:message]
|
128
|
+
when String
|
129
|
+
data
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def response_error
|
134
|
+
"Error: #{data[:error]}" if data.is_a?(Hash) && data[:error]
|
135
|
+
end
|
136
|
+
|
137
|
+
def response_error_summary
|
138
|
+
return nil unless data.is_a?(Hash) && !Array(data[:errors]).empty?
|
139
|
+
|
140
|
+
summary = "\nError summary:\n"
|
141
|
+
summary << data[:errors].map do |error|
|
142
|
+
if error.is_a? Hash
|
143
|
+
error.map { |k,v| " #{k}: #{v}" }
|
144
|
+
else
|
145
|
+
" #{error}"
|
146
|
+
end
|
147
|
+
end.join("\n")
|
148
|
+
|
149
|
+
summary
|
150
|
+
end
|
151
|
+
|
152
|
+
def build_error_message
|
153
|
+
return nil if @response.nil?
|
154
|
+
|
155
|
+
message = "#{@response[:method].to_s.upcase} "
|
156
|
+
message << redact_url(@response[:url].to_s) + ": "
|
157
|
+
message << "#{@response[:status]} - "
|
158
|
+
message << "#{response_message}" unless response_message.nil?
|
159
|
+
message << "#{response_error}" unless response_error.nil?
|
160
|
+
message << "#{response_error_summary}" unless response_error_summary.nil?
|
161
|
+
message << " // See: #{documentation_url}" unless documentation_url.nil?
|
162
|
+
message
|
163
|
+
end
|
164
|
+
|
165
|
+
def redact_url(url_string)
|
166
|
+
%w[client_secret access_token].each do |token|
|
167
|
+
url_string.gsub!(/#{token}=\S+/, "#{token}=(redacted)") if url_string.include? token
|
168
|
+
end
|
169
|
+
url_string
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Raised on errors in the 400-499 range
|
174
|
+
class ClientError < Error; end
|
175
|
+
|
176
|
+
# Raised when GitHub returns a 400 HTTP status code
|
177
|
+
class BadRequest < ClientError; end
|
178
|
+
|
179
|
+
# Raised when GitHub returns a 401 HTTP status code
|
180
|
+
class Unauthorized < ClientError; end
|
181
|
+
|
182
|
+
# Raised when GitHub returns a 401 HTTP status code
|
183
|
+
# and headers include "X-GitHub-OTP"
|
184
|
+
class OneTimePasswordRequired < ClientError
|
185
|
+
#@private
|
186
|
+
OTP_DELIVERY_PATTERN = /required; (\w+)/i
|
187
|
+
|
188
|
+
#@private
|
189
|
+
def self.required_header(headers)
|
190
|
+
OTP_DELIVERY_PATTERN.match headers['X-GitHub-OTP'].to_s
|
191
|
+
end
|
192
|
+
|
193
|
+
# Delivery method for the user's OTP
|
194
|
+
#
|
195
|
+
# @return [String]
|
196
|
+
def password_delivery
|
197
|
+
@password_delivery ||= delivery_method_from_header
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def delivery_method_from_header
|
203
|
+
if match = self.class.required_header(@response[:response_headers])
|
204
|
+
match[1]
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# Raised when GitHub returns a 403 HTTP status code
|
210
|
+
class Forbidden < ClientError; end
|
211
|
+
|
212
|
+
# Raised when GitHub returns a 403 HTTP status code
|
213
|
+
# and body matches 'rate limit exceeded'
|
214
|
+
class TooManyRequests < Forbidden; end
|
215
|
+
|
216
|
+
# Raised when GitHub returns a 403 HTTP status code
|
217
|
+
# and body matches 'login attempts exceeded'
|
218
|
+
class TooManyLoginAttempts < Forbidden; end
|
219
|
+
|
220
|
+
# Raised when GitHub returns a 403 HTTP status code
|
221
|
+
# and body matches 'abuse'
|
222
|
+
class AbuseDetected < Forbidden; end
|
223
|
+
|
224
|
+
# Raised when GitHub returns a 403 HTTP status code
|
225
|
+
# and body matches 'repository access blocked'
|
226
|
+
class RepositoryUnavailable < Forbidden; end
|
227
|
+
|
228
|
+
# Raised when GitHub returns a 403 HTTP status code
|
229
|
+
# and body matches 'email address must be verified'
|
230
|
+
class UnverifiedEmail < Forbidden; end
|
231
|
+
|
232
|
+
# Raised when GitHub returns a 403 HTTP status code
|
233
|
+
# and body matches 'account was suspended'
|
234
|
+
class AccountSuspended < Forbidden; end
|
235
|
+
|
236
|
+
# Raised when GitHub returns a 404 HTTP status code
|
237
|
+
class NotFound < ClientError; end
|
238
|
+
|
239
|
+
# Raised when GitHub returns a 404 HTTP status code
|
240
|
+
# and body matches 'Branch not protected'
|
241
|
+
class BranchNotProtected < ClientError; end
|
242
|
+
|
243
|
+
# Raised when GitHub returns a 405 HTTP status code
|
244
|
+
class MethodNotAllowed < ClientError; end
|
245
|
+
|
246
|
+
# Raised when GitHub returns a 406 HTTP status code
|
247
|
+
class NotAcceptable < ClientError; end
|
248
|
+
|
249
|
+
# Raised when GitHub returns a 409 HTTP status code
|
250
|
+
class Conflict < ClientError; end
|
251
|
+
|
252
|
+
# Raised when GitHub returns a 414 HTTP status code
|
253
|
+
class UnsupportedMediaType < ClientError; end
|
254
|
+
|
255
|
+
# Raised when GitHub returns a 422 HTTP status code
|
256
|
+
class UnprocessableEntity < ClientError; end
|
257
|
+
|
258
|
+
# Raised when GitHub returns a 451 HTTP status code
|
259
|
+
class UnavailableForLegalReasons < ClientError; end
|
260
|
+
|
261
|
+
# Raised on errors in the 500-599 range
|
262
|
+
class ServerError < Error; end
|
263
|
+
|
264
|
+
# Raised when GitHub returns a 500 HTTP status code
|
265
|
+
class InternalServerError < ServerError; end
|
266
|
+
|
267
|
+
# Raised when GitHub returns a 501 HTTP status code
|
268
|
+
class NotImplemented < ServerError; end
|
269
|
+
|
270
|
+
# Raised when GitHub returns a 502 HTTP status code
|
271
|
+
class BadGateway < ServerError; end
|
272
|
+
|
273
|
+
# Raised when GitHub returns a 503 HTTP status code
|
274
|
+
class ServiceUnavailable < ServerError; end
|
275
|
+
|
276
|
+
# Raised when client fails to provide valid Content-Type
|
277
|
+
class MissingContentType < ArgumentError; end
|
278
|
+
|
279
|
+
# Raised when a method requires an application client_id
|
280
|
+
# and secret but none is provided
|
281
|
+
class ApplicationCredentialsRequired < StandardError; end
|
282
|
+
|
283
|
+
# Raised when a repository is created with an invalid format
|
284
|
+
class InvalidRepository < ArgumentError; end
|
285
|
+
|
286
|
+
end
|