bitbuckets 0.2.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.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +7 -0
  3. data/README.md +169 -0
  4. data/Rakefile +1 -0
  5. data/lib/bitbucket_rest_api.rb +86 -0
  6. data/lib/bitbucket_rest_api/api.rb +104 -0
  7. data/lib/bitbucket_rest_api/api/actions.rb +32 -0
  8. data/lib/bitbucket_rest_api/api_factory.rb +29 -0
  9. data/lib/bitbucket_rest_api/authorization.rb +31 -0
  10. data/lib/bitbucket_rest_api/client.rb +53 -0
  11. data/lib/bitbucket_rest_api/configuration.rb +103 -0
  12. data/lib/bitbucket_rest_api/connection.rb +97 -0
  13. data/lib/bitbucket_rest_api/constants.rb +57 -0
  14. data/lib/bitbucket_rest_api/core_ext/array.rb +6 -0
  15. data/lib/bitbucket_rest_api/core_ext/hash.rb +58 -0
  16. data/lib/bitbucket_rest_api/deprecation.rb +36 -0
  17. data/lib/bitbucket_rest_api/error.rb +37 -0
  18. data/lib/bitbucket_rest_api/error/bad_events.rb +10 -0
  19. data/lib/bitbucket_rest_api/error/bad_request.rb +11 -0
  20. data/lib/bitbucket_rest_api/error/blank_value.rb +10 -0
  21. data/lib/bitbucket_rest_api/error/client_error.rb +19 -0
  22. data/lib/bitbucket_rest_api/error/forbidden.rb +11 -0
  23. data/lib/bitbucket_rest_api/error/internal_server_error.rb +11 -0
  24. data/lib/bitbucket_rest_api/error/invalid_options.rb +17 -0
  25. data/lib/bitbucket_rest_api/error/no_events.rb +10 -0
  26. data/lib/bitbucket_rest_api/error/not_found.rb +11 -0
  27. data/lib/bitbucket_rest_api/error/required_params.rb +17 -0
  28. data/lib/bitbucket_rest_api/error/service_error.rb +18 -0
  29. data/lib/bitbucket_rest_api/error/service_unavailable.rb +11 -0
  30. data/lib/bitbucket_rest_api/error/unauthorized.rb +11 -0
  31. data/lib/bitbucket_rest_api/error/unknown_value.rb +17 -0
  32. data/lib/bitbucket_rest_api/error/unprocessable_entity.rb +11 -0
  33. data/lib/bitbucket_rest_api/error/validations.rb +17 -0
  34. data/lib/bitbucket_rest_api/invitations.rb +14 -0
  35. data/lib/bitbucket_rest_api/issues.rb +229 -0
  36. data/lib/bitbucket_rest_api/issues/comments.rb +116 -0
  37. data/lib/bitbucket_rest_api/issues/components.rb +105 -0
  38. data/lib/bitbucket_rest_api/issues/milestones.rb +105 -0
  39. data/lib/bitbucket_rest_api/normalizer.rb +24 -0
  40. data/lib/bitbucket_rest_api/parameter_filter.rb +29 -0
  41. data/lib/bitbucket_rest_api/repos.rb +276 -0
  42. data/lib/bitbucket_rest_api/repos/changesets.rb +52 -0
  43. data/lib/bitbucket_rest_api/repos/commits.rb +38 -0
  44. data/lib/bitbucket_rest_api/repos/components.rb +35 -0
  45. data/lib/bitbucket_rest_api/repos/default_reviewers.rb +60 -0
  46. data/lib/bitbucket_rest_api/repos/download.rb +15 -0
  47. data/lib/bitbucket_rest_api/repos/following.rb +38 -0
  48. data/lib/bitbucket_rest_api/repos/forks.rb +66 -0
  49. data/lib/bitbucket_rest_api/repos/keys.rb +86 -0
  50. data/lib/bitbucket_rest_api/repos/pull_request.rb +158 -0
  51. data/lib/bitbucket_rest_api/repos/services.rb +101 -0
  52. data/lib/bitbucket_rest_api/repos/sources.rb +36 -0
  53. data/lib/bitbucket_rest_api/repos/webhooks.rb +99 -0
  54. data/lib/bitbucket_rest_api/request.rb +71 -0
  55. data/lib/bitbucket_rest_api/request/basic_auth.rb +30 -0
  56. data/lib/bitbucket_rest_api/request/jsonize.rb +39 -0
  57. data/lib/bitbucket_rest_api/request/oauth.rb +50 -0
  58. data/lib/bitbucket_rest_api/response.rb +26 -0
  59. data/lib/bitbucket_rest_api/response/helpers.rb +18 -0
  60. data/lib/bitbucket_rest_api/response/jsonize.rb +25 -0
  61. data/lib/bitbucket_rest_api/response/mashify.rb +23 -0
  62. data/lib/bitbucket_rest_api/response/raise_error.rb +28 -0
  63. data/lib/bitbucket_rest_api/response/xmlize.rb +25 -0
  64. data/lib/bitbucket_rest_api/result.rb +136 -0
  65. data/lib/bitbucket_rest_api/teams.rb +91 -0
  66. data/lib/bitbucket_rest_api/user.rb +87 -0
  67. data/lib/bitbucket_rest_api/users.rb +20 -0
  68. data/lib/bitbucket_rest_api/users/account.rb +50 -0
  69. data/lib/bitbucket_rest_api/utils/url.rb +61 -0
  70. data/lib/bitbucket_rest_api/validations.rb +23 -0
  71. data/lib/bitbucket_rest_api/validations/format.rb +21 -0
  72. data/lib/bitbucket_rest_api/validations/presence.rb +21 -0
  73. data/lib/bitbucket_rest_api/validations/required.rb +37 -0
  74. data/lib/bitbucket_rest_api/validations/token.rb +38 -0
  75. data/lib/bitbucket_rest_api/version.rb +10 -0
  76. data/lib/bitbuckets.rb +2 -0
  77. data/spec/bitbucket_rest_api/api/actions_spec.rb +18 -0
  78. data/spec/bitbucket_rest_api/api_factory_spec.rb +28 -0
  79. data/spec/bitbucket_rest_api/api_spec.rb +87 -0
  80. data/spec/bitbucket_rest_api/authorization_spec.rb +74 -0
  81. data/spec/bitbucket_rest_api/client_spec.rb +17 -0
  82. data/spec/bitbucket_rest_api/core_ext/array_spec.rb +13 -0
  83. data/spec/bitbucket_rest_api/core_ext/hash_spec.rb +47 -0
  84. data/spec/bitbucket_rest_api/deprecation_spec.rb +31 -0
  85. data/spec/bitbucket_rest_api/error/bad_events_spec.rb +11 -0
  86. data/spec/bitbucket_rest_api/error/blank_value_spec.rb +14 -0
  87. data/spec/bitbucket_rest_api/error/no_events_spec.rb +11 -0
  88. data/spec/bitbucket_rest_api/invitations_spec.rb +21 -0
  89. data/spec/bitbucket_rest_api/issues/comments_spec.rb +89 -0
  90. data/spec/bitbucket_rest_api/issues/components_spec.rb +89 -0
  91. data/spec/bitbucket_rest_api/issues/milestones_spec.rb +89 -0
  92. data/spec/bitbucket_rest_api/issues_spec.rb +91 -0
  93. data/spec/bitbucket_rest_api/normalizer_spec.rb +29 -0
  94. data/spec/bitbucket_rest_api/parameter_filter_spec.rb +42 -0
  95. data/spec/bitbucket_rest_api/repos/changesets_spec.rb +44 -0
  96. data/spec/bitbucket_rest_api/repos/commits_spec.rb +21 -0
  97. data/spec/bitbucket_rest_api/repos/components_spec.rb +43 -0
  98. data/spec/bitbucket_rest_api/repos/default_reviewers_spec.rb +65 -0
  99. data/spec/bitbucket_rest_api/repos/download_spec.rb +10 -0
  100. data/spec/bitbucket_rest_api/repos/following_spec.rb +53 -0
  101. data/spec/bitbucket_rest_api/repos/forks_spec.rb +46 -0
  102. data/spec/bitbucket_rest_api/repos/keys_spec.rb +73 -0
  103. data/spec/bitbucket_rest_api/repos/pull_request_spec.rb +283 -0
  104. data/spec/bitbucket_rest_api/repos/sources_spec.rb +78 -0
  105. data/spec/bitbucket_rest_api/repos/webhooks_spec.rb +245 -0
  106. data/spec/bitbucket_rest_api/repos_spec.rb +158 -0
  107. data/spec/bitbucket_rest_api/request/jsonize_spec.rb +19 -0
  108. data/spec/bitbucket_rest_api/request/oauth_spec.rb +26 -0
  109. data/spec/bitbucket_rest_api/request_spec.rb +88 -0
  110. data/spec/bitbucket_rest_api/response/jsonize_spec.rb +13 -0
  111. data/spec/bitbucket_rest_api/response/mashify_spec.rb +33 -0
  112. data/spec/bitbucket_rest_api/response/raise_error_spec.rb +42 -0
  113. data/spec/bitbucket_rest_api/teams_spec.rb +136 -0
  114. data/spec/bitbucket_rest_api/user_spec.rb +78 -0
  115. data/spec/bitbucket_rest_api/utils/url_spec.rb +34 -0
  116. data/spec/bitbucket_rest_api/validations/format_spec.rb +30 -0
  117. data/spec/bitbucket_rest_api/validations/presence_spec.rb +13 -0
  118. data/spec/bitbucket_rest_api/validations/required_spec.rb +44 -0
  119. data/spec/bitbucket_rest_api/validations/token_spec.rb +17 -0
  120. data/spec/bitbucket_rest_api_spec.rb +17 -0
  121. data/spec/spec_helper.rb +24 -0
  122. metadata +358 -0
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ require 'faraday'
3
+
4
+ module BitBucket
5
+ class Response::Helpers < Response
6
+ def on_complete(env)
7
+ env[:body].class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
8
+ include BitBucket::Result
9
+
10
+ def env
11
+ @env
12
+ end
13
+
14
+ RUBY_EVAL
15
+ env[:body].instance_eval { @env = env }
16
+ end
17
+ end # Response::Helpers
18
+ end # BitBucket
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ require 'faraday'
3
+
4
+ module BitBucket
5
+ class Response::Jsonize < Response
6
+ dependency 'multi_json'
7
+
8
+ define_parser do |body|
9
+ MultiJson.load(body)
10
+ end
11
+
12
+ def parse(body)
13
+ case body
14
+ when ''
15
+ nil
16
+ when 'true'
17
+ true
18
+ when 'false'
19
+ false
20
+ else
21
+ self.class.parser.call body
22
+ end
23
+ end
24
+ end # Response::Jsonize
25
+ end # BitBucket
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ require 'faraday'
3
+
4
+ module BitBucket
5
+ class Response::Mashify < Response
6
+ dependency 'hashie/mash'
7
+
8
+ define_parser do |body|
9
+ ::Hashie::Mash.new body
10
+ end
11
+
12
+ def parse(body)
13
+ case body
14
+ when Hash
15
+ self.class.parser.call body
16
+ when Array
17
+ body.map { |item| item.is_a?(Hash) ? self.class.parser.call(item) : item }
18
+ else
19
+ body
20
+ end
21
+ end
22
+ end # Response::Mashify
23
+ end # BitBucket
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ require 'faraday'
3
+ require 'bitbucket_rest_api/error'
4
+
5
+ module BitBucket
6
+ class Response::RaiseError < Faraday::Response::Middleware
7
+ def on_complete(env)
8
+ case env[:status].to_i
9
+ when 400
10
+ raise BitBucket::Error::BadRequest, env
11
+ when 401
12
+ raise BitBucket::Error::Unauthorized, env
13
+ when 403
14
+ raise BitBucket::Error::Forbidden, env
15
+ when 404
16
+ raise BitBucket::Error::NotFound, env
17
+ when 422
18
+ raise BitBucket::Error::UnprocessableEntity, env
19
+ when 500
20
+ raise BitBucket::Error::InternalServerError, env
21
+ when 503
22
+ raise BitBucket::Error::ServiceUnavailable, env
23
+ when 400...600
24
+ raise BitBucket::Error::ServiceError, env
25
+ end
26
+ end
27
+ end # Response::RaiseError
28
+ end # BitBucket
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ require 'faraday'
3
+
4
+ module BitBucket
5
+ class Response::Xmlize < Response
6
+ dependency 'nokogiri'
7
+
8
+ define_parser do |body|
9
+ ::Nokogiri::XML body
10
+ end
11
+
12
+ def parse(body)
13
+ case body
14
+ when ''
15
+ nil
16
+ when 'true'
17
+ true
18
+ when 'false'
19
+ false
20
+ else
21
+ self.class.parser.call body
22
+ end
23
+ end
24
+ end # Response::Xmlize
25
+ end # BitBucket
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+ module BitBucket
3
+ module Result
4
+ include BitBucket::Constants
5
+
6
+ # TODO: Add result counts method to check total items looking at result links
7
+
8
+ def ratelimit_limit
9
+ loaded? ? @env[:response_headers][RATELIMIT_LIMIT] : nil
10
+ end
11
+
12
+ def ratelimit_remaining
13
+ loaded? ? @env[:response_headers][RATELIMIT_REMAINING] : nil
14
+ end
15
+
16
+ def cache_control
17
+ loaded? ? @env[:response_headers][CACHE_CONTROL] : nil
18
+ end
19
+
20
+ def content_type
21
+ loaded? ? @env[:response_headers][CONTENT_TYPE] : nil
22
+ end
23
+
24
+ def content_length
25
+ loaded? ? @env[:response_headers][CONTENT_LENGTH] : nil
26
+ end
27
+
28
+ def etag
29
+ loaded? ? @env[:response_headers][ETAG] : nil
30
+ end
31
+
32
+ def date
33
+ loaded? ? @env[:response_headers][DATE] : nil
34
+ end
35
+
36
+ def location
37
+ loaded? ? @env[:response_headers][LOCATION] : nil
38
+ end
39
+
40
+ def server
41
+ loaded? ? @env[:response_headers][SERVER] : nil
42
+ end
43
+
44
+ def status
45
+ loaded? ? @env[:status] : nil
46
+ end
47
+
48
+ def success?
49
+ (200..299).include? status
50
+ end
51
+
52
+ # Returns raw body
53
+ def body
54
+ loaded? ? @env[:body] : nil
55
+ end
56
+
57
+ def loaded?
58
+ !!@env
59
+ end
60
+
61
+ # Return page links
62
+ def links
63
+ @@links = BitBucket::PageLinks.new(@env[:response_headers])
64
+ end
65
+
66
+ # Iterator like each for response pages. If there are no pages to
67
+ # iterate over this method will return nothing.
68
+ def each_page
69
+ yield body
70
+ yield next_page while page_iterator.has_next?
71
+ end
72
+
73
+ # Retrives the result of the first page. Returns <tt>nil</tt> if there is
74
+ # no first page - either because you are already on the first page
75
+ # or there are no pages at all in the result.
76
+ def first_page
77
+ first_request = page_iterator.first
78
+ instance_eval { @env = first_request.env } if first_request
79
+ body
80
+ end
81
+
82
+ # Retrives the result of the next page. Returns <tt>nil</tt> if there is
83
+ # no next page or no pages at all.
84
+ def next_page
85
+ next_request = page_iterator.next
86
+ instance_eval { @env = next_request.env } if next_request
87
+ body
88
+ end
89
+
90
+ # Retrives the result of the previous page. Returns <tt>nil</tt> if there is
91
+ # no previous page or no pages at all.
92
+ def prev_page
93
+ prev_request = page_iterator.prev
94
+ instance_eval { @env = prev_request.env } if prev_request
95
+ body
96
+ end
97
+ alias previous_page prev_page
98
+
99
+ # Retrives the result of the last page. Returns <tt>nil</tt> if there is
100
+ # no last page - either because you are already on the last page,
101
+ # there is only one page or there are no pages at all in the result.
102
+ def last_page
103
+ last_request = page_iterator.last
104
+ instance_eval { @env = last_request.env } if last_request
105
+ body
106
+ end
107
+
108
+ # Retrives a specific result for a page given page number.
109
+ # The <tt>page_number</tt> parameter is not validate, hitting a page
110
+ # that does not exist will return BitBucket API error. Consequently, if
111
+ # there is only one page, this method returns nil
112
+ def page(page_number)
113
+ request = page_iterator.get_page(page_number)
114
+ instance_eval { @env = request.env } if request
115
+ body
116
+ end
117
+
118
+ # Returns <tt>true</tt> if there is another page in the result set,
119
+ # otherwise <tt>false</tt>
120
+ def has_next_page?
121
+ page_iterator.has_next?
122
+ end
123
+
124
+ # Repopulates objects for new values
125
+ def reset
126
+ nil
127
+ end
128
+
129
+ private
130
+
131
+ # Internally used page iterator
132
+ def page_iterator # :nodoc:
133
+ @@page_iterator = BitBucket::PageIterator.new(@env)
134
+ end
135
+ end # Result
136
+ end # BitBucket
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+ module BitBucket
3
+ class Teams < API
4
+ extend AutoloadHelper
5
+
6
+ def initialize(options = {})
7
+ super(options)
8
+ end
9
+
10
+ # List teams for the authenticated user where the user has the provided role
11
+ # Roles are :admin, :contributor, :member
12
+ #
13
+ # = Examples
14
+ # bitbucket = BitBucket.new :oauth_token => '...', :oauth_secret => '...'
15
+ # bitbucket.teams.list(:admin)
16
+ # bitbucket.teams.list('member')
17
+ # bitbucket.teams.list(:contributor) { |team| ... }
18
+ def list(user_role)
19
+ response = get_request("/2.0/teams/?role=#{user_role}")
20
+ return response['values'] unless block_given?
21
+
22
+ response['values'].each { |el| yield el }
23
+ end
24
+
25
+ alias all list
26
+
27
+ # Return the profile for the provided team
28
+ #
29
+ # = Example
30
+ # bitbucket = BitBucket.new :oauth_token => '...', :oauth_secret => '...'
31
+ # bitbucket.teams.profile(:team_name_here)
32
+ def profile(team_name)
33
+ get_request("/2.0/teams/#{team_name}")
34
+ end
35
+
36
+ # List members of the provided team
37
+ #
38
+ # = Examples
39
+ # bitbucket = BitBucket.new :oauth_token => '...', :oauth_secret => '...'
40
+ # bitbucket.teams.members(:team_name_here)
41
+ # bitbucket.teams.members(:team_name_here) { |member| ... }
42
+ def members(team_name)
43
+ response = get_request("/2.0/teams/#{team_name}/members")
44
+ return response['values'] unless block_given?
45
+
46
+ response['values'].each { |el| yield el }
47
+ end
48
+
49
+ # List followers of the provided team
50
+ #
51
+ # = Examples
52
+ # bitbucket = BitBucket.new :oauth_token => '...', :oauth_secret => '...'
53
+ # bitbucket.teams.followers(:team_name_here)
54
+ # bitbucket.teams.followers(:team_name_here) { |follower| ... }
55
+ def followers(team_name)
56
+ response = get_request("/2.0/teams/#{team_name}/followers")
57
+ return response['values'] unless block_given?
58
+
59
+ response['values'].each { |el| yield el }
60
+ end
61
+
62
+ # List accounts following the provided team
63
+ #
64
+ # = Examples
65
+ # bitbucket = BitBucket.new :oauth_token => '...', :oauth_secret => '...'
66
+ # bitbucket.teams.following(:team_name_here)
67
+ # bitbucket.teams.following(:team_name_here) { |followee| ... }
68
+ def following(team_name)
69
+ response = get_request("/2.0/teams/#{team_name}/following")
70
+ return response['values'] unless block_given?
71
+
72
+ response['values'].each { |el| yield el }
73
+ end
74
+
75
+ # List repos for provided team
76
+ # Private repos will only be returned if the user is authorized to view them
77
+ #
78
+ # = Examples
79
+ # bitbucket = BitBucket.new :oauth_token => '...', :oauth_secret => '...'
80
+ # bitbucket.teams.repos(:team_name_here)
81
+ # bitbucket.teams.repos(:team_name_here) { |repo| ... }
82
+ def repos(team_name)
83
+ response = get_request("/2.0/repositories/#{team_name}")
84
+ return response['values'] unless block_given?
85
+
86
+ response['values'].each { |el| yield el }
87
+ end
88
+
89
+ alias repositories repos
90
+ end # Team
91
+ end # BitBucket
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+ module BitBucket
3
+ class User < API
4
+ DEFAULT_USER_OPTIONS = {
5
+ 'first_name' => '',
6
+ 'last_name' => '',
7
+ 'avatar' => ''
8
+ # TODO: can this filed be modified?
9
+ # "resource_uri" => ""
10
+ }.freeze
11
+
12
+ # Creates new User API
13
+ def initialize(options = {})
14
+ super(options)
15
+ end
16
+
17
+ # Gets the basic information associated with an account and
18
+ # a list of all of the repositories owned by the user.
19
+ # See https://confluence.atlassian.com/display/BITBUCKET/user+Endpoint#userEndpoint-GETauserprofile
20
+ #
21
+ # = Examples
22
+ # bitbucket = BitBucket.new
23
+ # bitbucket.user_api.profile
24
+ #
25
+ def profile
26
+ get_request('/1.0/user')
27
+ end
28
+
29
+ # Update a user
30
+
31
+ # = Parameters
32
+ # * <tt>:first_name</tt> Optional string
33
+ # * <tt>:last_name</tt> Optional string
34
+ # * <tt>:avatar</tt> Optional string
35
+ # * <tt>:resource_uri</tt> Optional string
36
+ #
37
+ # = Examples
38
+ #
39
+ # bitbucket = BitBucket.new
40
+ # bitbucket.user_api.update :first_name => 'first-name', :last_name => 'last-name'
41
+ #
42
+
43
+ def update(params = {})
44
+ normalize! params
45
+ filter! DEFAULT_USER_OPTIONS, params
46
+
47
+ put_request('/1.0/user', DEFAULT_USER_OPTIONS.merge(params))
48
+ end
49
+
50
+ # GET a list of user privileges
51
+ def privileges
52
+ get_request('/1.0/user/privileges')
53
+ end
54
+
55
+ # GET a list of repositories an account follows
56
+ # Gets the details of the repositories that the individual or team account follows.
57
+ # This call returns the full data about the repositories including
58
+ # if the repository is a fork of another repository.
59
+ # An account always "follows" its own repositories.
60
+ def follows
61
+ get_request('/1.0/user/follows')
62
+ end
63
+
64
+ # GET a list of repositories visible to an account
65
+ # Gets the details of the repositories that the user owns
66
+ # or has at least read access to.
67
+ # Use this if you're looking for a full list of all of the repositories associated with a user.
68
+ def repositories
69
+ get_request('/1.0/user/repositories')
70
+ end
71
+
72
+ alias repos repositories
73
+
74
+ # GET a list of repositories the account is following
75
+ # Gets a list of the repositories the account follows.
76
+ # This is the same list that appears on the Following tab on your account dashboard.
77
+ def overview
78
+ get_request('/1.0/user/repositories/overview')
79
+ end
80
+
81
+ # GET the list of repositories on the dashboard
82
+ # Gets the repositories list from the account's dashboard.
83
+ def dashboard
84
+ get_request('/1.0/user/repositories/dashboard')
85
+ end
86
+ end # User
87
+ end # BitBucket
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ module BitBucket
3
+ class Users < API
4
+ extend AutoloadHelper
5
+
6
+ # Load all the modules after initializing Repos to avoid superclass mismatch
7
+ autoload_all 'bitbucket_rest_api/users',
8
+ Account: 'account'
9
+
10
+ # Creates new Users API
11
+ def initialize(options = {})
12
+ super(options)
13
+ end
14
+
15
+ # Access to Users::Account API
16
+ def account
17
+ @account ||= ApiFactory.new 'Users::Account'
18
+ end
19
+ end # Users
20
+ end # BitBucket