github_api 0.3.5 → 0.3.6

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 (147) hide show
  1. data/LICENSE.txt +20 -0
  2. data/README.rdoc +228 -0
  3. data/Rakefile +52 -0
  4. data/features/github_api.feature +50 -0
  5. data/features/options.feature +4 -0
  6. data/features/pagination.feature +4 -0
  7. data/features/step_definitions/github_api_steps.rb +11 -0
  8. data/features/support/env.rb +13 -0
  9. data/lib/github_api.rb +73 -0
  10. data/lib/github_api/api.rb +175 -0
  11. data/lib/github_api/api/utils.rb +9 -0
  12. data/lib/github_api/authorization.rb +73 -0
  13. data/lib/github_api/authorizations.rb +119 -0
  14. data/lib/github_api/cache_control.rb +19 -0
  15. data/lib/github_api/client.rb +55 -0
  16. data/lib/github_api/compatibility.rb +23 -0
  17. data/lib/github_api/configuration.rb +96 -0
  18. data/lib/github_api/connection.rb +75 -0
  19. data/lib/github_api/core_ext/array.rb +14 -0
  20. data/lib/github_api/core_ext/hash.rb +42 -0
  21. data/lib/github_api/error.rb +35 -0
  22. data/lib/github_api/events.rb +202 -0
  23. data/lib/github_api/gists.rb +200 -0
  24. data/lib/github_api/gists/comments.rb +86 -0
  25. data/lib/github_api/git_data.rb +26 -0
  26. data/lib/github_api/git_data/blobs.rb +51 -0
  27. data/lib/github_api/git_data/commits.rb +78 -0
  28. data/lib/github_api/git_data/references.rb +113 -0
  29. data/lib/github_api/git_data/tags.rb +78 -0
  30. data/lib/github_api/git_data/trees.rb +89 -0
  31. data/lib/github_api/issues.rb +215 -0
  32. data/lib/github_api/issues/comments.rb +123 -0
  33. data/lib/github_api/issues/events.rb +54 -0
  34. data/lib/github_api/issues/labels.rb +191 -0
  35. data/lib/github_api/issues/milestones.rb +140 -0
  36. data/lib/github_api/mime_type.rb +55 -0
  37. data/lib/github_api/orgs.rb +95 -0
  38. data/lib/github_api/orgs/members.rb +120 -0
  39. data/lib/github_api/orgs/teams.rb +245 -0
  40. data/lib/github_api/pull_requests.rb +224 -0
  41. data/lib/github_api/pull_requests/comments.rb +144 -0
  42. data/lib/github_api/repos.rb +286 -0
  43. data/lib/github_api/repos/collaborators.rb +81 -0
  44. data/lib/github_api/repos/commits.rb +180 -0
  45. data/lib/github_api/repos/downloads.rb +155 -0
  46. data/lib/github_api/repos/forks.rb +48 -0
  47. data/lib/github_api/repos/hooks.rb +174 -0
  48. data/lib/github_api/repos/keys.rb +104 -0
  49. data/lib/github_api/repos/pub_sub_hubbub.rb +102 -0
  50. data/lib/github_api/repos/watching.rb +94 -0
  51. data/lib/github_api/request.rb +84 -0
  52. data/lib/github_api/request/basic_auth.rb +31 -0
  53. data/lib/github_api/request/caching.rb +33 -0
  54. data/lib/github_api/request/oauth2.rb +33 -0
  55. data/lib/github_api/response.rb +28 -0
  56. data/lib/github_api/response/helpers.rb +14 -0
  57. data/lib/github_api/response/jsonize.rb +26 -0
  58. data/lib/github_api/response/mashify.rb +24 -0
  59. data/lib/github_api/response/raise_error.rb +33 -0
  60. data/lib/github_api/result.rb +42 -0
  61. data/lib/github_api/users.rb +84 -0
  62. data/lib/github_api/users/emails.rb +49 -0
  63. data/lib/github_api/users/followers.rb +98 -0
  64. data/lib/github_api/users/keys.rb +84 -0
  65. data/lib/github_api/version.rb +12 -0
  66. data/spec/README.rdoc +22 -0
  67. data/spec/coverage_adapter.rb +15 -0
  68. data/spec/fixtures/auths/authorization.json +14 -0
  69. data/spec/fixtures/auths/authorizations.json +16 -0
  70. data/spec/fixtures/events/events.json +29 -0
  71. data/spec/fixtures/issues/comment.json +13 -0
  72. data/spec/fixtures/issues/comments.json +15 -0
  73. data/spec/fixtures/issues/event.json +13 -0
  74. data/spec/fixtures/issues/events.json +15 -0
  75. data/spec/fixtures/issues/issue.json +56 -0
  76. data/spec/fixtures/issues/issues.json +58 -0
  77. data/spec/fixtures/issues/milestone.json +18 -0
  78. data/spec/fixtures/issues/milestones.json +20 -0
  79. data/spec/fixtures/orgs/members.json +9 -0
  80. data/spec/fixtures/orgs/org.json +18 -0
  81. data/spec/fixtures/orgs/orgs.json +8 -0
  82. data/spec/fixtures/orgs/team.json +8 -0
  83. data/spec/fixtures/orgs/team_repos.json +29 -0
  84. data/spec/fixtures/orgs/teams.json +7 -0
  85. data/spec/fixtures/repos/branches.json +9 -0
  86. data/spec/fixtures/repos/collaborators.json +8 -0
  87. data/spec/fixtures/repos/commit.json +53 -0
  88. data/spec/fixtures/repos/commit_comment.json +16 -0
  89. data/spec/fixtures/repos/commit_comments.json +18 -0
  90. data/spec/fixtures/repos/commits.json +27 -0
  91. data/spec/fixtures/repos/contributors.json +8 -0
  92. data/spec/fixtures/repos/download.json +10 -0
  93. data/spec/fixtures/repos/download_s3.json +21 -0
  94. data/spec/fixtures/repos/downloads.json +12 -0
  95. data/spec/fixtures/repos/fork.json +27 -0
  96. data/spec/fixtures/repos/forks.json +29 -0
  97. data/spec/fixtures/repos/hook.json +15 -0
  98. data/spec/fixtures/repos/hooks.json +10 -0
  99. data/spec/fixtures/repos/key.json +6 -0
  100. data/spec/fixtures/repos/keys.json +8 -0
  101. data/spec/fixtures/repos/languages.json +4 -0
  102. data/spec/fixtures/repos/repo.json +90 -0
  103. data/spec/fixtures/repos/repo_comments.json +18 -0
  104. data/spec/fixtures/repos/repos.json +29 -0
  105. data/spec/fixtures/repos/tags.json +11 -0
  106. data/spec/fixtures/repos/teams.json +7 -0
  107. data/spec/fixtures/repos/watched.json +29 -0
  108. data/spec/fixtures/repos/watchers.json +8 -0
  109. data/spec/fixtures/users/user.json +32 -0
  110. data/spec/github/api_spec.rb +25 -0
  111. data/spec/github/authorization_spec.rb +176 -0
  112. data/spec/github/authorizations_spec.rb +242 -0
  113. data/spec/github/client_spec.rb +50 -0
  114. data/spec/github/core_ext/hash_spec.rb +44 -0
  115. data/spec/github/events_spec.rb +491 -0
  116. data/spec/github/gists/comments_spec.rb +5 -0
  117. data/spec/github/gists_spec.rb +5 -0
  118. data/spec/github/git_data/blobs_spec.rb +5 -0
  119. data/spec/github/git_data/commits_spec.rb +5 -0
  120. data/spec/github/git_data/references_spec.rb +5 -0
  121. data/spec/github/git_data/tags_spec.rb +5 -0
  122. data/spec/github/git_data/trees_spec.rb +5 -0
  123. data/spec/github/git_data_spec.rb +5 -0
  124. data/spec/github/issues/comments_spec.rb +254 -0
  125. data/spec/github/issues/events_spec.rb +153 -0
  126. data/spec/github/issues/labels_spec.rb +5 -0
  127. data/spec/github/issues/milestones_spec.rb +260 -0
  128. data/spec/github/issues_spec.rb +287 -0
  129. data/spec/github/mime_type_spec.rb +70 -0
  130. data/spec/github/orgs/members_spec.rb +275 -0
  131. data/spec/github/orgs/teams_spec.rb +563 -0
  132. data/spec/github/orgs_spec.rb +160 -0
  133. data/spec/github/repos/collaborators_spec.rb +169 -0
  134. data/spec/github/repos/commits_spec.rb +424 -0
  135. data/spec/github/repos/downloads_spec.rb +247 -0
  136. data/spec/github/repos/forks_spec.rb +108 -0
  137. data/spec/github/repos/hooks_spec.rb +333 -0
  138. data/spec/github/repos/keys_spec.rb +217 -0
  139. data/spec/github/repos/pub_sub_hubbub_spec.rb +83 -0
  140. data/spec/github/repos/watching_spec.rb +222 -0
  141. data/spec/github/repos_spec.rb +571 -0
  142. data/spec/github/result_spec.rb +43 -0
  143. data/spec/github/users_spec.rb +140 -0
  144. data/spec/github_spec.rb +109 -0
  145. data/spec/spec_helper.rb +86 -0
  146. data/spec/support/base.rb +13 -0
  147. metadata +149 -4
@@ -0,0 +1,175 @@
1
+ # encoding: utf-8
2
+
3
+ require 'github_api/configuration'
4
+ require 'github_api/connection'
5
+ require 'github_api/request'
6
+ require 'github_api/mime_type'
7
+ require 'github_api/core_ext/hash'
8
+ require 'github_api/core_ext/array'
9
+ require 'github_api/compatibility'
10
+
11
+ module Github
12
+
13
+ # @private
14
+ class API
15
+ include Authorization
16
+ include MimeType
17
+ include Connection
18
+ include Request
19
+
20
+ VALID_API_KEYS = [
21
+ :per_page,
22
+ :pagination
23
+ ]
24
+
25
+ attr_reader *Configuration::VALID_OPTIONS_KEYS
26
+ attr_accessor *VALID_API_KEYS
27
+
28
+ # Callback to update global configuration options
29
+ class_eval do
30
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
31
+ define_method "#{key}=" do |arg|
32
+ self.instance_variable_set("@#{key}", arg)
33
+ Github.send("#{key}=", arg)
34
+ end
35
+ end
36
+ end
37
+
38
+ # Creates new API
39
+ def initialize(options = {})
40
+ options = Github.options.merge(options)
41
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
42
+ send("#{key}=", options[key])
43
+ end
44
+ _process_basic_auth(options[:basic_auth])
45
+ client if client_id? && client_secret?
46
+ end
47
+
48
+ private
49
+
50
+ # Extract login and password from basic_auth parameter
51
+ def _process_basic_auth(auth)
52
+ case auth
53
+ when String
54
+ login = auth.split(':').first
55
+ password = auth.split(':').last
56
+ when Hash
57
+ login = auth[:login]
58
+ password = auth[:password]
59
+ end
60
+ end
61
+
62
+ # Responds to attribute query
63
+ def method_missing(method, *args, &block) # :nodoc:
64
+ if method.to_s =~ /^(.*)\?$/
65
+ return !self.send($1.to_s).nil?
66
+ else
67
+ super
68
+ end
69
+ end
70
+
71
+ def _validate_inputs(required, provided) # :nodoc:
72
+ required.all? do |key|
73
+ provided.has_key? key
74
+ end
75
+ end
76
+
77
+ def _validate_presence_of(*params) # :nodoc:
78
+ params.each do |param|
79
+ raise ArgumentError, "parameter cannot be nil" if param.nil?
80
+ end
81
+ end
82
+
83
+ def _validate_user_repo_params(user_name, repo_name) # :nodoc:
84
+ raise ArgumentError, "[user] parameter cannot be nil" if user_name.nil?
85
+ raise ArgumentError, "[repo] parameter cannot be nil" if repo_name.nil?
86
+ end
87
+
88
+ def _update_user_repo_params(user_name, repo_name=nil) # :nodoc:
89
+ self.user = user_name || self.user
90
+ self.repo = repo_name || self.repo
91
+ end
92
+
93
+ def _merge_user_into_params!(params) # :nodoc:
94
+ params.merge!({ 'user' => self.user }) if user?
95
+ end
96
+
97
+ def _merge_user_repo_into_params!(params) # :nodoc:
98
+ { 'user' => self.user, 'repo' => self.repo }.merge!(params)
99
+ end
100
+
101
+ # Turns any keys from nested hashes including nested arrays into strings
102
+ def _normalize_params_keys(params) # :nodoc:
103
+ case params
104
+ when Hash
105
+ params.keys.each do |k|
106
+ params[k.to_s] = params.delete(k)
107
+ _normalize_params_keys(params[k.to_s])
108
+ end
109
+ when Array
110
+ params.map! do |el|
111
+ _normalize_params_keys(el)
112
+ end
113
+ else
114
+ params.to_s
115
+ end
116
+ return params
117
+ end
118
+
119
+ def _filter_params_keys(keys, params) # :nodoc:
120
+ params.reject! { |k,v| !keys.include? k }
121
+ end
122
+
123
+ def _hash_traverse(hash, &block)
124
+ hash.each do |key, val|
125
+ block.call(key)
126
+ case val
127
+ when Hash
128
+ val.keys.each do |k|
129
+ _hash_traverse(val, &block)
130
+ end
131
+ when Array
132
+ val.each do |item|
133
+ _hash_traverse(item, &block)
134
+ end
135
+ end
136
+ end
137
+ return hash
138
+ end
139
+
140
+ def _validate_params_values(options, params) # :nodoc:
141
+ params.each do |k, v|
142
+ next unless options.keys.include?(k)
143
+ if options[k].is_a?(Array) && !options[k].include?(params[k])
144
+ raise ArgumentError, "Wrong value for #{k}, allowed: #{options[k].join(', ')}"
145
+ elsif options[k].is_a?(Regexp) && !(options[k] =~ params[k])
146
+ raise ArgumentError, "String does not match the parameter value."
147
+ end
148
+ end
149
+ end
150
+
151
+ def _merge_mime_type(resource, params) # :nodoc:
152
+ params['resource'] = resource
153
+ params['mime_type'] = params['mime_type'] || :raw
154
+ end
155
+
156
+ # TODO add to core extensions
157
+ def _extract_parameters(array)
158
+ if array.last.is_a?(Hash) && array.last.instance_of?(Hash)
159
+ pop
160
+ else
161
+ {}
162
+ end
163
+ end
164
+
165
+ # Passes configuration options to instantiated class
166
+ def _create_instance(klass, options)
167
+ options.symbolize_keys!
168
+ klass.new(options)
169
+ end
170
+
171
+ def _token_required
172
+ end
173
+
174
+ end # API
175
+ end # Github
@@ -0,0 +1,9 @@
1
+ module Github
2
+ class API
3
+ module Utils
4
+
5
+ private
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+ module Authorization
5
+
6
+ attr_accessor :scopes
7
+
8
+ # Setup OAuth2 instance
9
+ def client
10
+ @client ||= ::OAuth2::Client.new(client_id, client_secret,
11
+ :site => 'https://github.com',
12
+ :authorize_url => 'login/oauth/authorize',
13
+ :token_url => 'login/oauth/access_token'
14
+ )
15
+ end
16
+
17
+ # Strategy token
18
+ def auth_code
19
+ _verify_client
20
+ @client.auth_code
21
+ end
22
+
23
+ # Sends authorization request to GitHub.
24
+ # = Parameters
25
+ # * <tt>:redirect_uri</tt> - Required string.
26
+ # * <tt>:scope</tt> - Optional string. Comma separated list of scopes.
27
+ # Available scopes:
28
+ # * (no scope) - public read-only access (includes public user profile info, public repo info, and gists).
29
+ # * <tt>user</tt> - DB read/write access to profile info only.
30
+ # * <tt>public_repo</tt> - DB read/write access, and Git read access to public repos.
31
+ # * <tt>repo</tt> - DB read/write access, and Git read access to public and private repos.
32
+ # * <tt>gist</tt> - write access to gists.
33
+ #
34
+ def authorize_url(params = {})
35
+ _verify_client
36
+ @client.auth_code.authorize_url(params)
37
+ end
38
+
39
+ # Makes request to token endpoint and retrieves access token value
40
+ def get_token(authorization_code, params = {})
41
+ _verify_client
42
+ @client.auth_code.get_token(authorization_code, params)
43
+ end
44
+
45
+ # Check whether authentication credentials are present
46
+ def authenticated?
47
+ basic_authed? || oauth_token?
48
+ end
49
+
50
+ # Check whether basic authentication credentials are present
51
+ def basic_authed?
52
+ basic_auth? || (login? && password?)
53
+ end
54
+
55
+ # Select authentication parameters
56
+ def authentication
57
+ if login? && password?
58
+ { :login => login, :password => password }
59
+ elsif basic_auth?
60
+ { :basic_auth => basic_auth }
61
+ else
62
+ { }
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def _verify_client # :nodoc:
69
+ raise ArgumentError, 'Need to provide client_id and client_secret' unless client_id? && client_secret?
70
+ end
71
+
72
+ end # Authorization
73
+ end # Github
@@ -0,0 +1,119 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+ class Authorizations < API
5
+
6
+ VALID_AUTH_PARAM_NAMES = %w[
7
+ scopes
8
+ add_scopes
9
+ remove_scopes
10
+ ].freeze
11
+
12
+ # Creates new OAuth Authorizations API
13
+ def initialize(options = {})
14
+ super(options)
15
+ end
16
+
17
+ # List authorizations
18
+ #
19
+ # = Examples
20
+ # @github = Github.new :basic_auth => 'login:password'
21
+ # @github.oauth.authorizations
22
+ # @github.oauth.authorizations { |auth| ... }
23
+ #
24
+ def authorizations(params={})
25
+ _check_if_authenticated
26
+ _normalize_params_keys(params)
27
+
28
+ response = get("/authorizations", params)
29
+ return response unless block_given?
30
+ response.each { |el| yield el }
31
+ end
32
+ alias :auths :authorizations
33
+ alias :list_auths :authorizations
34
+ alias :list_authorizations :authorizations
35
+
36
+ # Get a single authorization
37
+ #
38
+ # = Examples
39
+ # @github = Github.new :basic_auth => 'login:password'
40
+ # @github.oauth.authorization 'authorization-id'
41
+ #
42
+ def authorization(authorization_id, params={})
43
+ _validate_presence_of(authorization_id)
44
+ _check_if_authenticated
45
+ _normalize_params_keys params
46
+
47
+ get "/authorizations/#{authorization_id}", params
48
+ end
49
+ alias :auth :authorization
50
+ alias :get_auth :authorization
51
+ alias :get_authorization :authorization
52
+
53
+ # Create a new authorization
54
+ #
55
+ # = Inputs
56
+ # * <tt>:scopes</tt> - Optional array - A list of scopes that this authorization is in.
57
+ # = Examples
58
+ # @github = Github.new :basic_auth => 'login:password'
59
+ # @github.oauth.create_authorization
60
+ # "scopes" => ["public_repo"]
61
+ #
62
+ def create_authorization(params={})
63
+ _check_if_authenticated
64
+ _normalize_params_keys(params)
65
+ _filter_params_keys(VALID_AUTH_PARAM_NAMES, params)
66
+
67
+ post("/authorizations", params)
68
+ end
69
+ alias :create_auth :create_authorization
70
+
71
+ # Update an existing authorization
72
+ #
73
+ # = Inputs
74
+ # * <tt>:scopes</tt> - Optional array - A list of scopes that this authorization is in.
75
+ # * <tt>:add_scopes</tt> - Optional array - A list of scopes to add to this authorization.
76
+ # * <tt>:remove_scopes</tt> - Optional array - A list of scopes to remove from this authorization.
77
+ #
78
+ # = Examples
79
+ # @github = Github.new :basic_auth => 'login:password'
80
+ # @github.oauth.update_authorization
81
+ # "add_scopes" => ["repo"],
82
+ #
83
+ def update_authorization(authorization_id, params={})
84
+ _check_if_authenticated
85
+ _validate_presence_of(authorization_id)
86
+
87
+ _normalize_params_keys(params)
88
+ _filter_params_keys(VALID_AUTH_PARAM_NAMES, params)
89
+
90
+ patch("/authorizations/#{authorization_id}", params)
91
+ end
92
+ alias :update_auth :update_authorization
93
+
94
+ # Delete an authorization
95
+ #
96
+ # = Examples
97
+ # @github.oauth.delete_authorization 'authorization-id'
98
+ #
99
+ def delete_authorization(authorization_id, params={})
100
+ _check_if_authenticated
101
+ _validate_presence_of(authorization_id)
102
+
103
+ _normalize_params_keys(params)
104
+ _filter_params_keys(VALID_AUTH_PARAM_NAMES, params)
105
+
106
+ delete("/authorizations/#{authorization_id}", params)
107
+ end
108
+ alias :delete_auth :delete_authorization
109
+ alias :remove_auth :delete_authorization
110
+ alias :remove_authorization :delete_authorization
111
+
112
+ private
113
+
114
+ def _check_if_authenticated
115
+ raise ArgumentError, 'You can only access authentication tokens through Basic Authentication' unless authenticated?
116
+ end
117
+
118
+ end # Authorizations
119
+ end # Github
@@ -0,0 +1,19 @@
1
+ module Github
2
+ module CacheOptions
3
+ extend self
4
+
5
+ def self.option_accessor(key)
6
+ defined_method("#{key}=") { |value| }
7
+ end
8
+
9
+ private
10
+
11
+ def initialize_options(options={})
12
+ @default_options = {
13
+ 'type' => :memoization,
14
+
15
+ }
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+ class Client < API
5
+
6
+ def gists(options = {})
7
+ @gists ||= _create_instance Github::Gists, options
8
+ end
9
+
10
+ # The Git Database API gives you access to read and write raw Git objects
11
+ # to your Git database on GitHub and to list and update your references
12
+ # (branch heads and tags).
13
+ def git_data(options = {})
14
+ @git_data ||= _create_instance Github::GitData, options
15
+ end
16
+ alias :git :git_data
17
+
18
+ def issues(options = {})
19
+ @issues ||= _create_instance Github::Issues, options
20
+ end
21
+
22
+ def orgs(options = {})
23
+ @orgs ||= _create_instance Github::Orgs, options
24
+ end
25
+ alias :organizations :orgs
26
+
27
+ def pull_requests(options = {})
28
+ @pull_requests ||= _create_instance Github::PullRequests, options
29
+ end
30
+
31
+ def repos(options = {})
32
+ @repos ||= _create_instance Github::Repos, options
33
+ end
34
+ alias :repositories :repos
35
+
36
+ # Many of the resources on the users API provide a shortcut for getting
37
+ # information about the currently authenticated user.
38
+ def users(options = {})
39
+ @users ||= _create_instance Github::Users, options
40
+ end
41
+
42
+ # This is a read-only API to the GitHub events.
43
+ # These events power the various activity streams on the site.
44
+ def events(options = {})
45
+ @events ||= _create_instance Github::Events, options
46
+ end
47
+
48
+ # An API for users to manage their own tokens. You can only access your own
49
+ # tokens, and only through Basic Authentication.
50
+ def oauth(options = {})
51
+ @oauth ||= _create_instance Github::Authorizations, options
52
+ end
53
+
54
+ end # Client
55
+ end # Github