bitbucket_rest_api 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/README.md +163 -0
  2. data/lib/bitbucket_rest_api/api/actions.rb +50 -0
  3. data/lib/bitbucket_rest_api/api.rb +121 -0
  4. data/lib/bitbucket_rest_api/api_factory.rb +30 -0
  5. data/lib/bitbucket_rest_api/authorization.rb +49 -0
  6. data/lib/bitbucket_rest_api/client.rb +52 -0
  7. data/lib/bitbucket_rest_api/compatibility.rb +23 -0
  8. data/lib/bitbucket_rest_api/configuration.rb +101 -0
  9. data/lib/bitbucket_rest_api/connection.rb +97 -0
  10. data/lib/bitbucket_rest_api/constants.rb +58 -0
  11. data/lib/bitbucket_rest_api/core_ext/array.rb +17 -0
  12. data/lib/bitbucket_rest_api/core_ext/hash.rb +56 -0
  13. data/lib/bitbucket_rest_api/core_ext/ordered_hash.rb +107 -0
  14. data/lib/bitbucket_rest_api/deprecation.rb +39 -0
  15. data/lib/bitbucket_rest_api/error/bad_request.rb +12 -0
  16. data/lib/bitbucket_rest_api/error/client_error.rb +20 -0
  17. data/lib/bitbucket_rest_api/error/forbidden.rb +12 -0
  18. data/lib/bitbucket_rest_api/error/internal_server_error.rb +12 -0
  19. data/lib/bitbucket_rest_api/error/invalid_options.rb +18 -0
  20. data/lib/bitbucket_rest_api/error/not_found.rb +12 -0
  21. data/lib/bitbucket_rest_api/error/required_params.rb +18 -0
  22. data/lib/bitbucket_rest_api/error/service_error.rb +19 -0
  23. data/lib/bitbucket_rest_api/error/service_unavailable.rb +12 -0
  24. data/lib/bitbucket_rest_api/error/unauthorized.rb +12 -0
  25. data/lib/bitbucket_rest_api/error/unknown_value.rb +18 -0
  26. data/lib/bitbucket_rest_api/error/unprocessable_entity.rb +12 -0
  27. data/lib/bitbucket_rest_api/error/validations.rb +18 -0
  28. data/lib/bitbucket_rest_api/error.rb +35 -0
  29. data/lib/bitbucket_rest_api/issues/comments.rb +118 -0
  30. data/lib/bitbucket_rest_api/issues/components.rb +106 -0
  31. data/lib/bitbucket_rest_api/issues/milestones.rb +107 -0
  32. data/lib/bitbucket_rest_api/issues.rb +201 -0
  33. data/lib/bitbucket_rest_api/normalizer.rb +27 -0
  34. data/lib/bitbucket_rest_api/parameter_filter.rb +32 -0
  35. data/lib/bitbucket_rest_api/repos/changesets.rb +54 -0
  36. data/lib/bitbucket_rest_api/repos/following.rb +39 -0
  37. data/lib/bitbucket_rest_api/repos/keys.rb +87 -0
  38. data/lib/bitbucket_rest_api/repos.rb +213 -0
  39. data/lib/bitbucket_rest_api/request/basic_auth.rb +31 -0
  40. data/lib/bitbucket_rest_api/request/jsonize.rb +46 -0
  41. data/lib/bitbucket_rest_api/request/oauth.rb +49 -0
  42. data/lib/bitbucket_rest_api/request.rb +67 -0
  43. data/lib/bitbucket_rest_api/response/helpers.rb +21 -0
  44. data/lib/bitbucket_rest_api/response/jsonize.rb +30 -0
  45. data/lib/bitbucket_rest_api/response/mashify.rb +24 -0
  46. data/lib/bitbucket_rest_api/response/raise_error.rb +31 -0
  47. data/lib/bitbucket_rest_api/response/xmlize.rb +26 -0
  48. data/lib/bitbucket_rest_api/response.rb +28 -0
  49. data/lib/bitbucket_rest_api/result.rb +140 -0
  50. data/lib/bitbucket_rest_api/utils/url.rb +56 -0
  51. data/lib/bitbucket_rest_api/validations/format.rb +24 -0
  52. data/lib/bitbucket_rest_api/validations/presence.rb +25 -0
  53. data/lib/bitbucket_rest_api/validations/required.rb +24 -0
  54. data/lib/bitbucket_rest_api/validations/token.rb +43 -0
  55. data/lib/bitbucket_rest_api/validations.rb +25 -0
  56. data/lib/bitbucket_rest_api/version.rb +11 -0
  57. data/lib/bitbucket_rest_api.rb +87 -0
  58. metadata +266 -0
data/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # BitBucketAPI
2
+
3
+ [Wiki](https://bitbucket.com/vongrippen/bitbucket/wiki) | [RDocs](http://rubydoc.info/github/vongrippen/bitbucket/master/frames)
4
+
5
+ A Ruby wrapper for the BitBucket REST API.
6
+
7
+ ## Installation
8
+
9
+ Install the gem by issuing
10
+
11
+ ```ruby
12
+ gem install bitbucket_rest_api
13
+ ```
14
+
15
+ or put it in your Gemfile and run `bundle install`
16
+
17
+ ```ruby
18
+ gem "bitbucket_rest_api"
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Create a new client instance
24
+
25
+ ```ruby
26
+ bitbucket = BitBucket.new
27
+ ```
28
+
29
+ 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:
30
+
31
+ ```ruby
32
+ bitbucket = BitBucket.new oauth_token: 'token', oauth_secret: 'secret'
33
+ ```
34
+
35
+ Alternatively, you can configure the BitBucket settings by passing a block, for instance, with custom enteprise endpoint like
36
+
37
+ ```ruby
38
+ bitbucket = BitBucket.new do |config|
39
+ config.oauth_token = 'token'
40
+ config.oauth_secret = 'secret'
41
+ config.adapter = :net_http
42
+ end
43
+ ```
44
+
45
+ You can authenticate either using OAuth authentication or through basic authentication by passing your login and password credentials
46
+
47
+ ```ruby
48
+ bitbucket = BitBucket.new login:'vongrippen', password:'...'
49
+ ```
50
+
51
+ or use convenience method:
52
+
53
+ ```ruby
54
+ bitbucket = BitBucket.new basic_auth: 'login:password'
55
+ ```
56
+
57
+ You can interact with BitBucket interface, for example repositories, by issuing following calls that correspond directly to the BitBucket API hierarchy
58
+
59
+ ```ruby
60
+ bitbucket.repos.changesets.all 'user-name', 'repo-name'
61
+ bitbucket.repos.keys.list 'user-name', 'repo-name'
62
+ ```
63
+
64
+ The response is of type [Hashie::Mash] and allows to traverse all the json response attributes like method calls.
65
+
66
+ ## Inputs
67
+
68
+ Some API methods apart from required parameters such as username or repository name
69
+ allow you to switch the way the data is returned to you, for instance by passing
70
+ a block you can iterate over the list of repositories
71
+
72
+ ```ruby
73
+ bitbucket.repos.list do |repo|
74
+ puts repo.slug
75
+ end
76
+ ```
77
+
78
+ ## Advanced Configuration
79
+
80
+ 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
81
+
82
+ ```ruby
83
+ bitbucket = BitBucket.new do |config|
84
+ config.stack.insert_after BitBucket::Response::Helpers, CustomMiddleware
85
+ end
86
+ ```
87
+
88
+ Furthermore, you can build your entire custom stack and specify other connection options such as `adapter`
89
+
90
+ ```ruby
91
+ bitbucket = BitBucket.new do |config|
92
+ config.adapter :excon
93
+
94
+ config.stack do |builder|
95
+ builder.use BitBucket::Response::Helpers
96
+ builder.use BitBucket::Response::Jsonize
97
+ end
98
+ end
99
+ ```
100
+
101
+ ## API
102
+
103
+ Main API methods are grouped into the following classes that can be instantiated on their own
104
+
105
+ ```ruby
106
+ BitBucket - full API access
107
+
108
+ BitBucket::Repos BitBucket::Issues
109
+ ```
110
+
111
+ Some parts of BitBucket API require you to be authenticated, for instance the following are examples of APIs only for the authenticated user
112
+
113
+ ```ruby
114
+ BitBucket::Issues::Create
115
+ ```
116
+
117
+ You can find out supported methods by calling `actions` on a class instance in your `irb`:
118
+
119
+ ```ruby
120
+ >> BitBucket::Repos.actions >> bitbucket.issues.actions
121
+ --- ---
122
+ |--> all |--> all
123
+ |--> branches |--> comments
124
+ |--> collaborators |--> create
125
+ |--> commits |--> edit
126
+ |--> contribs |--> events
127
+ |--> contributors |--> find
128
+ |--> create |--> get
129
+ |--> downloads |--> labels
130
+ |--> edit |--> list
131
+ |--> find |--> list_repo
132
+ |--> forks |--> list_repository
133
+ |--> get |--> milestones
134
+ |--> hooks ...
135
+ ...
136
+ ```
137
+
138
+ ## Configuration
139
+
140
+ Certain methods require authentication. To get your BitBucket OAuth credentials,
141
+ register an app with BitBucket.
142
+
143
+ ```ruby
144
+ BitBucket.configure do |config|
145
+ config.oauth_token = YOUR_OAUTH_ACCESS_TOKEN
146
+ config.oauth_secret = YOUR_OAUTH_ACCESS_TOKEN_SECRET
147
+ config.basic_auth = 'login:password'
148
+ end
149
+
150
+ or
151
+
152
+ BitBucket.new(:oauth_token => YOUR_OAUTH_TOKEN, :oauth_secret => YOUR_OAUTH_ACCESS_TOKEN_SECRET)
153
+ BitBucket.new(:basic_auth => 'login:password')
154
+ ```
155
+
156
+ ## Development
157
+
158
+ 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`.
159
+
160
+ ## Copyright
161
+
162
+ Copyright (c) 2012 James M Cochran.
163
+ Original github_api gem Copyright (c) 2011-2012 Piotr Murach. See LICENSE.txt for further details.
@@ -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,121 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'bitbucket_rest_api/configuration'
4
+ require 'bitbucket_rest_api/connection'
5
+ require 'bitbucket_rest_api/validations'
6
+ require 'bitbucket_rest_api/request'
7
+ require 'bitbucket_rest_api/core_ext/hash'
8
+ require 'bitbucket_rest_api/core_ext/array'
9
+ require 'bitbucket_rest_api/compatibility'
10
+ require 'bitbucket_rest_api/api/actions'
11
+ require 'bitbucket_rest_api/api_factory'
12
+
13
+ module BitBucket
14
+ class API
15
+ include Authorization
16
+ include Connection
17
+ include Request
18
+
19
+ # TODO consider these optional in a stack
20
+ include Validations
21
+ include ParameterFilter
22
+ include Normalizer
23
+
24
+ attr_reader *Configuration::VALID_OPTIONS_KEYS
25
+
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
+ BitBucket.send("#{key}=", arg)
34
+ end
35
+ end
36
+ end
37
+
38
+ # Creates new API
39
+ def initialize(options={}, &block)
40
+ super()
41
+ setup options
42
+ set_api_client
43
+ client if client_id? && client_secret?
44
+
45
+ self.instance_eval(&block) if block_given?
46
+ end
47
+
48
+ def setup(options={})
49
+ options = BitBucket.options.merge(options)
50
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
51
+ send("#{key}=", options[key])
52
+ end
53
+ process_basic_auth(options[:basic_auth])
54
+ end
55
+
56
+ # Extract login and password from basic_auth parameter
57
+ def process_basic_auth(auth)
58
+ case auth
59
+ when String
60
+ self.login, self.password = auth.split(':', 2)
61
+ when Hash
62
+ self.login = auth[:login]
63
+ self.password = auth[:password]
64
+ end
65
+ end
66
+
67
+ # Assigns current api class
68
+ def set_api_client
69
+ BitBucket.api_client = self
70
+ end
71
+
72
+ # Responds to attribute query or attribute clear
73
+ def method_missing(method, *args, &block) # :nodoc:
74
+ case method.to_s
75
+ when /^(.*)\?$/
76
+ return !self.send($1.to_s).nil?
77
+ when /^clear_(.*)$/
78
+ self.send("#{$1.to_s}=", nil)
79
+ else
80
+ super
81
+ end
82
+ end
83
+
84
+ def _update_user_repo_params(user_name, repo_name=nil) # :nodoc:
85
+ self.user = user_name || self.user
86
+ self.repo = repo_name || self.repo
87
+ end
88
+
89
+ def _merge_user_into_params!(params) # :nodoc:
90
+ params.merge!({ 'user' => self.user }) if user?
91
+ end
92
+
93
+ def _merge_user_repo_into_params!(params) # :nodoc:
94
+ { 'user' => self.user, 'repo' => self.repo }.merge!(params)
95
+ end
96
+
97
+ # TODO: See whether still needed, consider adding to core_exts
98
+ def _hash_traverse(hash, &block)
99
+ hash.each do |key, val|
100
+ block.call(key)
101
+ case val
102
+ when Hash
103
+ val.keys.each do |k|
104
+ _hash_traverse(val, &block)
105
+ end
106
+ when Array
107
+ val.each do |item|
108
+ _hash_traverse(item, &block)
109
+ end
110
+ end
111
+ end
112
+ return hash
113
+ end
114
+
115
+ def _merge_mime_type(resource, params) # :nodoc:
116
+ # params['resource'] = resource
117
+ # params['mime_type'] = params['mime_type'] || :raw
118
+ end
119
+
120
+ end # API
121
+ end # BitBucket
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bitbucket_rest_api/core_ext/hash'
4
+
5
+ module BitBucket
6
+ class ApiFactory
7
+
8
+ # Instantiates a new bitbucket api object
9
+ def self.new(klass, options={})
10
+ return create_instance(klass, options) if klass
11
+ raise ArgumentError, 'must provide klass to be instantiated'
12
+ end
13
+
14
+ # Passes configuration options to instantiated class
15
+ def self.create_instance(klass, options)
16
+ options.symbolize_keys!
17
+ instance = convert_to_constant(klass.to_s).new options
18
+ BitBucket.api_client = instance
19
+ instance
20
+ end
21
+
22
+ def self.convert_to_constant(classes)
23
+ constant = BitBucket
24
+ classes.split('::').each do |klass|
25
+ constant = constant.const_get klass
26
+ end
27
+ return constant
28
+ end
29
+ end
30
+ end # BitBucket
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module Authorization
5
+
6
+ # Setup OAuth instance
7
+ def client
8
+ @client ||= ::OAuth::Consumer.new(client_id, client_secret,
9
+ {:signature_method=>"HMAC-SHA1",
10
+ :request_token_path=>"/1.0/oauth/request_token",
11
+ :authorize_path=>"/1.0/oauth/authenticate",
12
+ :access_token_path=>"/1.0/oauth/access_token",
13
+ :proxy=>nil,
14
+ :scheme=>:header,
15
+ :http_method=>:post,
16
+ :oauth_version=>"1.0",
17
+ :site=>"https://api.bitbucket.org"}
18
+ )
19
+ end
20
+
21
+ # Check whether authentication credentials are present
22
+ def authenticated?
23
+ basic_authed? || oauth_token?
24
+ end
25
+
26
+ # Check whether basic authentication credentials are present
27
+ def basic_authed?
28
+ basic_auth? || (login? && password?)
29
+ end
30
+
31
+ # Select authentication parameters
32
+ def authentication
33
+ if basic_auth?
34
+ { :basic_auth => basic_auth }
35
+ elsif login? && password?
36
+ { :login => login, :password => password }
37
+ else
38
+ { }
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def _verify_client # :nodoc:
45
+ raise ArgumentError, 'Need to provide client_id and client_secret' unless client_id? && client_secret?
46
+ end
47
+
48
+ end # Authorization
49
+ end # BitBucket
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ class Client < API
5
+
6
+ # This is a read-only API to the BitBucket events.
7
+ # These events power the various activity streams on the site.
8
+ def events(options = {})
9
+ raise "Unimplemented"
10
+ #@events ||= ApiFactory.new 'Events', options
11
+ end
12
+
13
+ def issues(options = {})
14
+ @issues ||= ApiFactory.new 'Issues', options
15
+ end
16
+
17
+ # An API for users to manage their own tokens.
18
+ def oauth(options = {})
19
+ raise "Unimpletmented"
20
+ #@oauth ||= ApiFactory.new 'Authorizations', options
21
+ end
22
+ alias :authorizations :oauth
23
+
24
+ def teams(options = {})
25
+ raise "Unimplemented"
26
+ #@teams ||= ApiFactory.new 'teams', options
27
+ end
28
+
29
+ def pull_requests(options = {})
30
+ raise "Unimplemented"
31
+ #@pull_requests ||= ApiFactory.new 'PullRequests', options
32
+ end
33
+
34
+ def repos(options = {})
35
+ @repos ||= ApiFactory.new 'Repos', options
36
+ end
37
+ alias :repositories :repos
38
+
39
+ def search(options = {})
40
+ raise "Unimplemented"
41
+ #@search ||= ApiFactory.new 'Search', options
42
+ end
43
+
44
+ # Many of the resources on the users API provide a shortcut for getting
45
+ # information about the currently authenticated user.
46
+ def users(options = {})
47
+ raise "Unimplemented"
48
+ #@users ||= ApiFactory.new 'Users', options
49
+ end
50
+
51
+ end # Client
52
+ end # BitBucket
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+
3
+ if RUBY_VERSION < "1.9"
4
+
5
+ def ruby_18 #:nodoc:
6
+ yield
7
+ end
8
+
9
+ def ruby_19 #:nodoc:
10
+ false
11
+ end
12
+
13
+ else
14
+
15
+ def ruby_18 #:nodoc:
16
+ false
17
+ end
18
+
19
+ def ruby_19 #:nodoc:
20
+ yield
21
+ end
22
+
23
+ end
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module Configuration
5
+
6
+ VALID_OPTIONS_KEYS = [
7
+ :adapter,
8
+ :client_id,
9
+ :client_secret,
10
+ :oauth_token,
11
+ :oauth_secret,
12
+ :endpoint,
13
+ :mime_type,
14
+ :user_agent,
15
+ :connection_options,
16
+ :repo,
17
+ :user,
18
+ :login,
19
+ :password,
20
+ :basic_auth
21
+ ].freeze
22
+
23
+ # Other adapters are :typhoeus, :patron, :em_synchrony, :excon, :test
24
+ DEFAULT_ADAPTER = :net_http
25
+
26
+ # By default, don't set an application key
27
+ DEFAULT_CLIENT_ID = nil
28
+
29
+ # By default, don't set an application secret
30
+ DEFAULT_CLIENT_SECRET = nil
31
+
32
+ # By default, don't set a user oauth access token
33
+ DEFAULT_OAUTH_TOKEN = nil
34
+
35
+ # By default, don't set a user oauth access token secret
36
+ DEFAULT_OAUTH_SECRET = nil
37
+
38
+ # By default, don't set a user login name
39
+ DEFAULT_LOGIN = nil
40
+
41
+ # By default, don't set a user password
42
+ DEFAULT_PASSWORD = nil
43
+
44
+ # By default, don't set a user basic authentication
45
+ DEFAULT_BASIC_AUTH = nil
46
+
47
+ # The endpoint used to connect to BitBucket if none is set, in the event that BitBucket is ever available on location
48
+ DEFAULT_ENDPOINT = 'https://bitbucket.org/api/1.0'.freeze
49
+
50
+ # The value sent in the http header for 'User-Agent' if none is set
51
+ DEFAULT_USER_AGENT = "BitBucket Ruby Gem #{BitBucket::VERSION::STRING}".freeze
52
+
53
+ # By default the <tt>Accept</tt> header will make a request for <tt>JSON</tt>
54
+ DEFAULT_MIME_TYPE = :json
55
+
56
+ # By default uses the Faraday connection options if none is set
57
+ DEFAULT_CONNECTION_OPTIONS = { }
58
+
59
+ # By default, don't set user name
60
+ DEFAULT_USER = nil
61
+
62
+ # By default, don't set repository name
63
+ DEFAULT_REPO = nil
64
+
65
+ attr_accessor *VALID_OPTIONS_KEYS
66
+
67
+ # Convenience method to allow for global setting of configuration options
68
+ def configure
69
+ yield self
70
+ end
71
+
72
+ def self.extended(base)
73
+ base.set_defaults
74
+ end
75
+
76
+ def options
77
+ options = { }
78
+ VALID_OPTIONS_KEYS.each { |k| options[k] = send(k) }
79
+ options
80
+ end
81
+
82
+ def set_defaults
83
+ self.adapter = DEFAULT_ADAPTER
84
+ self.client_id = DEFAULT_CLIENT_ID
85
+ self.client_secret = DEFAULT_CLIENT_SECRET
86
+ self.oauth_token = DEFAULT_OAUTH_TOKEN
87
+ self.oauth_secret = DEFAULT_OAUTH_SECRET
88
+ self.endpoint = DEFAULT_ENDPOINT
89
+ self.user_agent = DEFAULT_USER_AGENT
90
+ self.connection_options = DEFAULT_CONNECTION_OPTIONS
91
+ self.mime_type = DEFAULT_MIME_TYPE
92
+ self.user = DEFAULT_USER
93
+ self.repo = DEFAULT_REPO
94
+ self.login = DEFAULT_LOGIN
95
+ self.password = DEFAULT_PASSWORD
96
+ self.basic_auth = DEFAULT_BASIC_AUTH
97
+ self
98
+ end
99
+
100
+ end # Configuration
101
+ end # BitBucket
@@ -0,0 +1,97 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+ require 'bitbucket_rest_api/response'
5
+ require 'bitbucket_rest_api/response/mashify'
6
+ require 'bitbucket_rest_api/response/jsonize'
7
+ require 'bitbucket_rest_api/response/helpers'
8
+ require 'bitbucket_rest_api/response/raise_error'
9
+ require 'bitbucket_rest_api/request/oauth'
10
+ require 'bitbucket_rest_api/request/basic_auth'
11
+ require 'bitbucket_rest_api/request/jsonize'
12
+
13
+ module BitBucket
14
+ module Connection
15
+ extend self
16
+ include BitBucket::Constants
17
+
18
+ ALLOWED_OPTIONS = [
19
+ :headers,
20
+ :url,
21
+ :params,
22
+ :request,
23
+ :ssl
24
+ ].freeze
25
+
26
+ def default_options(options={})
27
+ {
28
+ :headers => {
29
+ ACCEPT => "application/json;q=0.1",
30
+ ACCEPT_CHARSET => "utf-8",
31
+ USER_AGENT => user_agent,
32
+ CONTENT_TYPE => 'application/json'
33
+ },
34
+ :ssl => { :verify => false },
35
+ :url => options.fetch(:endpoint) { BitBucket.endpoint }
36
+ }.merge(options)
37
+ end
38
+
39
+ # Default middleware stack that uses default adapter as specified at
40
+ # configuration stage.
41
+ #
42
+ def default_middleware(options={})
43
+ Proc.new do |builder|
44
+ builder.use BitBucket::Request::Jsonize
45
+ builder.use Faraday::Request::Multipart
46
+ builder.use Faraday::Request::UrlEncoded
47
+ builder.use BitBucket::Request::OAuth, client, oauth_token, oauth_secret if oauth_token? and oauth_secret?
48
+ builder.use BitBucket::Request::BasicAuth, authentication if basic_authed?
49
+
50
+ builder.use Faraday::Response::Logger if ENV['DEBUG']
51
+ builder.use BitBucket::Response::Helpers
52
+ unless options[:raw]
53
+ builder.use BitBucket::Response::Mashify
54
+ builder.use BitBucket::Response::Jsonize
55
+ end
56
+ builder.use BitBucket::Response::RaiseError
57
+ builder.adapter adapter
58
+ end
59
+ end
60
+
61
+ @connection = nil
62
+
63
+ @stack = nil
64
+
65
+ def clear_cache
66
+ @connection = nil
67
+ end
68
+
69
+ def caching?
70
+ !@connection.nil?
71
+ end
72
+
73
+ # Exposes middleware builder to facilitate custom stacks and easy
74
+ # addition of new extensions such as cache adapter.
75
+ #
76
+ def stack(options={}, &block)
77
+ @stack ||= begin
78
+ if block_given?
79
+ Faraday::Builder.new(&block)
80
+ else
81
+ Faraday::Builder.new(&default_middleware(options))
82
+ end
83
+ end
84
+ end
85
+
86
+ # Returns a Fraday::Connection object
87
+ #
88
+ def connection(options = {})
89
+ conn_options = default_options(options)
90
+ clear_cache unless options.empty?
91
+ puts "OPTIONS:#{conn_options.inspect}" if ENV['DEBUG']
92
+
93
+ @connection ||= Faraday.new(conn_options.merge(:builder => stack(options)))
94
+ end
95
+
96
+ end # Connection
97
+ end # BitBucket