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
@@ -0,0 +1,58 @@
1
+ module BitBucket
2
+ module Constants
3
+ extend self
4
+
5
+ # Response headers
6
+ RATELIMIT_REMAINING = 'X-RateLimit-Remaining'.freeze
7
+
8
+ RATELIMIT_LIMIT = 'X-RateLimit-Limit'.freeze
9
+
10
+ CONTENT_TYPE = 'Content-Type'.freeze
11
+
12
+ CONTENT_LENGTH = 'content-length'.freeze
13
+
14
+ CACHE_CONTROL = 'cache-control'.freeze
15
+
16
+ ETAG = 'ETag'.freeze
17
+
18
+ SERVER = 'Server'.freeze
19
+
20
+ DATE = 'Date'.freeze
21
+
22
+ LOCATION = 'Location'.freeze
23
+
24
+ USER_AGENT = 'User-Agent'.freeze
25
+
26
+ ACCEPT = 'Accept'.freeze
27
+
28
+ ACCEPT_CHARSET = 'Accept-Charset'.freeze
29
+
30
+ # Link headers
31
+ HEADER_LINK = "Link".freeze
32
+
33
+ HEADER_NEXT = "X-Next".freeze
34
+
35
+ HEADER_LAST = "X-Last".freeze
36
+
37
+ META_REL = "rel".freeze
38
+
39
+ META_LAST = "last".freeze
40
+
41
+ META_NEXT = "next".freeze
42
+
43
+ META_FIRST = "first".freeze
44
+
45
+ META_PREV = "prev".freeze
46
+
47
+ PARAM_PAGE = "page".freeze
48
+
49
+ PARAM_PER_PAGE = "per_page".freeze
50
+
51
+ PARAM_START_PAGE = "start_page".freeze
52
+
53
+ # URI parsing
54
+ QUERY_STR_SEP = '?'.freeze
55
+
56
+
57
+ end # Constants
58
+ end # BitBucket
@@ -0,0 +1,17 @@
1
+ class Array # :nodoc:
2
+
3
+ def except(*keys) # :nodoc:
4
+ self.dup.except!(*keys)
5
+ end unless method_defined?(:except)
6
+
7
+ def except!(*items) # :nodoc:
8
+ copy = self.dup
9
+ copy.reject! { |item| items.include? item }
10
+ copy
11
+ end unless method_defined?(:except!)
12
+
13
+ def extract_options!
14
+ last.is_a?(::Hash) ? pop : {}
15
+ end
16
+
17
+ end # Array
@@ -0,0 +1,56 @@
1
+ class Hash # :nodoc:
2
+
3
+ def except(*items) # :nodoc:
4
+ self.dup.except!(*items)
5
+ end unless method_defined?(:except)
6
+
7
+ def except!(*keys) # :nodoc:
8
+ copy = self.dup
9
+ keys.each { |key| copy.delete!(key) }
10
+ copy
11
+ end unless method_defined?(:except!)
12
+
13
+ def symbolize_keys # :nodoc:
14
+ inject({}) do |hash, (key, value)|
15
+ hash[(key.to_sym rescue key) || key] = value
16
+ hash
17
+ end
18
+ end unless method_defined?(:symbolize_keys)
19
+
20
+ def symbolize_keys! # :nodoc:
21
+ hash = symbolize_keys
22
+ hash.each do |key, val|
23
+ hash[key] = case val
24
+ when Hash
25
+ val.symbolize_keys!
26
+ when Array
27
+ val.map do |item|
28
+ item.is_a?(Hash) ? item.symbolize_keys! : item
29
+ end
30
+ else
31
+ val
32
+ end
33
+ end
34
+ return hash
35
+ end unless method_defined?(:symbolize_keys!)
36
+
37
+ def serialize # :nodoc:
38
+ self.map { |key, val| [key, val].join("=") }.join("&")
39
+ end unless method_defined?(:serialize)
40
+
41
+ def all_keys # :nodoc:
42
+ keys = self.keys
43
+ keys.each do |key|
44
+ if self[key].is_a?(Hash)
45
+ keys << self[key].all_keys.compact.flatten
46
+ next
47
+ end
48
+ end
49
+ keys.flatten
50
+ end unless method_defined?(:all_keys)
51
+
52
+ def has_deep_key?(key)
53
+ self.all_keys.include? key
54
+ end unless method_defined?(:has_deep_key?)
55
+
56
+ end # Hash
@@ -0,0 +1,107 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module CoreExt #:nodoc:
5
+
6
+ if RUBY_VERSION >= '1.9'
7
+ class OrderedHash < ::Hash; end
8
+ else
9
+ class OrderedHash < ::Hash
10
+ attr_accessor :order
11
+
12
+ class << self
13
+ def [](*args)
14
+ hsh = OrderedHash.new
15
+ if Hash == args[0]
16
+ hsh.replace args[0]
17
+ elsif (args.size % 2) != 0
18
+ pp args
19
+ raise ArgumentError, "odd number of elements for Hash"
20
+ else
21
+ 0.step(args.size - 1, 2) do |a|
22
+ b = a + 1
23
+ hsh[args[a]] = args[b]
24
+ end
25
+ end
26
+ hsh
27
+ end
28
+ end
29
+
30
+ def initialize(*args, &block)
31
+ super
32
+ @order = []
33
+ end
34
+
35
+ def []=(key, value)
36
+ @order.push key unless member?(key)
37
+ super key, value
38
+ end
39
+
40
+ def ==(hsh2)
41
+ return false if @order != hsh2.order
42
+ super hsh2
43
+ end
44
+
45
+ def clear
46
+ @order = []
47
+ super
48
+ end
49
+
50
+ def delete(key)
51
+ @order.delete key
52
+ super
53
+ end
54
+
55
+ def each_key
56
+ @order.each { |k| yield k }
57
+ self
58
+ end
59
+
60
+ def each_value
61
+ @order.each { |k| yield self[k] }
62
+ self
63
+ end
64
+
65
+ def each
66
+ @order.each { |k| yield k, self[k] }
67
+ self
68
+ end
69
+ alias :each_pair :each
70
+
71
+ def delete_if
72
+ @order.clone.each { |k| delete k if yield }
73
+ self
74
+ end
75
+
76
+ def values
77
+ ary = []
78
+ @order.each { |k| ary.push self[k] }
79
+ ary
80
+ end
81
+
82
+ def keys
83
+ @order
84
+ end
85
+
86
+ def replace(hsh2)
87
+ @order = hsh2.keys
88
+ super hsh2
89
+ end
90
+
91
+ def shift
92
+ key = @order.first
93
+ key ? [key, delete(key)] : super
94
+ end
95
+
96
+ def class
97
+ Hash
98
+ end
99
+
100
+ def __class__
101
+ OrderedHash
102
+ end
103
+ end # OrderedHash
104
+ end
105
+
106
+ end # CoreExt
107
+ end # BitBucket
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+
5
+ DEPRECATION_PREFIX = "[BitBucketAPI] Deprecation warning:"
6
+
7
+ class << self
8
+
9
+ attr_writer :deprecation_tracker
10
+
11
+ def deprecation_tracker
12
+ @deprecation_tracker ||= []
13
+ end
14
+
15
+ # Displays deprecation message to the user.
16
+ # Each message is printed once.
17
+ def deprecate(method, alternate_method=nil)
18
+ return if deprecation_tracker.include? method
19
+ deprecation_tracker << method
20
+
21
+ message = <<-NOTICE
22
+ #{DEPRECATION_PREFIX}
23
+
24
+ * #{method} is deprecated.
25
+ NOTICE
26
+ if alternate_method
27
+ message << <<-ADDITIONAL
28
+ * please use #{alternate_method} instead.
29
+ ADDITIONAL
30
+ end
31
+ warn_deprecation(message)
32
+ end
33
+
34
+ def warn_deprecation(message)
35
+ send :warn, message
36
+ end
37
+ end
38
+
39
+ end # BitBucket
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module Error
5
+ # Raised when BitBucket returns the HTTP status code 400
6
+ class BadRequest < ServiceError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end
12
+ end # BitBucket
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 404
5
+ module Error
6
+ class ClientError < BitBucketError
7
+ attr_reader :problem, :summary, :resolution
8
+
9
+ def initialize(message)
10
+ super(message)
11
+ end
12
+
13
+ def generate_message(attributes)
14
+ "\nProblem:\n #{attributes[:problem]}"+
15
+ "\nSummary:\n #{attributes[:summary]}"+
16
+ "\nResolution:\n #{attributes[:resolution]}"
17
+ end
18
+ end
19
+ end # Error
20
+ end # BitBucket
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 403
5
+ module Error
6
+ class Forbidden < BitBucketError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end # Error
12
+ end # BitBucket
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 500
5
+ module Error
6
+ class InternalServerError < BitBucketError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end # Error
12
+ end # BitBucket
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when invalid options are passed to a request body
5
+ module Error
6
+ class InvalidOptions < ClientError
7
+ def initialize(invalid, valid)
8
+ super(
9
+ generate_message(
10
+ :problem => "Invalid option #{invalid.keys.join(', ')} provided for this request.",
11
+ :summary => "BitBucket gem checks the request parameters passed to ensure that github api is not hit unnecessairly and to fail fast.",
12
+ :resolution => "Valid options are: #{valid.join(', ')}, make sure these are the ones you are using"
13
+ )
14
+ )
15
+ end
16
+ end
17
+ end # Error
18
+ end # BitBucket
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 404
5
+ module Error
6
+ class NotFound < ServiceError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end # Error
12
+ end # BitBucket
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when invalid options are passed to a request body
5
+ module Error
6
+ class RequiredParams < ClientError
7
+ def initialize(provided, required)
8
+ super(
9
+ generate_message(
10
+ :problem => "Missing required parameters: #{provided.keys.join(', ')} provided for this request.",
11
+ :summary => "BitBucket gem checks the request parameters passed to ensure that github api is not hit unnecessairly and to fail fast.",
12
+ :resolution => "Required parameters are: #{required.join(', ')}, make sure these are the ones you are using"
13
+ )
14
+ )
15
+ end
16
+ end
17
+ end # Error
18
+ end # BitBucket
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns any of the HTTP status codes
5
+ module Error
6
+ class ServiceError < BitBucketError
7
+ attr_accessor :http_headers
8
+
9
+ def initialize(env)
10
+ super(generate_message(env))
11
+ @http_headers = env[:response_headers]
12
+ end
13
+
14
+ def generate_message(env)
15
+ "#{env[:method].to_s.upcase} #{env[:url].to_s}: #{env[:status]} #{env[:body]}"
16
+ end
17
+ end
18
+ end # Error
19
+ end # BitBucket
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 404
5
+ module Error
6
+ class ServiceUnavailable < BitBucketError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end # Error
12
+ end # BitBucket
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 401
5
+ module Error
6
+ class Unauthorized < BitBucketError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end # Error
12
+ end # BitBucket
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when invalid options are passed to a request body
5
+ module Error
6
+ class UnknownValue < ClientError
7
+ def initialize(key, value, permitted)
8
+ super(
9
+ generate_message(
10
+ :problem => "Wrong value of '#{value}' for the parameter: #{key} provided for this request.",
11
+ :summary => "BitBucket gem checks the request parameters passed to ensure that github api is not hit unnecessairly and fails fast.",
12
+ :resolution => "Permitted values are: #{permitted}, make sure these are the ones you are using"
13
+ )
14
+ )
15
+ end
16
+ end
17
+ end # Error
18
+ end # BitBucket
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 422
5
+ module Error
6
+ class UnprocessableEntity < BitBucketError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end # Error
12
+ end # BitBucket
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when passed parameters are missing or contain wrong values.
5
+ module Error
6
+ class Validations < ClientError
7
+ def initialize(errors)
8
+ super(
9
+ generate_message(
10
+ :problem => '',
11
+ :summary => '',
12
+ :resolution => ''
13
+ )
14
+ )
15
+ end
16
+ end
17
+ end # Error
18
+ end # BitBucket
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module Error
5
+ class BitBucketError < StandardError
6
+ attr_reader :response_message, :response_headers
7
+
8
+ def initialize(message)
9
+ super message
10
+ @response_message = message
11
+ end
12
+
13
+ # def inspect
14
+ # %(#<#{self.class}>)
15
+ # end
16
+ end
17
+ end # Error
18
+ end # BitBucket
19
+
20
+ %w[
21
+ service_error
22
+ not_found
23
+ forbidden
24
+ bad_request
25
+ unauthorized
26
+ service_unavailable
27
+ internal_server_error
28
+ unprocessable_entity
29
+ client_error
30
+ invalid_options
31
+ required_params
32
+ unknown_value
33
+ ].each do |error|
34
+ require "bitbucket_rest_api/error/#{error}"
35
+ end
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ class Issues::Comments < API
5
+
6
+ VALID_ISSUE_COMMENT_PARAM_NAME = %w[
7
+ content
8
+ ].freeze
9
+
10
+ # Creates new Issues::Comments API
11
+ def initialize(options = {})
12
+ super(options)
13
+ end
14
+
15
+ # List comments on an issue
16
+ #
17
+ # = Examples
18
+ # bitbucket = BitBucket.new
19
+ # bitbucket.issues.comments.all 'user-name', 'repo-name', 'issue-id'
20
+ # bitbucket.issues.comments.all 'user-name', 'repo-name', 'issue-id' {|com| .. }
21
+ #
22
+ def list(user_name, repo_name, issue_id, params={})
23
+ _update_user_repo_params(user_name, repo_name)
24
+ _validate_user_repo_params(user, repo) unless user? && repo?
25
+ _validate_presence_of issue_id
26
+
27
+ normalize! params
28
+ # _merge_mime_type(:issue_comment, params)
29
+
30
+ response = get_request("/repositories/#{user}/#{repo}/issues/#{issue_id}/comments/", params)
31
+ return response unless block_given?
32
+ response.each { |el| yield el }
33
+ end
34
+ alias :all :list
35
+
36
+ # Get a single comment
37
+ #
38
+ # = Examples
39
+ # bitbucket = BitBucket.new
40
+ # bitbucket.issues.comments.find 'user-name', 'repo-name', 'comment-id'
41
+ #
42
+ def get(user_name, repo_name, comment_id, params={})
43
+ _update_user_repo_params(user_name, repo_name)
44
+ _validate_user_repo_params(user, repo) unless user? && repo?
45
+ _validate_presence_of comment_id
46
+
47
+ normalize! params
48
+ # _merge_mime_type(:issue_comment, params)
49
+
50
+ get_request("/repositories/#{user}/#{repo}/issues/comments/#{comment_id}", params)
51
+ end
52
+ alias :find :get
53
+
54
+ # Create a comment
55
+ #
56
+ # = Inputs
57
+ # <tt>:content</tt> Required string
58
+ #
59
+ # = Examples
60
+ # bitbucket = BitBucket.new
61
+ # bitbucket.issues.comments.create 'user-name', 'repo-name', 'issue-id',
62
+ # "content" => 'a new comment'
63
+ #
64
+ def create(user_name, repo_name, issue_id, params={})
65
+ _update_user_repo_params(user_name, repo_name)
66
+ _validate_user_repo_params(user, repo) unless user? && repo?
67
+ _validate_presence_of issue_id
68
+
69
+ normalize! params
70
+ # _merge_mime_type(:issue_comment, params)
71
+ filter! VALID_ISSUE_COMMENT_PARAM_NAME, params
72
+ assert_required_keys(%w[ content ], params)
73
+
74
+ post_request("/repositories/#{user}/#{repo}/issues/#{issue_id}/comments/", params)
75
+ end
76
+
77
+ # Edit a comment
78
+ #
79
+ # = Inputs
80
+ # <tt>:content</tt> Required string
81
+ #
82
+ # = Examples
83
+ # bitbucket = BitBucket.new
84
+ # bitbucket.issues.comments.edit 'user-name', 'repo-name', 'comment-id',
85
+ # "content" => 'a new comment'
86
+ #
87
+ def edit(user_name, repo_name, comment_id, params={})
88
+ _update_user_repo_params(user_name, repo_name)
89
+ _validate_user_repo_params(user, repo) unless user? && repo?
90
+ _validate_presence_of comment_id
91
+
92
+ normalize! params
93
+ # _merge_mime_type(:issue_comment, params)
94
+ filter! VALID_ISSUE_COMMENT_PARAM_NAME, params
95
+ assert_required_keys(%w[ content ], params)
96
+
97
+ put_request("/repositories/#{user}/#{repo}/issues/comments/#{comment_id}")
98
+ end
99
+
100
+ # Delete a comment
101
+ #
102
+ # = Examples
103
+ # bitbucket = BitBucket.new
104
+ # bitbucket.issues.comments.delete 'user-name', 'repo-name', 'comment-id'
105
+ #
106
+ def delete(user_name, repo_name, comment_id, params={})
107
+ _update_user_repo_params(user_name, repo_name)
108
+ _validate_user_repo_params(user, repo) unless user? && repo?
109
+ _validate_presence_of comment_id
110
+
111
+ normalize! params
112
+ # _merge_mime_type(:issue_comment, params)
113
+
114
+ delete_request("/repositories/#{user}/#{repo}/issues/comments/#{comment_id}", params)
115
+ end
116
+
117
+ end # Issues::Comments
118
+ end # BitBucket