reenhanced_bitbucket_api 0.1.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bitbucket_rest_api/api/arguments.rb +248 -0
  3. data/lib/bitbucket_rest_api/api/config/property.rb +30 -0
  4. data/lib/bitbucket_rest_api/api/config/property_set.rb +118 -0
  5. data/lib/bitbucket_rest_api/api/config.rb +107 -0
  6. data/lib/bitbucket_rest_api/api/factory.rb +29 -0
  7. data/lib/bitbucket_rest_api/api.rb +155 -33
  8. data/lib/bitbucket_rest_api/{invitations.rb → client/invitations.rb} +4 -3
  9. data/lib/bitbucket_rest_api/{issues → client/issues}/comments.rb +2 -11
  10. data/lib/bitbucket_rest_api/{issues → client/issues}/components.rb +3 -6
  11. data/lib/bitbucket_rest_api/{issues → client/issues}/milestones.rb +3 -7
  12. data/lib/bitbucket_rest_api/{issues.rb → client/issues.rb} +9 -25
  13. data/lib/bitbucket_rest_api/{repos → client/repos}/changesets.rb +3 -2
  14. data/lib/bitbucket_rest_api/{repos → client/repos}/following.rb +2 -1
  15. data/lib/bitbucket_rest_api/{repos → client/repos}/keys.rb +2 -1
  16. data/lib/bitbucket_rest_api/client/repos/pull_requests/activity.rb +22 -0
  17. data/lib/bitbucket_rest_api/client/repos/pull_requests/comments.rb +40 -0
  18. data/lib/bitbucket_rest_api/client/repos/pull_requests/commits.rb +24 -0
  19. data/lib/bitbucket_rest_api/client/repos/pull_requests.rb +205 -0
  20. data/lib/bitbucket_rest_api/{repos → client/repos}/services.rb +2 -1
  21. data/lib/bitbucket_rest_api/{repos → client/repos}/sources.rb +2 -1
  22. data/lib/bitbucket_rest_api/{repos.rb → client/repos.rb} +26 -40
  23. data/lib/bitbucket_rest_api/{user.rb → client/user.rb} +2 -7
  24. data/lib/bitbucket_rest_api/{users → client/users}/account.rb +2 -1
  25. data/lib/bitbucket_rest_api/client/users.rb +14 -0
  26. data/lib/bitbucket_rest_api/client.rb +28 -32
  27. data/lib/bitbucket_rest_api/configuration.rb +24 -67
  28. data/lib/bitbucket_rest_api/connection.rb +15 -50
  29. data/lib/bitbucket_rest_api/constants.rb +1 -9
  30. data/lib/bitbucket_rest_api/core_ext/array.rb +1 -1
  31. data/lib/bitbucket_rest_api/error/invalid_options.rb +1 -1
  32. data/lib/bitbucket_rest_api/error/required_params.rb +1 -1
  33. data/lib/bitbucket_rest_api/error/unknown_value.rb +1 -1
  34. data/lib/bitbucket_rest_api/ext/faraday.rb +38 -0
  35. data/lib/bitbucket_rest_api/middleware.rb +31 -0
  36. data/lib/bitbucket_rest_api/null_encoder.rb +25 -0
  37. data/lib/bitbucket_rest_api/page_iterator.rb +90 -0
  38. data/lib/bitbucket_rest_api/page_links.rb +33 -0
  39. data/lib/bitbucket_rest_api/paged_request.rb +29 -0
  40. data/lib/bitbucket_rest_api/pagination.rb +98 -0
  41. data/lib/bitbucket_rest_api/parameter_filter.rb +1 -1
  42. data/lib/bitbucket_rest_api/params_hash.rb +100 -0
  43. data/lib/bitbucket_rest_api/request/basic_auth.rb +4 -2
  44. data/lib/bitbucket_rest_api/request/jsonize.rb +5 -0
  45. data/lib/bitbucket_rest_api/request/oauth.rb +3 -3
  46. data/lib/bitbucket_rest_api/request/verbs.rb +53 -0
  47. data/lib/bitbucket_rest_api/request.rb +60 -36
  48. data/lib/bitbucket_rest_api/response/header.rb +68 -0
  49. data/lib/bitbucket_rest_api/response_wrapper.rb +157 -0
  50. data/lib/bitbucket_rest_api/result.rb +5 -77
  51. data/lib/bitbucket_rest_api/users.rb +4 -8
  52. data/lib/bitbucket_rest_api/validations/presence.rb +16 -11
  53. data/lib/bitbucket_rest_api/validations.rb +6 -6
  54. data/lib/bitbucket_rest_api/version.rb +2 -2
  55. data/lib/bitbucket_rest_api.rb +89 -44
  56. metadata +39 -131
  57. data/lib/bitbucket_rest_api/api_factory.rb +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d277a40d6a0329bdffe0c73a4f763114ab5bce42
4
- data.tar.gz: a57c2f43ffbf60bb800b1118054d3a10637b6c39
3
+ metadata.gz: f1a895c33b9ba283852dbf0d5af066a2acbaa05f
4
+ data.tar.gz: 9773125535fa33ff8f10a20a3b379b7615701e7c
5
5
  SHA512:
6
- metadata.gz: 25fdcd0f4b728c37f7bb4ecaa6dc10c300f335dfd83647de539732da2f62e4d9cf986797e4402c5c5431257764504fde6fe1efab8b466b1cb9123a68a3612b00
7
- data.tar.gz: bb139a3ab32b6ef2ce5a372c13ccb778e6b0ec6d435a8a09f27cfe7d4cf89d993c3db69e7533f731e7c83e7ebb37245c406f39a5e5c8d8e0e2c949d0aecccdcb
6
+ metadata.gz: 8fd84a1de59f109e782b11f6b0839555a2cf93f452ee7342642e2bb6a9a43c407354f044d2ee50c50a5dae37984d135b0c87533213781b3defb863ea1cd0d537
7
+ data.tar.gz: 6456a8bbe344e0856f392c1e90cc7deec072d5a8dead1c7a8c039a8537249edc149d5b6706136e29c0f9dd803b94891c9166c36a6d16d2488b1a464220e2c7dd
@@ -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
@@ -0,0 +1,107 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bitbucket_rest_api/api/config/property'
4
+ require 'bitbucket_rest_api/api/config/property_set'
5
+
6
+ module BitBucket
7
+
8
+ class API
9
+ # A base class for constructing api configuration
10
+ class Config
11
+
12
+ # Defines a property on an object's class or instance
13
+ #
14
+ # @example
15
+ # class Configuration < Api::Config
16
+ # property :adapter, default: :net_http
17
+ # property :user, required: true
18
+ # end
19
+ #
20
+ # @param [Symbol] name
21
+ # the name of a property
22
+ #
23
+ # @param [#to_hash] options
24
+ # the extra options
25
+ #
26
+ # @return [self]
27
+ #
28
+ # @api public
29
+ def self.property(name, options = {})
30
+ self.property_set << Property.new(name, options)
31
+ update_subclasses(name, options)
32
+ self
33
+ end
34
+
35
+ def self.update_subclasses(name, options)
36
+ if defined?(@subclasses) && @subclasses
37
+ @subclasses.each { |klass| klass.property(name, options) }
38
+ end
39
+ end
40
+
41
+ # Check if property is defined
42
+ #
43
+ # @param [Symbol] name
44
+ # the name to check
45
+ #
46
+ # @return [Boolean]
47
+ #
48
+ # @api public
49
+ def self.property?(name)
50
+ property_set.include?(name)
51
+ end
52
+
53
+ class << self
54
+ attr_reader :property_set
55
+ end
56
+
57
+ instance_variable_set("@property_set", PropertySet.new(self))
58
+
59
+ def self.inherited(descendant)
60
+ super
61
+ (@subclasses ||= Set.new) << descendant
62
+ descendant.instance_variable_set('@property_set',
63
+ PropertySet.new(descendant, self.property_set.properties.dup))
64
+ end
65
+
66
+ def initialize(&block)
67
+ super(&block)
68
+ end
69
+
70
+ def property_names
71
+ self.class.property_set.properties.map(&:name)
72
+ end
73
+
74
+ def self.property_names
75
+ property_set.properties.map(&:name)
76
+ end
77
+
78
+ # Fetach all the properties and their values
79
+ #
80
+ # @return [Hash[Symbol]]
81
+ #
82
+ # @api public
83
+ def fetch(value = nil)
84
+ if value
85
+ self.class.property_set[value]
86
+ else
87
+ self.class.property_set.to_hash
88
+ end
89
+ end
90
+
91
+ # Provide access to properties
92
+ #
93
+ # @example
94
+ # config.call do |config|
95
+ # config.adapter = :net_http
96
+ # end
97
+ #
98
+ # @return [self]
99
+ #
100
+ # @api private
101
+ def call(&block)
102
+ block.call(self) if block_given?
103
+ self
104
+ end
105
+ end # Config
106
+ end # Api
107
+ end # BitBucket
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bitbucket_rest_api/core_ext/hash'
4
+
5
+ module BitBucket
6
+ class API
7
+ class Factory
8
+
9
+ # Instantiates a new bitbucket api object
10
+ def self.new(klass, options={}, &block)
11
+ return create_instance(klass, options, &block) if klass
12
+ raise ArgumentError, 'must provide klass to be instantiated'
13
+ end
14
+
15
+ # Passes configuration options to instantiated class
16
+ def self.create_instance(klass, options, &block)
17
+ options.symbolize_keys!
18
+ convert_to_constant(klass.to_s).new options, &block
19
+ end
20
+
21
+ def self.convert_to_constant(classes)
22
+ classes.split('::').inject(BitBucket) do |constant, klass|
23
+ constant.const_get klass
24
+ end
25
+ end
26
+
27
+ end # Factory
28
+ end # Api
29
+ end # BitBucket