lingfennan-github_api 0.18.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.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +741 -0
  4. data/lib/github_api.rb +93 -0
  5. data/lib/github_api/api.rb +398 -0
  6. data/lib/github_api/api/actions.rb +60 -0
  7. data/lib/github_api/api/arguments.rb +253 -0
  8. data/lib/github_api/api/config.rb +105 -0
  9. data/lib/github_api/api/config/property.rb +30 -0
  10. data/lib/github_api/api/config/property_set.rb +120 -0
  11. data/lib/github_api/api/factory.rb +33 -0
  12. data/lib/github_api/authorization.rb +75 -0
  13. data/lib/github_api/client.rb +77 -0
  14. data/lib/github_api/client/activity.rb +31 -0
  15. data/lib/github_api/client/activity/events.rb +233 -0
  16. data/lib/github_api/client/activity/feeds.rb +50 -0
  17. data/lib/github_api/client/activity/notifications.rb +181 -0
  18. data/lib/github_api/client/activity/starring.rb +130 -0
  19. data/lib/github_api/client/activity/watching.rb +176 -0
  20. data/lib/github_api/client/authorizations.rb +142 -0
  21. data/lib/github_api/client/authorizations/app.rb +98 -0
  22. data/lib/github_api/client/emojis.rb +19 -0
  23. data/lib/github_api/client/gists.rb +289 -0
  24. data/lib/github_api/client/gists/comments.rb +100 -0
  25. data/lib/github_api/client/git_data.rb +31 -0
  26. data/lib/github_api/client/git_data/blobs.rb +51 -0
  27. data/lib/github_api/client/git_data/commits.rb +101 -0
  28. data/lib/github_api/client/git_data/references.rb +150 -0
  29. data/lib/github_api/client/git_data/tags.rb +95 -0
  30. data/lib/github_api/client/git_data/trees.rb +113 -0
  31. data/lib/github_api/client/gitignore.rb +57 -0
  32. data/lib/github_api/client/issues.rb +248 -0
  33. data/lib/github_api/client/issues/assignees.rb +77 -0
  34. data/lib/github_api/client/issues/comments.rb +146 -0
  35. data/lib/github_api/client/issues/events.rb +50 -0
  36. data/lib/github_api/client/issues/labels.rb +189 -0
  37. data/lib/github_api/client/issues/milestones.rb +146 -0
  38. data/lib/github_api/client/markdown.rb +62 -0
  39. data/lib/github_api/client/meta.rb +19 -0
  40. data/lib/github_api/client/orgs.rb +127 -0
  41. data/lib/github_api/client/orgs/hooks.rb +182 -0
  42. data/lib/github_api/client/orgs/members.rb +142 -0
  43. data/lib/github_api/client/orgs/memberships.rb +131 -0
  44. data/lib/github_api/client/orgs/projects.rb +57 -0
  45. data/lib/github_api/client/orgs/teams.rb +407 -0
  46. data/lib/github_api/client/projects.rb +83 -0
  47. data/lib/github_api/client/projects/cards.rb +158 -0
  48. data/lib/github_api/client/projects/columns.rb +146 -0
  49. data/lib/github_api/client/pull_requests.rb +195 -0
  50. data/lib/github_api/client/pull_requests/comments.rb +140 -0
  51. data/lib/github_api/client/pull_requests/reviews.rb +158 -0
  52. data/lib/github_api/client/repos.rb +468 -0
  53. data/lib/github_api/client/repos/branches.rb +48 -0
  54. data/lib/github_api/client/repos/branches/protections.rb +75 -0
  55. data/lib/github_api/client/repos/collaborators.rb +84 -0
  56. data/lib/github_api/client/repos/comments.rb +125 -0
  57. data/lib/github_api/client/repos/commits.rb +80 -0
  58. data/lib/github_api/client/repos/contents.rb +246 -0
  59. data/lib/github_api/client/repos/deployments.rb +138 -0
  60. data/lib/github_api/client/repos/downloads.rb +62 -0
  61. data/lib/github_api/client/repos/forks.rb +48 -0
  62. data/lib/github_api/client/repos/hooks.rb +214 -0
  63. data/lib/github_api/client/repos/keys.rb +104 -0
  64. data/lib/github_api/client/repos/merging.rb +47 -0
  65. data/lib/github_api/client/repos/pages.rb +48 -0
  66. data/lib/github_api/client/repos/projects.rb +62 -0
  67. data/lib/github_api/client/repos/pub_sub_hubbub.rb +133 -0
  68. data/lib/github_api/client/repos/releases.rb +189 -0
  69. data/lib/github_api/client/repos/releases/assets.rb +136 -0
  70. data/lib/github_api/client/repos/releases/tags.rb +24 -0
  71. data/lib/github_api/client/repos/statistics.rb +89 -0
  72. data/lib/github_api/client/repos/statuses.rb +91 -0
  73. data/lib/github_api/client/say.rb +25 -0
  74. data/lib/github_api/client/scopes.rb +46 -0
  75. data/lib/github_api/client/search.rb +133 -0
  76. data/lib/github_api/client/search/legacy.rb +111 -0
  77. data/lib/github_api/client/users.rb +117 -0
  78. data/lib/github_api/client/users/emails.rb +65 -0
  79. data/lib/github_api/client/users/followers.rb +115 -0
  80. data/lib/github_api/client/users/keys.rb +104 -0
  81. data/lib/github_api/configuration.rb +70 -0
  82. data/lib/github_api/connection.rb +82 -0
  83. data/lib/github_api/constants.rb +61 -0
  84. data/lib/github_api/core_ext/array.rb +25 -0
  85. data/lib/github_api/core_ext/hash.rb +91 -0
  86. data/lib/github_api/core_ext/ordered_hash.rb +107 -0
  87. data/lib/github_api/deprecation.rb +39 -0
  88. data/lib/github_api/error.rb +32 -0
  89. data/lib/github_api/error/client_error.rb +89 -0
  90. data/lib/github_api/error/service_error.rb +223 -0
  91. data/lib/github_api/ext/faraday.rb +38 -0
  92. data/lib/github_api/mash.rb +7 -0
  93. data/lib/github_api/middleware.rb +37 -0
  94. data/lib/github_api/mime_type.rb +33 -0
  95. data/lib/github_api/normalizer.rb +23 -0
  96. data/lib/github_api/null_encoder.rb +25 -0
  97. data/lib/github_api/page_iterator.rb +138 -0
  98. data/lib/github_api/page_links.rb +63 -0
  99. data/lib/github_api/paged_request.rb +42 -0
  100. data/lib/github_api/pagination.rb +115 -0
  101. data/lib/github_api/parameter_filter.rb +35 -0
  102. data/lib/github_api/params_hash.rb +115 -0
  103. data/lib/github_api/rate_limit.rb +25 -0
  104. data/lib/github_api/request.rb +85 -0
  105. data/lib/github_api/request/basic_auth.rb +36 -0
  106. data/lib/github_api/request/jsonize.rb +54 -0
  107. data/lib/github_api/request/oauth2.rb +44 -0
  108. data/lib/github_api/request/verbs.rb +63 -0
  109. data/lib/github_api/response.rb +48 -0
  110. data/lib/github_api/response/atom_parser.rb +22 -0
  111. data/lib/github_api/response/follow_redirects.rb +140 -0
  112. data/lib/github_api/response/header.rb +87 -0
  113. data/lib/github_api/response/jsonize.rb +28 -0
  114. data/lib/github_api/response/mashify.rb +24 -0
  115. data/lib/github_api/response/raise_error.rb +22 -0
  116. data/lib/github_api/response/xmlize.rb +27 -0
  117. data/lib/github_api/response_wrapper.rb +161 -0
  118. data/lib/github_api/ssl_certs/cacerts.pem +2183 -0
  119. data/lib/github_api/utils/url.rb +63 -0
  120. data/lib/github_api/validations.rb +22 -0
  121. data/lib/github_api/validations/format.rb +26 -0
  122. data/lib/github_api/validations/presence.rb +32 -0
  123. data/lib/github_api/validations/required.rb +21 -0
  124. data/lib/github_api/validations/token.rb +41 -0
  125. data/lib/github_api/version.rb +5 -0
  126. metadata +338 -0
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ module Github
6
+ class Response::AtomParser < Response
7
+ define_parser do |body|
8
+ require 'rss'
9
+ RSS::Parser.parse(body)
10
+ end
11
+
12
+ def initialize(app, options = {})
13
+ super(app, options.merge(content_type: /(\batom|\brss)/))
14
+ end
15
+
16
+ def on_complete(env)
17
+ if parse_body?(env)
18
+ process_body(env)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,140 @@
1
+ require 'faraday'
2
+ require 'set'
3
+
4
+ # First saw on octokit, then copied from lostisland/faraday_middleware
5
+ # and adapted for this library.
6
+ #
7
+ # faraday_middleware/lib/faraday_middleware/response/follow_redirects.rb
8
+
9
+ module Github
10
+ # Public: Exception thrown when the maximum amount of requests is exceeded.
11
+ class RedirectLimitReached < Faraday::Error::ClientError
12
+ attr_reader :response
13
+
14
+ def initialize(response)
15
+ super "too many redirects; last one to: #{response['location']}"
16
+ @response = response
17
+ end
18
+ end
19
+
20
+ # Public: Follow HTTP 301, 302, 303, 307, and 308 redirects.
21
+ #
22
+ # For HTTP 301, 302, and 303, the original GET, POST, PUT, DELETE, or PATCH
23
+ # request gets converted into a GET. With `:standards_compliant => true`,
24
+ # however, the HTTP method after 301/302 remains unchanged. This allows you
25
+ # to opt into HTTP/1.1 compliance and act unlike the major web browsers.
26
+ #
27
+ # This middleware currently only works with synchronous requests; i.e. it
28
+ # doesn't support parallelism.
29
+ #
30
+ # If you wish to persist cookies across redirects, you could use
31
+ # the faraday-cookie_jar gem:
32
+ #
33
+ # Faraday.new(:url => url) do |faraday|
34
+ # faraday.use FaradayMiddleware::FollowRedirects
35
+ # faraday.use :cookie_jar
36
+ # faraday.adapter Faraday.default_adapter
37
+ # end
38
+
39
+ class Response::FollowRedirects < Faraday::Middleware
40
+ # HTTP methods for which 30x redirects can be followed
41
+ ALLOWED_METHODS = Set.new [:head, :options, :get, :post, :put, :patch, :delete]
42
+ # HTTP redirect status codes that this middleware implements
43
+ REDIRECT_CODES = Set.new [301, 302, 303, 307, 308]
44
+ # Keys in env hash which will get cleared between requests
45
+ ENV_TO_CLEAR = Set.new [:status, :response, :response_headers]
46
+
47
+ # Default value for max redirects followed
48
+ FOLLOW_LIMIT = 3
49
+
50
+ # Regex that matches characters that need to be escaped in URLs, sans
51
+ # the "%" character which we assume already represents an escaped sequence.
52
+ URI_UNSAFE = /[^\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]%]/
53
+
54
+ # Public: Initialize the middleware.
55
+ #
56
+ # options - An options Hash (default: {}):
57
+ # :limit - A Numeric redirect limit (default: 3)
58
+ # :standards_compliant - A Boolean indicating whether to respect
59
+ # the HTTP spec when following 301/302
60
+ # (default: false)
61
+ # :callback - A callable that will be called on redirects
62
+ # with the old and new envs
63
+ def initialize(app, options = {})
64
+ super(app)
65
+ @options = options
66
+
67
+ @convert_to_get = Set.new [303]
68
+ @convert_to_get << 301 << 302 unless standards_compliant?
69
+ end
70
+
71
+ def call(env)
72
+ perform_with_redirection(env, follow_limit)
73
+ end
74
+
75
+ private
76
+
77
+ def convert_to_get?(response)
78
+ ![:head, :options].include?(response.env[:method]) &&
79
+ @convert_to_get.include?(response.status)
80
+ end
81
+
82
+ def perform_with_redirection(env, follows)
83
+ request_body = env[:body]
84
+ response = @app.call(env)
85
+
86
+ response.on_complete do |response_env|
87
+ if follow_redirect?(response_env, response)
88
+ raise RedirectLimitReached, response if follows.zero?
89
+ new_request_env = update_env(response_env.dup, request_body, response)
90
+ callback.call(response_env, new_request_env) if callback
91
+ response = perform_with_redirection(new_request_env, follows - 1)
92
+ end
93
+ end
94
+ response
95
+ end
96
+
97
+ def update_env(env, request_body, response)
98
+ env[:url] += safe_escape(response['location'])
99
+
100
+ if convert_to_get?(response)
101
+ env[:method] = :get
102
+ env[:body] = nil
103
+ else
104
+ env[:body] = request_body
105
+ end
106
+
107
+ ENV_TO_CLEAR.each {|key| env.delete key }
108
+
109
+ env
110
+ end
111
+
112
+ def follow_redirect?(env, response)
113
+ ALLOWED_METHODS.include? env[:method] and
114
+ REDIRECT_CODES.include? response.status
115
+ end
116
+
117
+ def follow_limit
118
+ @options.fetch(:limit, FOLLOW_LIMIT)
119
+ end
120
+
121
+ def standards_compliant?
122
+ @options.fetch(:standards_compliant, false)
123
+ end
124
+
125
+ def callback
126
+ @options[:callback]
127
+ end
128
+
129
+ # Internal: escapes unsafe characters from an URL which might be a path
130
+ # component only or a fully qualified URI so that it can be joined onto an
131
+ # URI:HTTP using the `+` operator. Doesn't escape "%" characters so to not
132
+ # risk double-escaping.
133
+ def safe_escape(uri)
134
+ uri = uri.split('#')[0] # we want to remove the fragment if present
135
+ uri.to_s.gsub(URI_UNSAFE) { |match|
136
+ '%' + match.unpack('H2' * match.bytesize).join('%').upcase
137
+ }
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,87 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative '../constants'
4
+
5
+ module Github
6
+ class Response
7
+
8
+ # Represents http response header
9
+ class Header < Struct.new(:env)
10
+ include Github::Constants
11
+
12
+ SUCCESSFUL_STATUSES = 200..299
13
+
14
+ def loaded?
15
+ !!env
16
+ end
17
+
18
+ def [](property)
19
+ loaded? ? env[:response_headers][property] : nil
20
+ end
21
+
22
+ def oauth_scopes
23
+ loaded? ? env[:response_headers][OAUTH_SCOPES] : nil
24
+ end
25
+
26
+ def accepted_oauth_scopes
27
+ loaded? ? env[:response_headers][ACCEPTED_OAUTH_SCOPES] : nil
28
+ end
29
+
30
+ # Requests are limited to API v3 to 5000 per hour.
31
+ def ratelimit_limit
32
+ loaded? ? env[:response_headers][RATELIMIT_LIMIT] : nil
33
+ end
34
+
35
+ def ratelimit_remaining
36
+ loaded? ? env[:response_headers][RATELIMIT_REMAINING] : nil
37
+ end
38
+
39
+ # A unix timestamp describing when the ratelimit will
40
+ # be reset
41
+ def ratelimit_reset
42
+ loaded? ? env[:response_headers][RATELIMIT_RESET] : nil
43
+ end
44
+
45
+ def cache_control
46
+ loaded? ? env[:response_headers][CACHE_CONTROL] : nil
47
+ end
48
+
49
+ def content_type
50
+ loaded? ? env[:response_headers][CONTENT_TYPE] : nil
51
+ end
52
+
53
+ def content_length
54
+ loaded? ? env[:response_headers][CONTENT_LENGTH] : nil
55
+ end
56
+
57
+ def etag
58
+ loaded? ? env[:response_headers][ETAG] : nil
59
+ end
60
+
61
+ def date
62
+ loaded? ? env[:response_headers][DATE] : nil
63
+ end
64
+
65
+ def location
66
+ loaded? ? env[:response_headers][LOCATION] : nil
67
+ end
68
+
69
+ def server
70
+ loaded? ? env[:response_headers][SERVER] : nil
71
+ end
72
+
73
+ def status
74
+ loaded? ? env[:status] : nil
75
+ end
76
+
77
+ def success?
78
+ SUCCESSFUL_STATUSES.include? status
79
+ end
80
+
81
+ # Returns raw body
82
+ def body
83
+ loaded? ? env[:body] : nil
84
+ end
85
+ end # Header
86
+ end # Response
87
+ end # Github
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+ require 'json'
5
+
6
+ module Github
7
+ class Response::Jsonize < Response
8
+
9
+ dependency 'json'
10
+
11
+ define_parser do |body|
12
+ JSON.parse(body)
13
+ end
14
+
15
+ def parse(body)
16
+ case body
17
+ when ''
18
+ nil
19
+ when 'true'
20
+ true
21
+ when 'false'
22
+ false
23
+ else
24
+ self.class.parser.call(body)
25
+ end
26
+ end
27
+ end # Response::Jsonize
28
+ end # Github
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+ require 'hashie'
5
+ require 'github_api/mash'
6
+
7
+ module Github
8
+ class Response::Mashify < Response
9
+ define_parser do |body|
10
+ ::Github::Mash.new body
11
+ end
12
+
13
+ def parse(body)
14
+ case body
15
+ when Hash
16
+ self.class.parser.call body
17
+ when Array
18
+ body.map { |item| item.is_a?(Hash) ? self.class.parser.call(item) : item }
19
+ else
20
+ body
21
+ end
22
+ end
23
+ end # Response::Mashify
24
+ end # Github
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ require_relative '../error/service_error'
6
+
7
+ module Github
8
+ class Response::RaiseError < Faraday::Response::Middleware
9
+ # Check if status code requires raising a ServiceError
10
+ #
11
+ # @api private
12
+ def on_complete(env)
13
+ status_code = env[:status].to_i
14
+ service_error = Github::Error::ServiceError
15
+ error_class = service_error.error_mapping[status_code]
16
+ if !error_class and (400...600) === status_code
17
+ error_class = service_error
18
+ end
19
+ raise error_class.new(env) if error_class
20
+ end
21
+ end # Response::RaiseError
22
+ end # Github
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ module Github
6
+ class Response::Xmlize < Response
7
+
8
+ dependency 'nokogiri'
9
+
10
+ define_parser do |body|
11
+ ::Nokogiri::XML body
12
+ end
13
+
14
+ def parse(body)
15
+ case body
16
+ when ''
17
+ nil
18
+ when 'true'
19
+ true
20
+ when 'false'
21
+ false
22
+ else
23
+ self.class.parser.call(body)
24
+ end
25
+ end
26
+ end # Response::Xmlize
27
+ end # Github
@@ -0,0 +1,161 @@
1
+ # encoding: utf-8
2
+
3
+ require 'forwardable'
4
+
5
+ require_relative 'pagination'
6
+
7
+ module Github
8
+ # A class responsible for proxing to faraday response
9
+ class ResponseWrapper
10
+ extend Forwardable
11
+ include Pagination
12
+ include Enumerable
13
+
14
+ attr_reader :response
15
+
16
+ attr_reader :current_api
17
+
18
+ attr_reader :env
19
+
20
+ def_delegators :body, :empty?, :size, :include?, :length, :to_a, :first, :flatten, :include?, :keys, :[]
21
+
22
+ def initialize(response, current_api)
23
+ @response = response
24
+ @current_api = current_api
25
+ @env = response.env
26
+ @body = nil
27
+ end
28
+
29
+ # Overwrite methods to hash keys
30
+ #
31
+ ['id', 'type', 'fork'].each do |method_name|
32
+ define_method(method_name) do
33
+ self.body.fetch(method_name.to_s)
34
+ end
35
+ end
36
+
37
+ # Request url
38
+ #
39
+ def url
40
+ response.env[:url].to_s
41
+ end
42
+
43
+ def body=(value)
44
+ @body = value
45
+ @env[:body] = value
46
+ end
47
+
48
+ # Response raw body
49
+ #
50
+ def body
51
+ @body ? @body : response.body
52
+ end
53
+
54
+ # Response status
55
+ #
56
+ def status
57
+ response.status
58
+ end
59
+
60
+ def success?
61
+ response.success?
62
+ end
63
+
64
+ def redirect?
65
+ status.to_i >= 300 && status.to_i < 400
66
+ end
67
+
68
+ def client_error?
69
+ status.to_i >= 400 && status.to_i < 500
70
+ end
71
+
72
+ def server_error?
73
+ status.to_i >= 500 && status.to_i < 600
74
+ end
75
+
76
+ # Return response headers
77
+ #
78
+ def headers
79
+ Github::Response::Header.new(env)
80
+ end
81
+
82
+ # Lookup an attribute from the body if hash, otherwise behave like array index.
83
+ # Convert any key to string before calling.
84
+ #
85
+ def [](key)
86
+ if self.body.is_a?(Array)
87
+ self.body[key]
88
+ else
89
+ self.body.send(:"#{key}")
90
+ end
91
+ end
92
+
93
+ # Return response body as string
94
+ #
95
+ def to_s
96
+ body.to_s
97
+ end
98
+
99
+ # Convert the ResponseWrapper into a Hash
100
+ #
101
+ def to_hash
102
+ body.to_hash
103
+ end
104
+
105
+ # Convert the ResponseWrapper into an Array
106
+ #
107
+ def to_ary
108
+ body.to_ary
109
+ end
110
+
111
+ # Iterate over each resource inside the body
112
+ #
113
+ def each
114
+ body_parts = self.body.respond_to?(:each) ? self.body : [self.body]
115
+ return body_parts.to_enum unless block_given?
116
+ body_parts.each { |part| yield(part) }
117
+ end
118
+
119
+ # Check if body has an attribute
120
+ #
121
+ def has_key?(key)
122
+ self.body.is_a?(Hash) && self.body.has_key?(key)
123
+ end
124
+
125
+ # Coerce any method calls for body attributes
126
+ #
127
+ def method_missing(method_name, *args, &block)
128
+ if self.has_key?(method_name.to_s)
129
+ self.[](method_name, &block)
130
+ else
131
+ super
132
+ end
133
+ end
134
+
135
+ # Check if method is defined on the body
136
+ #
137
+ def respond_to?(method_name, include_all = false)
138
+ if self.has_key?(method_name.to_s)
139
+ true
140
+ else
141
+ super
142
+ end
143
+ end
144
+
145
+ # Print only response body
146
+ #
147
+ def inspect
148
+ "#<#{self.class.name} @body=\"#{self.body}\">"
149
+ end
150
+
151
+ # Compare the wrapper with other wrapper for equality
152
+ #
153
+ def ==(other)
154
+ return false unless other.is_a?(self.class)
155
+ return false unless (other.respond_to?(:env) && other.respond_to?(:body))
156
+ self.env == other.env && self.body == other.body
157
+ end
158
+ alias eql? ==
159
+
160
+ end # ResponseWrapper
161
+ end # Github