github_api2 1.0.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 (127) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +770 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.md +741 -0
  5. data/lib/github_api2/api/actions.rb +60 -0
  6. data/lib/github_api2/api/arguments.rb +253 -0
  7. data/lib/github_api2/api/config/property.rb +30 -0
  8. data/lib/github_api2/api/config/property_set.rb +120 -0
  9. data/lib/github_api2/api/config.rb +105 -0
  10. data/lib/github_api2/api/factory.rb +33 -0
  11. data/lib/github_api2/api.rb +398 -0
  12. data/lib/github_api2/authorization.rb +75 -0
  13. data/lib/github_api2/client/activity/events.rb +233 -0
  14. data/lib/github_api2/client/activity/feeds.rb +50 -0
  15. data/lib/github_api2/client/activity/notifications.rb +181 -0
  16. data/lib/github_api2/client/activity/starring.rb +130 -0
  17. data/lib/github_api2/client/activity/watching.rb +176 -0
  18. data/lib/github_api2/client/activity.rb +31 -0
  19. data/lib/github_api2/client/authorizations/app.rb +98 -0
  20. data/lib/github_api2/client/authorizations.rb +142 -0
  21. data/lib/github_api2/client/emojis.rb +19 -0
  22. data/lib/github_api2/client/gists/comments.rb +100 -0
  23. data/lib/github_api2/client/gists.rb +289 -0
  24. data/lib/github_api2/client/git_data/blobs.rb +51 -0
  25. data/lib/github_api2/client/git_data/commits.rb +101 -0
  26. data/lib/github_api2/client/git_data/references.rb +150 -0
  27. data/lib/github_api2/client/git_data/tags.rb +95 -0
  28. data/lib/github_api2/client/git_data/trees.rb +113 -0
  29. data/lib/github_api2/client/git_data.rb +31 -0
  30. data/lib/github_api2/client/gitignore.rb +57 -0
  31. data/lib/github_api2/client/issues/assignees.rb +77 -0
  32. data/lib/github_api2/client/issues/comments.rb +146 -0
  33. data/lib/github_api2/client/issues/events.rb +50 -0
  34. data/lib/github_api2/client/issues/labels.rb +189 -0
  35. data/lib/github_api2/client/issues/milestones.rb +146 -0
  36. data/lib/github_api2/client/issues.rb +248 -0
  37. data/lib/github_api2/client/markdown.rb +62 -0
  38. data/lib/github_api2/client/meta.rb +19 -0
  39. data/lib/github_api2/client/orgs/hooks.rb +182 -0
  40. data/lib/github_api2/client/orgs/members.rb +142 -0
  41. data/lib/github_api2/client/orgs/memberships.rb +131 -0
  42. data/lib/github_api2/client/orgs/projects.rb +57 -0
  43. data/lib/github_api2/client/orgs/teams.rb +407 -0
  44. data/lib/github_api2/client/orgs.rb +127 -0
  45. data/lib/github_api2/client/projects/cards.rb +158 -0
  46. data/lib/github_api2/client/projects/columns.rb +146 -0
  47. data/lib/github_api2/client/projects.rb +83 -0
  48. data/lib/github_api2/client/pull_requests/comments.rb +140 -0
  49. data/lib/github_api2/client/pull_requests/reviews.rb +158 -0
  50. data/lib/github_api2/client/pull_requests.rb +195 -0
  51. data/lib/github_api2/client/repos/branches/protections.rb +75 -0
  52. data/lib/github_api2/client/repos/branches.rb +48 -0
  53. data/lib/github_api2/client/repos/collaborators.rb +84 -0
  54. data/lib/github_api2/client/repos/comments.rb +125 -0
  55. data/lib/github_api2/client/repos/commits.rb +80 -0
  56. data/lib/github_api2/client/repos/contents.rb +263 -0
  57. data/lib/github_api2/client/repos/deployments.rb +138 -0
  58. data/lib/github_api2/client/repos/downloads.rb +62 -0
  59. data/lib/github_api2/client/repos/forks.rb +50 -0
  60. data/lib/github_api2/client/repos/hooks.rb +214 -0
  61. data/lib/github_api2/client/repos/invitations.rb +41 -0
  62. data/lib/github_api2/client/repos/keys.rb +104 -0
  63. data/lib/github_api2/client/repos/merging.rb +47 -0
  64. data/lib/github_api2/client/repos/pages.rb +48 -0
  65. data/lib/github_api2/client/repos/projects.rb +62 -0
  66. data/lib/github_api2/client/repos/pub_sub_hubbub.rb +133 -0
  67. data/lib/github_api2/client/repos/releases/assets.rb +136 -0
  68. data/lib/github_api2/client/repos/releases/tags.rb +24 -0
  69. data/lib/github_api2/client/repos/releases.rb +189 -0
  70. data/lib/github_api2/client/repos/statistics.rb +89 -0
  71. data/lib/github_api2/client/repos/statuses.rb +91 -0
  72. data/lib/github_api2/client/repos.rb +473 -0
  73. data/lib/github_api2/client/say.rb +25 -0
  74. data/lib/github_api2/client/scopes.rb +46 -0
  75. data/lib/github_api2/client/search/legacy.rb +111 -0
  76. data/lib/github_api2/client/search.rb +133 -0
  77. data/lib/github_api2/client/users/emails.rb +65 -0
  78. data/lib/github_api2/client/users/followers.rb +115 -0
  79. data/lib/github_api2/client/users/keys.rb +104 -0
  80. data/lib/github_api2/client/users.rb +117 -0
  81. data/lib/github_api2/client.rb +77 -0
  82. data/lib/github_api2/configuration.rb +70 -0
  83. data/lib/github_api2/connection.rb +82 -0
  84. data/lib/github_api2/constants.rb +61 -0
  85. data/lib/github_api2/core_ext/array.rb +25 -0
  86. data/lib/github_api2/core_ext/hash.rb +91 -0
  87. data/lib/github_api2/deprecation.rb +39 -0
  88. data/lib/github_api2/error/client_error.rb +89 -0
  89. data/lib/github_api2/error/service_error.rb +223 -0
  90. data/lib/github_api2/error.rb +32 -0
  91. data/lib/github_api2/ext/faraday.rb +40 -0
  92. data/lib/github_api2/mash.rb +7 -0
  93. data/lib/github_api2/middleware.rb +37 -0
  94. data/lib/github_api2/mime_type.rb +33 -0
  95. data/lib/github_api2/normalizer.rb +23 -0
  96. data/lib/github_api2/null_encoder.rb +25 -0
  97. data/lib/github_api2/page_iterator.rb +138 -0
  98. data/lib/github_api2/page_links.rb +63 -0
  99. data/lib/github_api2/paged_request.rb +42 -0
  100. data/lib/github_api2/pagination.rb +115 -0
  101. data/lib/github_api2/parameter_filter.rb +35 -0
  102. data/lib/github_api2/params_hash.rb +115 -0
  103. data/lib/github_api2/rate_limit.rb +25 -0
  104. data/lib/github_api2/request/basic_auth.rb +36 -0
  105. data/lib/github_api2/request/jsonize.rb +54 -0
  106. data/lib/github_api2/request/oauth2.rb +45 -0
  107. data/lib/github_api2/request/verbs.rb +63 -0
  108. data/lib/github_api2/request.rb +84 -0
  109. data/lib/github_api2/response/atom_parser.rb +22 -0
  110. data/lib/github_api2/response/follow_redirects.rb +140 -0
  111. data/lib/github_api2/response/header.rb +87 -0
  112. data/lib/github_api2/response/jsonize.rb +28 -0
  113. data/lib/github_api2/response/mashify.rb +24 -0
  114. data/lib/github_api2/response/raise_error.rb +22 -0
  115. data/lib/github_api2/response/xmlize.rb +28 -0
  116. data/lib/github_api2/response.rb +48 -0
  117. data/lib/github_api2/response_wrapper.rb +161 -0
  118. data/lib/github_api2/ssl_certs/cacerts.pem +2183 -0
  119. data/lib/github_api2/utils/url.rb +63 -0
  120. data/lib/github_api2/validations/format.rb +26 -0
  121. data/lib/github_api2/validations/presence.rb +32 -0
  122. data/lib/github_api2/validations/required.rb +21 -0
  123. data/lib/github_api2/validations/token.rb +41 -0
  124. data/lib/github_api2/validations.rb +22 -0
  125. data/lib/github_api2/version.rb +5 -0
  126. data/lib/github_api2.rb +92 -0
  127. metadata +363 -0
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ require_relative 'constants'
6
+
7
+ module Github
8
+ # Specifies Http connection options
9
+ module Connection
10
+ extend self
11
+ include Github::Constants
12
+
13
+ ALLOWED_OPTIONS = [
14
+ :headers,
15
+ :url,
16
+ :params,
17
+ :request,
18
+ :ssl
19
+ ].freeze
20
+
21
+ # Default requets header information
22
+ #
23
+ # @return [Hash[String]]
24
+ #
25
+ # @api private
26
+ def default_headers
27
+ {
28
+ ACCEPT => 'application/vnd.github.v3+json,' \
29
+ 'application/vnd.github.beta+json;q=0.5,' \
30
+ 'application/json;q=0.1',
31
+ ACCEPT_CHARSET => 'utf-8'
32
+ }
33
+ end
34
+
35
+ # Create default connection options
36
+ #
37
+ # @return [Hash[Symbol]]
38
+ # the default options
39
+ #
40
+ # @api private
41
+ def default_options(options = {})
42
+ headers = default_headers.merge(options[:headers] || {})
43
+ headers.merge!({USER_AGENT => options[:user_agent]})
44
+ {
45
+ headers: headers,
46
+ ssl: options[:ssl],
47
+ url: options[:endpoint]
48
+ }
49
+ end
50
+
51
+ # Exposes middleware builder to facilitate custom stacks and easy
52
+ # addition of new extensions such as cache adapter.
53
+ #
54
+ # @api public
55
+ def stack(options = {})
56
+ @stack ||= begin
57
+ builder_class = if defined?(Faraday::RackBuilder)
58
+ Faraday::RackBuilder
59
+ else
60
+ Faraday::Builder
61
+ end
62
+ builder_class.new(&Github.default_middleware(options))
63
+ end
64
+ end
65
+
66
+ # Creates http connection
67
+ #
68
+ # Returns a Faraday::Connection object
69
+ def connection(api, options = {})
70
+ connection_options = default_options(options)
71
+ connection_options.merge!(builder: stack(options.merge!(api: api)))
72
+ if options[:connection_options]
73
+ connection_options.deep_merge!(options[:connection_options])
74
+ end
75
+ if ENV['DEBUG']
76
+ p "Connection options : \n"
77
+ pp connection_options
78
+ end
79
+ Faraday.new(connection_options)
80
+ end
81
+ end # Connection
82
+ end # Github
@@ -0,0 +1,61 @@
1
+ module Github
2
+ module Constants
3
+ extend self
4
+
5
+ # Response headers
6
+ RATELIMIT_REMAINING = 'X-RateLimit-Remaining'.freeze
7
+
8
+ RATELIMIT_LIMIT = 'X-RateLimit-Limit'.freeze
9
+
10
+ RATELIMIT_RESET = 'X-RateLimit-Reset'.freeze
11
+
12
+ CONTENT_TYPE = 'Content-Type'.freeze
13
+
14
+ CONTENT_LENGTH = 'content-length'.freeze
15
+
16
+ CACHE_CONTROL = 'cache-control'.freeze
17
+
18
+ ETAG = 'ETag'.freeze
19
+
20
+ SERVER = 'Server'.freeze
21
+
22
+ DATE = 'Date'.freeze
23
+
24
+ LOCATION = 'Location'.freeze
25
+
26
+ USER_AGENT = 'User-Agent'.freeze
27
+
28
+ ACCEPT = 'Accept'.freeze
29
+
30
+ ACCEPT_CHARSET = 'Accept-Charset'.freeze
31
+
32
+ OAUTH_SCOPES = 'X-OAuth-Scopes'.freeze
33
+
34
+ ACCEPTED_OAUTH_SCOPES = 'X-Accepted-Oauth-Scopes'.freeze
35
+
36
+ # Link headers
37
+ HEADER_LINK = "Link".freeze
38
+
39
+ HEADER_NEXT = "X-Next".freeze
40
+
41
+ HEADER_LAST = "X-Last".freeze
42
+
43
+ META_REL = "rel".freeze
44
+
45
+ META_LAST = "last".freeze
46
+
47
+ META_NEXT = "next".freeze
48
+
49
+ META_FIRST = "first".freeze
50
+
51
+ META_PREV = "prev".freeze
52
+
53
+ PARAM_PAGE = "page".freeze
54
+
55
+ PARAM_PER_PAGE = "per_page".freeze
56
+
57
+ PARAM_START_PAGE = "start_page".freeze
58
+
59
+
60
+ end # Constants
61
+ end # Github
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ class Array # :nodoc:
4
+
5
+ # Returns a new arrray with keys removed
6
+ #
7
+ def except(*keys)
8
+ self.dup.except!(*keys)
9
+ end unless method_defined? :except
10
+
11
+ # Similar to except but modifies self
12
+ #
13
+ def except!(*items)
14
+ copy = self.dup
15
+ copy.reject! { |item| items.include? item }
16
+ copy
17
+ end unless method_defined? :except!
18
+
19
+ # Selects a hash from the arguments list
20
+ #
21
+ def extract_options!
22
+ last.is_a?(::Hash) ? pop : {}
23
+ end unless method_defined? :extract_options!
24
+
25
+ end # Array
@@ -0,0 +1,91 @@
1
+ # encoding: utf-8
2
+
3
+ class Hash # :nodoc:
4
+
5
+ # Returns a new hash with keys removed
6
+ #
7
+ def except(*items)
8
+ self.dup.except!(*items)
9
+ end unless method_defined? :except
10
+
11
+ # Similar to except but modifies self
12
+ #
13
+ def except!(*keys)
14
+ keys.each { |key| delete(key) }
15
+ self
16
+ end unless method_defined? :except!
17
+
18
+ # Returns a new hash with all the keys converted to symbols
19
+ #
20
+ def symbolize_keys
21
+ inject({}) do |hash, (key, value)|
22
+ hash[(key.to_sym rescue key) || key] = value
23
+ hash
24
+ end
25
+ end unless method_defined? :symbolize_keys
26
+
27
+ # Similar to symbolize_keys but modifies self
28
+ #
29
+ def symbolize_keys!
30
+ hash = symbolize_keys
31
+ hash.each do |key, val|
32
+ hash[key] = case val
33
+ when Hash
34
+ val.symbolize_keys!
35
+ when Array
36
+ val.map do |item|
37
+ item.is_a?(Hash) ? item.symbolize_keys! : item
38
+ end
39
+ else
40
+ val
41
+ end
42
+ end
43
+ return hash
44
+ end unless method_defined? :symbolize_keys!
45
+
46
+ # Returns hash collapsed into a query string
47
+ #
48
+ def serialize
49
+ self.map { |key, val| [key, val].join("=") }.join("&")
50
+ end unless method_defined? :serialize
51
+
52
+ # Searches for all deeply nested keys
53
+ #
54
+ def deep_keys
55
+ keys = self.keys
56
+ keys.each do |key|
57
+ if self[key].is_a?(Hash)
58
+ keys << self[key].deep_keys.compact.flatten
59
+ next
60
+ end
61
+ end
62
+ keys.flatten
63
+ end unless method_defined? :deep_keys
64
+
65
+ # Returns true if the given key is present inside deeply nested hash
66
+ #
67
+ def deep_key?(key)
68
+ self.deep_keys.include? key
69
+ end unless method_defined? :deep_key?
70
+
71
+ # Recursively merges self with other hash and returns new hash.
72
+ #
73
+ def deep_merge(other, &block)
74
+ dup.deep_merge!(other, &block)
75
+ end unless method_defined? :deep_merge
76
+
77
+ # Similar as deep_merge but modifies self
78
+ #
79
+ def deep_merge!(other, &block)
80
+ other.each_pair do |key, val|
81
+ tval = self[key]
82
+ if tval.is_a?(Hash) && val.is_a?(Hash)
83
+ self[key] = tval.deep_merge(val)
84
+ else
85
+ self[key] = block && tval ? block.call(k, tval, val) : val
86
+ end
87
+ end
88
+ self
89
+ end unless method_defined? :deep_merge!
90
+
91
+ end # Hash
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+
5
+ DEPRECATION_PREFIX = "[GithubAPI] Deprecation warning:"
6
+
7
+ class << self
8
+
9
+ attr_writer :deprecation_tracker
10
+
11
+ def deprecation_tracker
12
+ @deprecation_tracker ||= []
13
+ end
14
+
15
+ # Displays deprecation message to the user.
16
+ # Each message is printed once.
17
+ def deprecate(method, alternate_method=nil)
18
+ return if deprecation_tracker.include? method
19
+ deprecation_tracker << method
20
+
21
+ message = <<-NOTICE
22
+ #{DEPRECATION_PREFIX}
23
+
24
+ * #{method} is deprecated.
25
+ NOTICE
26
+ if alternate_method
27
+ message << <<-ADDITIONAL
28
+ * please use #{alternate_method} instead.
29
+ ADDITIONAL
30
+ end
31
+ warn_deprecation(message)
32
+ end
33
+
34
+ def warn_deprecation(message)
35
+ send :warn, message
36
+ end
37
+ end
38
+
39
+ end # Github
@@ -0,0 +1,89 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative '../error'
4
+
5
+ module Github #:nodoc
6
+ # Raised when Github returns the HTTP status code 404
7
+ module Error
8
+ class ClientError < GithubError
9
+ attr_reader :problem, :summary, :resolution
10
+
11
+ def initialize(message)
12
+ super(message)
13
+ end
14
+
15
+ def generate_message(attributes)
16
+ @problem = attributes[:problem]
17
+ @summary = attributes[:summary]
18
+ @resolution = attributes[:resolution]
19
+ "\nProblem:\n #{@problem}"+
20
+ "\nSummary:\n #{@summary}"+
21
+ "\nResolution:\n #{@resolution}"
22
+ end
23
+ end
24
+
25
+ # Raised when invalid options are passed to a request body
26
+ class InvalidOptions < ClientError
27
+ def initialize(invalid, valid)
28
+ super(
29
+ generate_message(
30
+ problem: "Invalid option #{invalid.keys.join(', ')} provided for this request.",
31
+ summary: "Github gem checks the request parameters passed to ensure that github api is not hit unnecessarily and to fail fast.",
32
+ resolution: "Valid options are: #{valid.join(', ')}, make sure these are the ones you are using"
33
+ )
34
+ )
35
+ end
36
+ end
37
+
38
+ # Raised when invalid options are passed to a request body
39
+ class RequiredParams < ClientError
40
+ def initialize(provided, required)
41
+ super(
42
+ generate_message(
43
+ problem: "Missing required parameters: #{provided.keys.join(', ')} provided for this request.",
44
+ summary: "Github gem checks the request parameters passed to ensure that github api is not hit unnecessarily and to fail fast.",
45
+ resolution: "Required parameters are: #{required.join(', ')}, make sure these are the ones you are using"
46
+ )
47
+ )
48
+ end
49
+ end
50
+
51
+ # Raised when invalid options are passed to a request body
52
+ class UnknownMedia < ClientError
53
+ def initialize(file)
54
+ super(
55
+ generate_message(
56
+ problem: "Unknown content type for: '#{file}' provided for this request.",
57
+ summary: "Github gem infers the content type of the resource by calling the mime-types gem type inference.",
58
+ resolution: "Please install mime-types gem to infer the resource content type."
59
+ )
60
+ )
61
+ end
62
+ end
63
+
64
+ # Raised when invalid options are passed to a request body
65
+ class UnknownValue < ClientError
66
+ def initialize(key, value, permitted)
67
+ super(
68
+ generate_message(
69
+ problem: "Wrong value of '#{value}' for the parameter: #{key} provided for this request.",
70
+ summary: "Github gem checks the request parameters passed to ensure that github api is not hit unnecessairly and fails fast.",
71
+ resolution: "Permitted values are: #{permitted}, make sure these are the ones you are using"
72
+ )
73
+ )
74
+ end
75
+ end
76
+
77
+ class Validations < ClientError
78
+ def initialize(errors)
79
+ super(
80
+ generate_message(
81
+ problem: "Attempted to send request with nil arguments for #{errors.keys.join(', ')}.",
82
+ summary: 'Each request expects certain number of required arguments.',
83
+ resolution: 'Double check that the provided arguments are set to some value that is neither nil nor empty string.'
84
+ )
85
+ )
86
+ end
87
+ end
88
+ end # Error
89
+ end # Github
@@ -0,0 +1,223 @@
1
+ # encoding: utf-8
2
+
3
+ require 'json'
4
+
5
+ require_relative '../error'
6
+
7
+ module Github
8
+ # Raised when GitHub returns any of the HTTP status codes
9
+ module Error
10
+ class ServiceError < GithubError
11
+ # Add http status code method to error type
12
+ #
13
+ # @param [Integer] code
14
+ # the status code
15
+ #
16
+ # @api public
17
+ def self.http_status_code(code)
18
+ define_method(:http_status_code) { code }
19
+ end
20
+
21
+ # A mapping of status codes and error types
22
+ #
23
+ # @return [Hash[Integer, Object]]
24
+ #
25
+ # @api public
26
+ def self.error_mapping
27
+ @error_mapping ||= Hash[
28
+ descendants.map do |klass|
29
+ [klass.new({}).http_status_code, klass]
30
+ end
31
+ ]
32
+ end
33
+
34
+ MIN_BODY_LENGTH = 2
35
+
36
+ # Create a ServiceError
37
+ #
38
+ # @param [Hash[Symbol]] response
39
+ #
40
+ # @api public
41
+ def initialize(response)
42
+ @headers = response[:response_headers]
43
+ @body = response[:body]
44
+ @status = response[:status]
45
+
46
+ @response_headers = @headers
47
+ @response_message = @body
48
+
49
+ super(create_message(response))
50
+ end
51
+
52
+ # Expose response payload as JSON object if possible
53
+ #
54
+ # @return [Hash[Symbol]|String]
55
+ #
56
+ # @api public
57
+ def data
58
+ @data ||= decode_data(@body)
59
+ end
60
+
61
+ # Stores error message(s) returned in response body
62
+ #
63
+ # @return [Array[Hash[Symbol]]]
64
+ # the array of hash error objects
65
+ #
66
+ # @api public
67
+ def error_messages
68
+ @error_messages ||= begin
69
+ data[:errors] ? data[:errors] : [data]
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ # Create full error message
76
+ #
77
+ # @param [Hash[Symbol]] response
78
+ # the http response
79
+ #
80
+ # @return [String]
81
+ # the error message
82
+ #
83
+ # @api private
84
+ def create_message(response)
85
+ return if response.nil?
86
+
87
+ message = "#{response[:method].to_s.upcase} "
88
+ message << "#{response[:url]}: "
89
+ message << "#{@status} - #{format_response}"
90
+ message
91
+ end
92
+
93
+ # Decode body information if in JSON format
94
+ #
95
+ # @param [String] body
96
+ # the response body
97
+ #
98
+ # @api private
99
+ def decode_data(body)
100
+ if body.respond_to?(:to_str) &&
101
+ body.length >= MIN_BODY_LENGTH &&
102
+ @headers[:content_type] =~ /json/
103
+
104
+ JSON.parse(body, symbolize_names: true)
105
+ else
106
+ body
107
+ end
108
+ end
109
+
110
+ # Read response body and convert to human friendly format
111
+ #
112
+ # @return [String]
113
+ #
114
+ # @api private
115
+ def format_response
116
+ return '' if data.nil? || data.empty?
117
+
118
+ case data
119
+ when Hash
120
+ message = data[:message] ? data[:message] : ' '
121
+ docs = data[:documentation_url]
122
+ error = create_error_summary
123
+ message << error if error
124
+ message << "\nSee: #{docs}" if docs
125
+ message
126
+ when String
127
+ data
128
+ end
129
+ end
130
+
131
+ # Create error summary from response body
132
+ #
133
+ # @return [String]
134
+ #
135
+ # @api private
136
+ def create_error_summary
137
+ if data[:error]
138
+ "\nError: #{data[:error]}"
139
+ elsif data[:errors]
140
+ message = "\nErrors:\n"
141
+ message << data[:errors].map do |error|
142
+ case error
143
+ when Hash
144
+ "Error: #{error.map { |k, v| "#{k}: #{v}" }.join(', ')}"
145
+ else
146
+ "Error: #{error}"
147
+ end
148
+ end.join("\n")
149
+ end
150
+ end
151
+ end # ServiceError
152
+
153
+ # Raised when Github returns the HTTP status code 400
154
+ class BadRequest < ServiceError
155
+ http_status_code 400
156
+ end
157
+
158
+ # Raised when GitHub returns the HTTP status code 401
159
+ class Unauthorized < ServiceError
160
+ http_status_code 401
161
+ end
162
+
163
+ # Raised when Github returns the HTTP status code 403
164
+ class Forbidden < ServiceError
165
+ http_status_code 403
166
+ end
167
+
168
+ # Raised when Github returns the HTTP status code 404
169
+ class NotFound < ServiceError
170
+ http_status_code 404
171
+ end
172
+
173
+ # Raised when Github returns the HTTP status code 405
174
+ class MethodNotAllowed < ServiceError
175
+ http_status_code 405
176
+ end
177
+
178
+ # Raised when Github returns the HTTP status code 406
179
+ class NotAcceptable < ServiceError
180
+ http_status_code 406
181
+ end
182
+
183
+ # Raised when GitHub returns the HTTP status code 409
184
+ class Conflict < ServiceError
185
+ http_status_code 409
186
+ end
187
+
188
+ # Raised when GitHub returns the HTTP status code 414
189
+ class UnsupportedMediaType < ServiceError
190
+ http_status_code 414
191
+ end
192
+
193
+ # Raised when GitHub returns the HTTP status code 422
194
+ class UnprocessableEntity < ServiceError
195
+ http_status_code 422
196
+ end
197
+
198
+ # Raised when GitHub returns the HTTP status code 451
199
+ class UnavailableForLegalReasons < ServiceError
200
+ http_status_code 451
201
+ end
202
+
203
+ # Raised when Github returns the HTTP status code 500
204
+ class InternalServerError < ServiceError
205
+ http_status_code 500
206
+ end
207
+
208
+ # Raised when Github returns the HTTP status code 501
209
+ class NotImplemented < ServiceError
210
+ http_status_code 501
211
+ end
212
+
213
+ # Raised when Github returns the HTTP status code 502
214
+ class BadGateway < ServiceError
215
+ http_status_code 502
216
+ end
217
+
218
+ # Raised when GitHub returns the HTTP status code 503
219
+ class ServiceUnavailable < ServiceError
220
+ http_status_code 503
221
+ end
222
+ end # Error
223
+ end # Github
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'descendants_tracker'
4
+
5
+ module Github
6
+ module Error
7
+ class GithubError < StandardError
8
+ extend DescendantsTracker
9
+
10
+ attr_reader :response_message, :response_headers
11
+
12
+ # Initialize a new Github error object.
13
+ #
14
+ def initialize(message = $!)
15
+ if message.respond_to?(:backtrace)
16
+ super(message.message)
17
+ @response_message = message
18
+ else
19
+ super(message.to_s)
20
+ end
21
+ end
22
+
23
+ def backtrace
24
+ if @response_message.respond_to?(:backtrace)
25
+ @response_message.backtrace
26
+ else
27
+ super
28
+ end
29
+ end
30
+ end # GithubError
31
+ end # Error
32
+ end # Github
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ module Faraday
4
+ module Utils
5
+
6
+ class ParamsHash
7
+ def params_encoder(encoder = nil)
8
+ if encoder
9
+ @encoder = encoder
10
+ elsif defined?(@encoder)
11
+ @encoder
12
+ end
13
+ end
14
+
15
+ def to_query(encoder = nil)
16
+ Utils.build_nested_query(self, nil, params_encoder)
17
+ end
18
+ end
19
+
20
+ module_function
21
+
22
+ def build_nested_query(value, prefix = nil, encoder = nil)
23
+ case value
24
+ when Array
25
+ value.map { |v| build_nested_query(v, "#{prefix}%5B%5D", encoder) }.join("&")
26
+ when Hash
27
+ value.map { |k, v|
28
+ processed_value = encoder ? encoder.escape(k) : escape(k)
29
+ build_nested_query(v, prefix ? "#{prefix}%5B#{processed_value}%5D" : processed_value, encoder)
30
+ }.join("&")
31
+ when NilClass
32
+ prefix
33
+ else
34
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
35
+ processed_value = encoder ? encoder.escape(value) : escape(value)
36
+ "#{prefix}=#{processed_value}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Github
4
+ class Mash < ::Hashie::Mash
5
+ disable_warnings
6
+ end
7
+ end