codenamev_bitbucket_api 0.4.0
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +43 -0
- data/README.md +169 -0
- data/Rakefile +3 -0
- data/lib/bitbucket_rest_api/api/actions.rb +50 -0
- data/lib/bitbucket_rest_api/api/arguments.rb +248 -0
- data/lib/bitbucket_rest_api/api/config/property.rb +30 -0
- data/lib/bitbucket_rest_api/api/config/property_set.rb +118 -0
- data/lib/bitbucket_rest_api/api/config.rb +107 -0
- data/lib/bitbucket_rest_api/api/factory.rb +29 -0
- data/lib/bitbucket_rest_api/api.rb +242 -0
- data/lib/bitbucket_rest_api/authorization.rb +34 -0
- data/lib/bitbucket_rest_api/client/invitations.rb +16 -0
- data/lib/bitbucket_rest_api/client/issues/comments.rb +109 -0
- data/lib/bitbucket_rest_api/client/issues/components.rb +103 -0
- data/lib/bitbucket_rest_api/client/issues/milestones.rb +103 -0
- data/lib/bitbucket_rest_api/client/issues.rb +214 -0
- data/lib/bitbucket_rest_api/client/repos/changesets.rb +55 -0
- data/lib/bitbucket_rest_api/client/repos/following.rb +40 -0
- data/lib/bitbucket_rest_api/client/repos/keys.rb +88 -0
- data/lib/bitbucket_rest_api/client/repos/pull_requests/comments.rb +42 -0
- data/lib/bitbucket_rest_api/client/repos/pull_requests/commits.rb +24 -0
- data/lib/bitbucket_rest_api/client/repos/pull_requests.rb +199 -0
- data/lib/bitbucket_rest_api/client/repos/services.rb +104 -0
- data/lib/bitbucket_rest_api/client/repos/sources.rb +32 -0
- data/lib/bitbucket_rest_api/client/repos.rb +224 -0
- data/lib/bitbucket_rest_api/client/user.rb +96 -0
- data/lib/bitbucket_rest_api/client/users/account.rb +54 -0
- data/lib/bitbucket_rest_api/client/users.rb +14 -0
- data/lib/bitbucket_rest_api/client.rb +54 -0
- data/lib/bitbucket_rest_api/compatibility.rb +23 -0
- data/lib/bitbucket_rest_api/configuration.rb +59 -0
- data/lib/bitbucket_rest_api/connection.rb +61 -0
- data/lib/bitbucket_rest_api/constants.rb +50 -0
- data/lib/bitbucket_rest_api/core_ext/array.rb +17 -0
- data/lib/bitbucket_rest_api/core_ext/hash.rb +56 -0
- data/lib/bitbucket_rest_api/core_ext/ordered_hash.rb +107 -0
- data/lib/bitbucket_rest_api/deprecation.rb +39 -0
- data/lib/bitbucket_rest_api/error/bad_request.rb +12 -0
- data/lib/bitbucket_rest_api/error/client_error.rb +20 -0
- data/lib/bitbucket_rest_api/error/forbidden.rb +12 -0
- data/lib/bitbucket_rest_api/error/internal_server_error.rb +12 -0
- data/lib/bitbucket_rest_api/error/invalid_options.rb +18 -0
- data/lib/bitbucket_rest_api/error/not_found.rb +12 -0
- data/lib/bitbucket_rest_api/error/required_params.rb +18 -0
- data/lib/bitbucket_rest_api/error/service_error.rb +19 -0
- data/lib/bitbucket_rest_api/error/service_unavailable.rb +12 -0
- data/lib/bitbucket_rest_api/error/unauthorized.rb +12 -0
- data/lib/bitbucket_rest_api/error/unknown_value.rb +18 -0
- data/lib/bitbucket_rest_api/error/unprocessable_entity.rb +12 -0
- data/lib/bitbucket_rest_api/error/validations.rb +18 -0
- data/lib/bitbucket_rest_api/error.rb +35 -0
- data/lib/bitbucket_rest_api/ext/faraday.rb +38 -0
- data/lib/bitbucket_rest_api/middleware.rb +31 -0
- data/lib/bitbucket_rest_api/normalizer.rb +27 -0
- data/lib/bitbucket_rest_api/null_encoder.rb +25 -0
- data/lib/bitbucket_rest_api/page_iterator.rb +90 -0
- data/lib/bitbucket_rest_api/page_links.rb +33 -0
- data/lib/bitbucket_rest_api/paged_request.rb +29 -0
- data/lib/bitbucket_rest_api/pagination.rb +97 -0
- data/lib/bitbucket_rest_api/parameter_filter.rb +32 -0
- data/lib/bitbucket_rest_api/params_hash.rb +100 -0
- data/lib/bitbucket_rest_api/request/basic_auth.rb +33 -0
- data/lib/bitbucket_rest_api/request/jsonize.rb +51 -0
- data/lib/bitbucket_rest_api/request/oauth.rb +51 -0
- data/lib/bitbucket_rest_api/request/verbs.rb +53 -0
- data/lib/bitbucket_rest_api/request.rb +91 -0
- data/lib/bitbucket_rest_api/response/header.rb +68 -0
- data/lib/bitbucket_rest_api/response/helpers.rb +21 -0
- data/lib/bitbucket_rest_api/response/jsonize.rb +30 -0
- data/lib/bitbucket_rest_api/response/mashify.rb +24 -0
- data/lib/bitbucket_rest_api/response/raise_error.rb +31 -0
- data/lib/bitbucket_rest_api/response/xmlize.rb +26 -0
- data/lib/bitbucket_rest_api/response.rb +28 -0
- data/lib/bitbucket_rest_api/response_wrapper.rb +157 -0
- data/lib/bitbucket_rest_api/result.rb +68 -0
- data/lib/bitbucket_rest_api/users.rb +20 -0
- data/lib/bitbucket_rest_api/utils/url.rb +56 -0
- data/lib/bitbucket_rest_api/validations/format.rb +24 -0
- data/lib/bitbucket_rest_api/validations/presence.rb +30 -0
- data/lib/bitbucket_rest_api/validations/required.rb +24 -0
- data/lib/bitbucket_rest_api/validations/token.rb +43 -0
- data/lib/bitbucket_rest_api/validations.rb +25 -0
- data/lib/bitbucket_rest_api/version.rb +11 -0
- data/lib/bitbucket_rest_api.rb +136 -0
- 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
|
+
[](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,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
|