github_api 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
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