codenamev_bitbucket_api 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +43 -0
  3. data/README.md +169 -0
  4. data/Rakefile +3 -0
  5. data/lib/bitbucket_rest_api/api/actions.rb +50 -0
  6. data/lib/bitbucket_rest_api/api/arguments.rb +248 -0
  7. data/lib/bitbucket_rest_api/api/config/property.rb +30 -0
  8. data/lib/bitbucket_rest_api/api/config/property_set.rb +118 -0
  9. data/lib/bitbucket_rest_api/api/config.rb +107 -0
  10. data/lib/bitbucket_rest_api/api/factory.rb +29 -0
  11. data/lib/bitbucket_rest_api/api.rb +242 -0
  12. data/lib/bitbucket_rest_api/authorization.rb +34 -0
  13. data/lib/bitbucket_rest_api/client/invitations.rb +16 -0
  14. data/lib/bitbucket_rest_api/client/issues/comments.rb +109 -0
  15. data/lib/bitbucket_rest_api/client/issues/components.rb +103 -0
  16. data/lib/bitbucket_rest_api/client/issues/milestones.rb +103 -0
  17. data/lib/bitbucket_rest_api/client/issues.rb +214 -0
  18. data/lib/bitbucket_rest_api/client/repos/changesets.rb +55 -0
  19. data/lib/bitbucket_rest_api/client/repos/following.rb +40 -0
  20. data/lib/bitbucket_rest_api/client/repos/keys.rb +88 -0
  21. data/lib/bitbucket_rest_api/client/repos/pull_requests/comments.rb +42 -0
  22. data/lib/bitbucket_rest_api/client/repos/pull_requests/commits.rb +24 -0
  23. data/lib/bitbucket_rest_api/client/repos/pull_requests.rb +199 -0
  24. data/lib/bitbucket_rest_api/client/repos/services.rb +104 -0
  25. data/lib/bitbucket_rest_api/client/repos/sources.rb +32 -0
  26. data/lib/bitbucket_rest_api/client/repos.rb +224 -0
  27. data/lib/bitbucket_rest_api/client/user.rb +96 -0
  28. data/lib/bitbucket_rest_api/client/users/account.rb +54 -0
  29. data/lib/bitbucket_rest_api/client/users.rb +14 -0
  30. data/lib/bitbucket_rest_api/client.rb +54 -0
  31. data/lib/bitbucket_rest_api/compatibility.rb +23 -0
  32. data/lib/bitbucket_rest_api/configuration.rb +59 -0
  33. data/lib/bitbucket_rest_api/connection.rb +61 -0
  34. data/lib/bitbucket_rest_api/constants.rb +50 -0
  35. data/lib/bitbucket_rest_api/core_ext/array.rb +17 -0
  36. data/lib/bitbucket_rest_api/core_ext/hash.rb +56 -0
  37. data/lib/bitbucket_rest_api/core_ext/ordered_hash.rb +107 -0
  38. data/lib/bitbucket_rest_api/deprecation.rb +39 -0
  39. data/lib/bitbucket_rest_api/error/bad_request.rb +12 -0
  40. data/lib/bitbucket_rest_api/error/client_error.rb +20 -0
  41. data/lib/bitbucket_rest_api/error/forbidden.rb +12 -0
  42. data/lib/bitbucket_rest_api/error/internal_server_error.rb +12 -0
  43. data/lib/bitbucket_rest_api/error/invalid_options.rb +18 -0
  44. data/lib/bitbucket_rest_api/error/not_found.rb +12 -0
  45. data/lib/bitbucket_rest_api/error/required_params.rb +18 -0
  46. data/lib/bitbucket_rest_api/error/service_error.rb +19 -0
  47. data/lib/bitbucket_rest_api/error/service_unavailable.rb +12 -0
  48. data/lib/bitbucket_rest_api/error/unauthorized.rb +12 -0
  49. data/lib/bitbucket_rest_api/error/unknown_value.rb +18 -0
  50. data/lib/bitbucket_rest_api/error/unprocessable_entity.rb +12 -0
  51. data/lib/bitbucket_rest_api/error/validations.rb +18 -0
  52. data/lib/bitbucket_rest_api/error.rb +35 -0
  53. data/lib/bitbucket_rest_api/ext/faraday.rb +38 -0
  54. data/lib/bitbucket_rest_api/middleware.rb +31 -0
  55. data/lib/bitbucket_rest_api/normalizer.rb +27 -0
  56. data/lib/bitbucket_rest_api/null_encoder.rb +25 -0
  57. data/lib/bitbucket_rest_api/page_iterator.rb +90 -0
  58. data/lib/bitbucket_rest_api/page_links.rb +33 -0
  59. data/lib/bitbucket_rest_api/paged_request.rb +29 -0
  60. data/lib/bitbucket_rest_api/pagination.rb +97 -0
  61. data/lib/bitbucket_rest_api/parameter_filter.rb +32 -0
  62. data/lib/bitbucket_rest_api/params_hash.rb +100 -0
  63. data/lib/bitbucket_rest_api/request/basic_auth.rb +33 -0
  64. data/lib/bitbucket_rest_api/request/jsonize.rb +51 -0
  65. data/lib/bitbucket_rest_api/request/oauth.rb +51 -0
  66. data/lib/bitbucket_rest_api/request/verbs.rb +53 -0
  67. data/lib/bitbucket_rest_api/request.rb +91 -0
  68. data/lib/bitbucket_rest_api/response/header.rb +68 -0
  69. data/lib/bitbucket_rest_api/response/helpers.rb +21 -0
  70. data/lib/bitbucket_rest_api/response/jsonize.rb +30 -0
  71. data/lib/bitbucket_rest_api/response/mashify.rb +24 -0
  72. data/lib/bitbucket_rest_api/response/raise_error.rb +31 -0
  73. data/lib/bitbucket_rest_api/response/xmlize.rb +26 -0
  74. data/lib/bitbucket_rest_api/response.rb +28 -0
  75. data/lib/bitbucket_rest_api/response_wrapper.rb +157 -0
  76. data/lib/bitbucket_rest_api/result.rb +68 -0
  77. data/lib/bitbucket_rest_api/users.rb +20 -0
  78. data/lib/bitbucket_rest_api/utils/url.rb +56 -0
  79. data/lib/bitbucket_rest_api/validations/format.rb +24 -0
  80. data/lib/bitbucket_rest_api/validations/presence.rb +30 -0
  81. data/lib/bitbucket_rest_api/validations/required.rb +24 -0
  82. data/lib/bitbucket_rest_api/validations/token.rb +43 -0
  83. data/lib/bitbucket_rest_api/validations.rb +25 -0
  84. data/lib/bitbucket_rest_api/version.rb +11 -0
  85. data/lib/bitbucket_rest_api.rb +136 -0
  86. metadata +238 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cc4fce64074332f0f3496e0f986c20b07565720e91cdfabcd64c05235c6b49ad
4
+ data.tar.gz: d8dd76817622dc3c600f5aafddec3caa21f8fe9dca64e67ca5f3cf2c09b76414
5
+ SHA512:
6
+ metadata.gz: 69ab08f6cb0db0b7ecf33b072b793f40858fb30bc9194f2986ad30604894e1b33d81611f5b4b48cc0159ddb80effd2978918ffd829f0990e1c0c132ec01ba813
7
+ data.tar.gz: 983e6da829c7c7015f88971ef092dee0b94f7febb9247e29581806b631e195779802a1fea132b05c7fcaf23c9e940b27896fbef1e3ca4d3aca8ebf951cf4d7f7
data/LICENSE.txt ADDED
@@ -0,0 +1,43 @@
1
+ Copyright (c) 2013 James M Cochran
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+
23
+ Original github_api project:
24
+ Copyright (c) 2011 Piotr Murach
25
+
26
+ Permission is hereby granted, free of charge, to any person obtaining
27
+ a copy of this software and associated documentation files (the
28
+ "Software"), to deal in the Software without restriction, including
29
+ without limitation the rights to use, copy, modify, merge, publish,
30
+ distribute, sublicense, and/or sell copies of the Software, and to
31
+ permit persons to whom the Software is furnished to do so, subject to
32
+ the following conditions:
33
+
34
+ The above copyright notice and this permission notice shall be
35
+ included in all copies or substantial portions of the Software.
36
+
37
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
40
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
41
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
42
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
43
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # BitBucketAPI
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/bitbucket_rest_api.png)](http://badge.fury.io/rb/bitbucket_rest_api)
4
+
5
+ [Wiki](https://github.com/vongrippen/bitbucket/wiki) | [RDocs](http://rubydoc.info/github/vongrippen/bitbucket/master/frames)
6
+
7
+ A Ruby wrapper for the BitBucket REST API.
8
+
9
+ ## Installation
10
+
11
+ Install the gem by issuing
12
+
13
+ ```ruby
14
+ gem install bitbucket_rest_api
15
+ ```
16
+
17
+ or put it in your Gemfile and run `bundle install`
18
+
19
+ ```ruby
20
+ gem "bitbucket_rest_api"
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ Create a new client instance
26
+
27
+ ```ruby
28
+ bitbucket = BitBucket.new
29
+ ```
30
+
31
+ At this stage you can also supply various configuration parameters, such as `:user`,`:repo`, `:oauth_token`, `:oauth_secret`, `:basic_auth` which are used throughout the API. These can be passed directly as hash options:
32
+
33
+ ```ruby
34
+ bitbucket = BitBucket.new oauth_token: 'request_token', oauth_secret: 'request_secret'
35
+ ```
36
+
37
+ Alternatively, you can configure the BitBucket settings by passing a block:
38
+
39
+ ```ruby
40
+ bitbucket = BitBucket.new do |config|
41
+ config.oauth_token = 'request_token'
42
+ config.oauth_secret = 'request_secret'
43
+ config.client_id = 'consumer_key'
44
+ config.client_secret = 'consumer_secret'
45
+ config.adapter = :net_http
46
+ end
47
+ ```
48
+
49
+ You can authenticate either using OAuth authentication or through basic authentication by passing your login and password credentials
50
+
51
+ ```ruby
52
+ bitbucket = BitBucket.new login:'vongrippen', password:'...'
53
+ ```
54
+
55
+ or use convenience method:
56
+
57
+ ```ruby
58
+ bitbucket = BitBucket.new basic_auth: 'login:password'
59
+ ```
60
+
61
+ You can interact with BitBucket interface, for example repositories, by issuing following calls that correspond directly to the BitBucket API hierarchy
62
+
63
+ ```ruby
64
+ bitbucket.repos.changesets.all 'user-name', 'repo-name'
65
+ bitbucket.repos.keys.list 'user-name', 'repo-name'
66
+ ```
67
+
68
+ The response is of type [Hashie::Mash] and allows to traverse all the json response attributes like method calls.
69
+
70
+ ## Inputs
71
+
72
+ Some API methods apart from required parameters such as username or repository name
73
+ allow you to switch the way the data is returned to you, for instance by passing
74
+ a block you can iterate over the list of repositories
75
+
76
+ ```ruby
77
+ bitbucket.repos.list do |repo|
78
+ puts repo.slug
79
+ end
80
+ ```
81
+
82
+ ## Advanced Configuration
83
+
84
+ The `bitbucket_rest_api` gem will use the default middleware stack which is exposed by calling `stack` on client instance. However, this stack can be freely modified with methods such as `insert`, `insert_after`, `delete` and `swap`. For instance to add your `CustomMiddleware` do
85
+
86
+ ```ruby
87
+ bitbucket = BitBucket.new do |config|
88
+ config.stack.insert_after BitBucket::Response::Helpers, CustomMiddleware
89
+ end
90
+ ```
91
+
92
+ Furthermore, you can build your entire custom stack and specify other connection options such as `adapter`
93
+
94
+ ```ruby
95
+ bitbucket = BitBucket.new do |config|
96
+ config.adapter :excon
97
+
98
+ config.stack do |builder|
99
+ builder.use BitBucket::Response::Helpers
100
+ builder.use BitBucket::Response::Jsonize
101
+ end
102
+ end
103
+ ```
104
+
105
+ ## API
106
+
107
+ Main API methods are grouped into the following classes that can be instantiated on their own
108
+
109
+ ```ruby
110
+ BitBucket - full API access
111
+
112
+ BitBucket::Repos BitBucket::Issues
113
+ ```
114
+
115
+ Some parts of BitBucket API require you to be authenticated, for instance the following are examples of APIs only for the authenticated user
116
+
117
+ ```ruby
118
+ BitBucket::Issues::Create
119
+ ```
120
+
121
+ You can find out supported methods by calling `actions` on a class instance in your `irb`:
122
+
123
+ ```ruby
124
+ >> BitBucket::Repos.actions >> bitbucket.issues.actions
125
+ --- ---
126
+ |--> all |--> all
127
+ |--> branches |--> comments
128
+ |--> collaborators |--> create
129
+ |--> commits |--> edit
130
+ |--> contribs |--> events
131
+ |--> contributors |--> find
132
+ |--> create |--> get
133
+ |--> downloads |--> labels
134
+ |--> edit |--> list
135
+ |--> find |--> list_repo
136
+ |--> forks |--> list_repository
137
+ |--> get |--> milestones
138
+ |--> hooks ...
139
+ ...
140
+ ```
141
+
142
+ ## Configuration
143
+
144
+ Certain methods require authentication. To get your BitBucket OAuth credentials,
145
+ register an app with BitBucket.
146
+
147
+ ```ruby
148
+ BitBucket.configure do |config|
149
+ config.oauth_token = YOUR_OAUTH_REQUEST_TOKEN # Different for each user
150
+ config.oauth_secret = YOUR_OAUTH_REQUEST_TOKEN_SECRET # Differenct for each user
151
+ config.client_id = YOUR_OAUTH_CONSUMER_TOKEN
152
+ config.client_secret = YOUR_OAUTH_CONSUMER_TOKEN_SECRET
153
+ config.basic_auth = 'login:password'
154
+ end
155
+
156
+ or
157
+
158
+ BitBucket.new(:oauth_token => YOUR_OAUTH_REQUEST_TOKEN, :oauth_secret => YOUR_OAUTH_REQUEST_TOKEN_SECRET)
159
+ BitBucket.new(:basic_auth => 'login:password')
160
+ ```
161
+
162
+ ## Development
163
+
164
+ Questions or problems? Please post them on the [issue tracker](https://bitbucket.com/vongrippen/bitbucket/issues). You can contribute changes by forking the project and submitting a pull request. You can ensure the tests are passing by running `bundle` and `rake`.
165
+
166
+ ## Copyright
167
+
168
+ Copyright (c) 2012 James M Cochran.
169
+ Original github_api gem Copyright (c) 2011-2012 Piotr Murach. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/gem_tasks'
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ class API
5
+
6
+ # Returns all API public methods for a given class.
7
+ def self.inherited(klass)
8
+ klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
9
+ def self.actions
10
+ self.new.api_methods_in(#{klass})
11
+ end
12
+ def actions
13
+ api_methods_in(#{klass})
14
+ end
15
+ RUBY_EVAL
16
+ super
17
+ end
18
+
19
+ def api_methods_in(klass)
20
+ puts "---"
21
+ (klass.send(:instance_methods, false) - ['actions']).sort.each do |method|
22
+ puts "|--> #{method}"
23
+ end
24
+ klass.included_modules.each do |mod|
25
+ if mod.to_s =~ /#{klass}/
26
+ puts "| \\ #{mod.to_s}"
27
+ mod.instance_methods(false).each do |met|
28
+ puts "| |--> #{met}"
29
+ end
30
+ puts "| /"
31
+ end
32
+ end
33
+ puts "---"
34
+ nil
35
+ end
36
+
37
+ def append_arguments(method)
38
+ _method = self.method(method)
39
+ if _method.arity == 0
40
+ args = "()"
41
+ elsif _method.arity > 0
42
+ args = "(few)"
43
+ else
44
+ args = "(else)"
45
+ end
46
+ args
47
+ end
48
+
49
+ end # API
50
+ end # BitBucket
@@ -0,0 +1,248 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ class API
5
+ # A class responsible for handilng request arguments
6
+ class Arguments
7
+ include Normalizer
8
+ include ParameterFilter
9
+ include Validations
10
+
11
+ AUTO_PAGINATION = 'auto_pagination'.freeze
12
+
13
+ # Parameters passed to request
14
+ attr_reader :params
15
+
16
+ # The remaining unparsed arguments
17
+ attr_reader :remaining
18
+
19
+ # The request api
20
+ attr_reader :api
21
+
22
+ # Initialize an Arguments
23
+ #
24
+ # @param [Hash] options
25
+ #
26
+ # @option options [Array[String]] :required
27
+ # arguments that must be present before request is fired
28
+ #
29
+ # @option options [BitBucket::API] :api
30
+ # the reference to the current api
31
+ #
32
+ # @api public
33
+ def initialize(options = {}, &block)
34
+ normalize! options
35
+
36
+ @api = options.fetch('api')
37
+ @required = options.fetch('required', []).map(&:to_s)
38
+ @optional = options.fetch('optional', []).map(&:to_s)
39
+ @assigns = {}
40
+
41
+ yield_or_eval(&block)
42
+ end
43
+
44
+ # Specify required attribute(s)
45
+ #
46
+ # @api public
47
+ def require(*attrs, &block)
48
+ attrs_clone = attrs.clone
49
+ @required = Array(attrs_clone)
50
+ self
51
+ end
52
+ alias :required :require
53
+
54
+ # Specify optional attribute(s)
55
+ #
56
+ # @api public
57
+ def optional(*attrs, &block)
58
+ end
59
+
60
+ # Hash like access to request arguments
61
+ #
62
+ # @param [String, Symbol] property
63
+ # the property name
64
+ #
65
+ # @api public
66
+ def [](property)
67
+ @assigns[property.to_s]
68
+ end
69
+
70
+ def []=(property, value)
71
+ @assigns[property.to_s] = value
72
+ end
73
+
74
+ def method_missing(method_name, *args, &block)
75
+ if @assigns.key?(method_name.to_s)
76
+ self[method_name]
77
+ else
78
+ super
79
+ end
80
+ end
81
+
82
+ def respond_to_missing?(method_name, include_private = false)
83
+ @assigns.key?(method_name) || super
84
+ end
85
+
86
+ # Parse arguments to allow for flexible api calls
87
+ #
88
+ # Arguments can be part of parameters hash or be simple string arguments.
89
+ #
90
+ # @api public
91
+ def parse(*args, &block)
92
+ options = ParamsHash.new(args.extract_options!)
93
+ normalize! options
94
+
95
+ if args.size.zero? # Arguments are inside the parameters hash
96
+ parse_hash(options)
97
+ else
98
+ parse_array(*args)
99
+ end
100
+ @params = options
101
+ @remaining = args[@required.size..-1]
102
+ extract_pagination(options)
103
+
104
+ yield_or_eval(&block)
105
+ self
106
+ end
107
+
108
+ # Remove unknown keys from parameters hash.
109
+ #
110
+ # = Parameters
111
+ # :recursive - boolean that toggles whether nested filtering should be applied
112
+ #
113
+ def permit(keys, key=nil, options={})
114
+ filter! keys, (key.nil? ? params : params[key]), options if keys.any?
115
+ self
116
+ end
117
+
118
+ # Check if required keys are present inside parameters hash.
119
+ #
120
+ # @api public
121
+ def assert_required(required)
122
+ assert_required_keys required, params
123
+ self
124
+ end
125
+
126
+ # Check if parameters match expected values.
127
+ #
128
+ # @api public
129
+ def assert_values(values, key=nil)
130
+ assert_valid_values values, (key.nil? ? params : params[key])
131
+ self
132
+ end
133
+
134
+ private
135
+
136
+ # Parse array arguments and assign in order to required properties
137
+ #
138
+ # @param [Array[Object]] args
139
+ #
140
+ # @raise ArgumentError
141
+ #
142
+ # @return [nil]
143
+ #
144
+ # @api public
145
+ def parse_array(*args)
146
+ assert_presence_of(*args)
147
+ @required.each_with_index do |req, indx|
148
+ @assigns[req] = args[indx]
149
+ end
150
+ check_requirement!(*args)
151
+ end
152
+
153
+ # Remove required arguments from parameters and
154
+ # validate their presence(if not nil or empty string).
155
+ #
156
+ # @param [Hash[String]] options
157
+ #
158
+ # @return [nil]
159
+ #
160
+ # @api private
161
+ def parse_hash(options)
162
+ options.each { |key, val| remove_required(options, key, val) }
163
+ hash = update_required_from_global
164
+ check_requirement!(*hash.keys)
165
+ end
166
+
167
+ # Remove required property from hash
168
+ #
169
+ # @param [Hash[String]] options
170
+ # the options to check
171
+ #
172
+ # @param [String] key
173
+ # the key to remove
174
+ #
175
+ # @param [String] val
176
+ # the value to assign
177
+ #
178
+ # @api private
179
+ def remove_required(options, key, val)
180
+ if @required.include?(key.to_s)
181
+ assert_presence_of(val)
182
+ options.delete(key)
183
+ @assigns[key.to_s] = val
184
+ end
185
+ end
186
+
187
+ # Update required property from globals if not present
188
+ #
189
+ # @return [Hash[String]]
190
+ #
191
+ # @api private
192
+ def update_required_from_global
193
+ @required.reduce({}) do |hash, property|
194
+ if @assigns.key?(property)
195
+ hash[property] = self[property]
196
+ elsif api_property?(property)
197
+ hash[property] = api.send(:"#{property}")
198
+ self[property] = hash[property]
199
+ end
200
+ hash
201
+ end
202
+ end
203
+
204
+ # Check if api has non-empty property
205
+ #
206
+ # @param [String] property
207
+ # the property to check
208
+ #
209
+ # @return [Boolean]
210
+ #
211
+ # @api private
212
+ def api_property?(property)
213
+ api.respond_to?(:"#{property}") && api.send(:"#{property}")
214
+ end
215
+
216
+ # Check if required arguments are present.
217
+ #
218
+ #
219
+ def check_requirement!(*args)
220
+ args_length = args.length
221
+ required_length = @required.length
222
+
223
+ if args_length < required_length
224
+ raise ArgumentError, "Wrong number of arguments " \
225
+ "(#{args_length} for #{required_length}). " \
226
+ "Expected `#{@required.join(', ')}` as required arguments, " \
227
+ "but got `#{args.join(", ")}`."
228
+ end
229
+ end
230
+
231
+ # Find auto_pagination parameter in options hash
232
+ #
233
+ def extract_pagination(options)
234
+ if (value = options.delete(AUTO_PAGINATION))
235
+ api.auto_pagination = value
236
+ end
237
+ end
238
+
239
+ # Evaluate a block
240
+ #
241
+ # @api privte
242
+ def yield_or_eval(&block)
243
+ return unless block
244
+ block.arity > 0 ? yield(self) : instance_eval(&block)
245
+ end
246
+ end # Arguments
247
+ end # Api
248
+ end # BitBucket
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ class API
5
+ class Config
6
+
7
+ # Property objects provide an interface for configuration options
8
+ class Property
9
+
10
+ attr_reader :name
11
+ attr_reader :default
12
+ attr_reader :required
13
+
14
+ def initialize(name, options)
15
+ @name = name
16
+ @default = options.fetch(:default, nil)
17
+ @required = options.fetch(:required, nil)
18
+ @options = options
19
+ end
20
+
21
+ # @api private
22
+ def define_accessor_methods(properties)
23
+ properties.define_reader_method(self, self.name, :public)
24
+ properties.define_writer_method(self, "#{self.name}=", :public)
25
+ end
26
+ end # Property
27
+
28
+ end # Config
29
+ end # Api
30
+ end # BitBucket
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ class API
5
+ class Config
6
+ # Class responsible for storing configuration properties
7
+ class PropertySet
8
+ include Enumerable
9
+
10
+ attr_reader :parent
11
+
12
+ attr_reader :properties
13
+
14
+ # Initialize an PropertySet
15
+ #
16
+ # @param [Object] parent
17
+ # @param [Set] properties
18
+ #
19
+ # @return [undefined]
20
+ #
21
+ # @api private
22
+ def initialize(parent = nil, properties = Set.new)
23
+ @parent = parent
24
+ @properties = properties
25
+ @map = {}
26
+ end
27
+
28
+ # Iterate over properties
29
+ #
30
+ # @yield [property]
31
+ #
32
+ # @yieldparam [Property] property
33
+ #
34
+ # @return [self]
35
+ #
36
+ # @api public
37
+ def each
38
+ return to_enum unless block_given?
39
+ @map.each { |name, property| yield property if name.is_a?(Symbol) }
40
+ self
41
+ end
42
+
43
+ # Adds property to the set
44
+ #
45
+ # @example
46
+ # properties_set << property
47
+ #
48
+ # @param [Property] property
49
+ #
50
+ # @return [self]
51
+ #
52
+ # @api public
53
+ def <<(property)
54
+ properties << property
55
+ update_map(property.name, property.default)
56
+ property.define_accessor_methods(self)
57
+ self
58
+ end
59
+
60
+ # Access property by name
61
+ #
62
+ # @api public
63
+ def [](name)
64
+ @map[name]
65
+ end
66
+ alias_method :fetch, :[]
67
+
68
+ # Set property value by name
69
+ #
70
+ # @api public
71
+ def []=(name, property)
72
+ update_map(name, property)
73
+ end
74
+
75
+ # Update map with index
76
+ #
77
+ # @api private
78
+ def update_map(name, property)
79
+ @map[name.to_sym] = @map[name.to_s.freeze] = property
80
+ end
81
+
82
+ # Convert properties to a hash of property names and
83
+ # corresponding values
84
+ #
85
+ # @api public
86
+ def to_hash
87
+ properties.each_with_object({}) do |property, props|
88
+ name = property.name
89
+ props[name] = self[name]
90
+ end
91
+ end
92
+
93
+ # Check if properties exist
94
+ #
95
+ # @api public
96
+ def empty?
97
+ @map.empty?
98
+ end
99
+
100
+ # @api private
101
+ def define_reader_method(property, method_name, visibility)
102
+ property_set = self
103
+ parent.send(:define_method, method_name) { property_set[property.name] }
104
+ parent.send(visibility, method_name)
105
+ end
106
+
107
+ # @api private
108
+ def define_writer_method(property, method_name, visibility)
109
+ property_set = self
110
+ parent.send(:define_method, method_name) do |value|
111
+ property_set[property.name]= value
112
+ end
113
+ parent.send(visibility, method_name)
114
+ end
115
+ end # PropertySet
116
+ end # Config
117
+ end # Api
118
+ end # BitBucket