tinybucket 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +35 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +44 -0
  6. data/.travis.yml +10 -0
  7. data/Gemfile +22 -0
  8. data/Guardfile +13 -0
  9. data/LICENSE +21 -0
  10. data/README.md +237 -0
  11. data/Rakefile +39 -0
  12. data/lib/faraday_middleware/follow_oauth_redirects.rb +67 -0
  13. data/lib/tinybucket.rb +61 -0
  14. data/lib/tinybucket/api.rb +20 -0
  15. data/lib/tinybucket/api/base_api.rb +31 -0
  16. data/lib/tinybucket/api/branch_restrictions_api.rb +26 -0
  17. data/lib/tinybucket/api/comments_api.rb +46 -0
  18. data/lib/tinybucket/api/commits_api.rb +26 -0
  19. data/lib/tinybucket/api/diff_api.rb +17 -0
  20. data/lib/tinybucket/api/helper.rb +22 -0
  21. data/lib/tinybucket/api/helper/api_helper.rb +48 -0
  22. data/lib/tinybucket/api/helper/branch_restrictions_helper.rb +27 -0
  23. data/lib/tinybucket/api/helper/comments_helper.rb +49 -0
  24. data/lib/tinybucket/api/helper/commits_helper.rb +27 -0
  25. data/lib/tinybucket/api/helper/diff_helper.rb +29 -0
  26. data/lib/tinybucket/api/helper/pull_requests_helper.rb +44 -0
  27. data/lib/tinybucket/api/helper/repo_helper.rb +29 -0
  28. data/lib/tinybucket/api/helper/repos_helper.rb +21 -0
  29. data/lib/tinybucket/api/helper/team_helper.rb +35 -0
  30. data/lib/tinybucket/api/helper/user_helper.rb +31 -0
  31. data/lib/tinybucket/api/pull_requests_api.rb +49 -0
  32. data/lib/tinybucket/api/repo_api.rb +35 -0
  33. data/lib/tinybucket/api/repos_api.rb +19 -0
  34. data/lib/tinybucket/api/team_api.rb +51 -0
  35. data/lib/tinybucket/api/user_api.rb +44 -0
  36. data/lib/tinybucket/api_factory.rb +21 -0
  37. data/lib/tinybucket/client.rb +95 -0
  38. data/lib/tinybucket/connection.rb +62 -0
  39. data/lib/tinybucket/constants.rb +4 -0
  40. data/lib/tinybucket/error.rb +8 -0
  41. data/lib/tinybucket/error/base_error.rb +12 -0
  42. data/lib/tinybucket/error/service_error.rb +20 -0
  43. data/lib/tinybucket/model.rb +20 -0
  44. data/lib/tinybucket/model/base.rb +54 -0
  45. data/lib/tinybucket/model/branch_restriction.rb +17 -0
  46. data/lib/tinybucket/model/comment.rb +39 -0
  47. data/lib/tinybucket/model/commit.rb +39 -0
  48. data/lib/tinybucket/model/concerns.rb +14 -0
  49. data/lib/tinybucket/model/concerns/reloadable.rb +45 -0
  50. data/lib/tinybucket/model/concerns/repository_keys.rb +43 -0
  51. data/lib/tinybucket/model/error_response.rb +7 -0
  52. data/lib/tinybucket/model/page.rb +65 -0
  53. data/lib/tinybucket/model/profile.rb +37 -0
  54. data/lib/tinybucket/model/pull_request.rb +64 -0
  55. data/lib/tinybucket/model/repository.rb +96 -0
  56. data/lib/tinybucket/model/team.rb +39 -0
  57. data/lib/tinybucket/parser.rb +25 -0
  58. data/lib/tinybucket/parser/base_parser.rb +17 -0
  59. data/lib/tinybucket/parser/branch_restriction_parser.rb +9 -0
  60. data/lib/tinybucket/parser/branch_restrictions_parser.rb +10 -0
  61. data/lib/tinybucket/parser/comment_parser.rb +9 -0
  62. data/lib/tinybucket/parser/comments_parser.rb +10 -0
  63. data/lib/tinybucket/parser/commit_parser.rb +9 -0
  64. data/lib/tinybucket/parser/commits_parser.rb +9 -0
  65. data/lib/tinybucket/parser/profile_parser.rb +9 -0
  66. data/lib/tinybucket/parser/profiles_parser.rb +9 -0
  67. data/lib/tinybucket/parser/pull_request_parser.rb +9 -0
  68. data/lib/tinybucket/parser/pull_requests_parser.rb +10 -0
  69. data/lib/tinybucket/parser/repo_parser.rb +9 -0
  70. data/lib/tinybucket/parser/repos_parser.rb +10 -0
  71. data/lib/tinybucket/parser/team_parser.rb +9 -0
  72. data/lib/tinybucket/parser/teams_parser.rb +9 -0
  73. data/lib/tinybucket/request.rb +55 -0
  74. data/lib/tinybucket/response.rb +7 -0
  75. data/lib/tinybucket/response/error_handler.rb +14 -0
  76. data/lib/tinybucket/version.rb +3 -0
  77. data/spec/fixtures/commit.json +83 -0
  78. data/spec/fixtures/profile.json +29 -0
  79. data/spec/fixtures/pull_request.json +106 -0
  80. data/spec/fixtures/repositories/get.json +78 -0
  81. data/spec/fixtures/repositories/test_owner/get.json +78 -0
  82. data/spec/fixtures/repositories/test_owner/test_repo/branch-restrictions/1/get.json +17 -0
  83. data/spec/fixtures/repositories/test_owner/test_repo/branch-restrictions/get.json +101 -0
  84. data/spec/fixtures/repositories/test_owner/test_repo/commit/1/comments/1/get.json +38 -0
  85. data/spec/fixtures/repositories/test_owner/test_repo/commit/1/comments/get.json +40 -0
  86. data/spec/fixtures/repositories/test_owner/test_repo/commit/1/get.json +83 -0
  87. data/spec/fixtures/repositories/test_owner/test_repo/commits/get.json +73 -0
  88. data/spec/fixtures/repositories/test_owner/test_repo/diff/1/get.json +21 -0
  89. data/spec/fixtures/repositories/test_owner/test_repo/forks/get.json +78 -0
  90. data/spec/fixtures/repositories/test_owner/test_repo/get.json +71 -0
  91. data/spec/fixtures/repositories/test_owner/test_repo/patch/1/get.json +29 -0
  92. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/1/approve/delete.json +3 -0
  93. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/1/approve/post.json +3 -0
  94. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/1/comments/1/get.json +30 -0
  95. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/1/comments/get.json +44 -0
  96. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/1/commits/get.json +66 -0
  97. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/1/diff/get.txt +13 -0
  98. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/1/get.json +164 -0
  99. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/get.json +112 -0
  100. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/get_state_declined.json +112 -0
  101. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/get_state_merged.json +112 -0
  102. data/spec/fixtures/repositories/test_owner/test_repo/pullrequests/get_state_open.json +112 -0
  103. data/spec/fixtures/repositories/test_owner/test_repo/watchers/get.json +32 -0
  104. data/spec/fixtures/repository.json +71 -0
  105. data/spec/fixtures/teams/test_team/followers/get.json +36 -0
  106. data/spec/fixtures/teams/test_team/following/get.json +39 -0
  107. data/spec/fixtures/teams/test_team/get.json +32 -0
  108. data/spec/fixtures/teams/test_team/members/get.json +36 -0
  109. data/spec/fixtures/teams/test_team/repositories/get.json +125 -0
  110. data/spec/fixtures/users/test_owner/followers/get.json +65 -0
  111. data/spec/fixtures/users/test_owner/following/get.json +100 -0
  112. data/spec/fixtures/users/test_owner/get.json +29 -0
  113. data/spec/lib/tinybucket/api/branch_restrictions_api_spec.rb +78 -0
  114. data/spec/lib/tinybucket/api/comments_api_spec.rb +133 -0
  115. data/spec/lib/tinybucket/api/commits_api_spec.rb +63 -0
  116. data/spec/lib/tinybucket/api/diff_api_spec.rb +5 -0
  117. data/spec/lib/tinybucket/api/pull_requests_api_spec.rb +229 -0
  118. data/spec/lib/tinybucket/api/repo_api_spec.rb +100 -0
  119. data/spec/lib/tinybucket/api/repos_api_spec.rb +28 -0
  120. data/spec/lib/tinybucket/api/team_api_spec.rb +87 -0
  121. data/spec/lib/tinybucket/api/user_api_spec.rb +60 -0
  122. data/spec/lib/tinybucket/api_factory_spec.rb +23 -0
  123. data/spec/lib/tinybucket/client_spec.rb +102 -0
  124. data/spec/lib/tinybucket/connection_spec.rb +30 -0
  125. data/spec/lib/tinybucket/model/branch_restriction_spec.rb +29 -0
  126. data/spec/lib/tinybucket/model/comment_spec.rb +31 -0
  127. data/spec/lib/tinybucket/model/commit_spec.rb +62 -0
  128. data/spec/lib/tinybucket/model/page_spec.rb +58 -0
  129. data/spec/lib/tinybucket/model/profile_spec.rb +47 -0
  130. data/spec/lib/tinybucket/model/pull_request_spec.rb +122 -0
  131. data/spec/lib/tinybucket/model/repository_spec.rb +131 -0
  132. data/spec/lib/tinybucket/model/team_spec.rb +53 -0
  133. data/spec/lib/tinybucket_spec.rb +32 -0
  134. data/spec/spec_helper.rb +42 -0
  135. data/spec/support/api_response_macros.rb +30 -0
  136. data/spec/support/model_macros.rb +61 -0
  137. data/tinybucket.gemspec +36 -0
  138. metadata +437 -0
@@ -0,0 +1,67 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module FaradayMiddleware
5
+ class FollowOAuthRedirects < FollowRedirects
6
+ dependency 'simple_oauth'
7
+
8
+ AUTH_HEADER = OAuth::AUTH_HEADER
9
+ CONTENT_TYPE = OAuth::CONTENT_TYPE
10
+ TYPE_URLENCODED = OAuth::TYPE_URLENCODED
11
+
12
+ def update_env(env, request_body, response)
13
+ env = super(env, request_body, response)
14
+
15
+ # update Authentication Header
16
+ env[:request_headers][OAuth::AUTH_HEADER] = \
17
+ oauth_header(env).to_s if oauth_signed_request?(env)
18
+
19
+ env
20
+ end
21
+
22
+ def oauth_header(env)
23
+ SimpleOAuth::Header.new env[:method],
24
+ env[:url].to_s,
25
+ signature_params(body_params(env)),
26
+ oauth_options(env)
27
+ end
28
+
29
+ def oauth_signed_request?(env)
30
+ env[:request].fetch(:oauth, nil).present?
31
+ end
32
+
33
+ def oauth_options(env)
34
+ extra = env[:request][:oauth]
35
+ if extra.present? and extra.is_a? Hash and !extra.empty?
36
+ @options.merge extra
37
+ else
38
+ @options
39
+ end
40
+ end
41
+
42
+ def body_params(env)
43
+ if include_body_params?(env)
44
+ if env[:body].respond_to?(:to_str)
45
+ ::Faraday::Utils.parse_nested_query env[:body]
46
+ else
47
+ env[:body]
48
+ end
49
+ end || {}
50
+ end
51
+
52
+ def include_body_params?(env)
53
+ # see RFC 5849, section 3.4.1.3.1 for details
54
+ !(type = env[:request_headers][OAuth::CONTENT_TYPE]) or type == OAuth::TYPE_URLENCODED
55
+ end
56
+
57
+ def signature_params(params)
58
+ params.empty? ? params :
59
+ params.reject { |_k, v| v.respond_to?(:content_type) }
60
+ end
61
+ end
62
+
63
+ if Faraday::Middleware.respond_to? :register_middleware
64
+ Faraday::Response.register_middleware \
65
+ follow_oauth_redirects: -> { FollowOAuthRedirects }
66
+ end
67
+ end
data/lib/tinybucket.rb ADDED
@@ -0,0 +1,61 @@
1
+ require 'tinybucket/version'
2
+
3
+ require 'active_support/dependencies/autoload'
4
+
5
+ require 'active_support/core_ext/hash'
6
+ require 'active_support/configurable'
7
+ require 'active_support/inflector'
8
+
9
+ require 'faraday'
10
+ require 'faraday_middleware'
11
+ require 'faraday_middleware/response_middleware'
12
+ require 'faraday_middleware/follow_oauth_redirects'
13
+
14
+ require 'active_model'
15
+
16
+ require 'logger'
17
+
18
+ require 'tinybucket/api'
19
+ require 'tinybucket/api_factory'
20
+ require 'tinybucket/api/helper'
21
+ require 'tinybucket/client'
22
+ require 'tinybucket/connection'
23
+ require 'tinybucket/constants'
24
+ require 'tinybucket/error'
25
+ require 'tinybucket/model/concerns'
26
+ require 'tinybucket/model'
27
+ require 'tinybucket/parser'
28
+ require 'tinybucket/request'
29
+ require 'tinybucket/response'
30
+
31
+ require 'active_support/notifications'
32
+ ActiveSupport::Notifications.subscribe('request.faraday') \
33
+ do |_name, start_time, end_time, _, env|
34
+ url = env[:url]
35
+ http_method = env[:method].to_s.upcase
36
+ duration = end_time - start_time
37
+ Tinybucket.logger.debug \
38
+ format(
39
+ '[%s] %s %s (%.3f s)',
40
+ url.host, http_method, url.request_uri, duration
41
+ )
42
+ end
43
+
44
+ module Tinybucket
45
+ class << self
46
+ include ActiveSupport::Configurable
47
+ attr_accessor :logger, :api_client
48
+
49
+ def new(options = {}, &block)
50
+ @api_client = Tinybucket::Client.new(options, &block)
51
+ end
52
+
53
+ def logger
54
+ @logger ||= begin
55
+ logger = Logger.new($stdout)
56
+ logger.level = Logger::DEBUG
57
+ logger
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,20 @@
1
+ module Tinybucket
2
+ module Api
3
+ extend ActiveSupport::Autoload
4
+
5
+ [
6
+ :BaseApi,
7
+ :BranchRestrictionsApi,
8
+ :CommitsApi,
9
+ :CommentsApi,
10
+ :DiffApi,
11
+ :PullRequestsApi,
12
+ :ReposApi,
13
+ :RepoApi,
14
+ :TeamApi,
15
+ :UserApi
16
+ ].each do |klass_name|
17
+ autoload klass_name
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ module Tinybucket
2
+ module Api
3
+ class BaseApi
4
+ include Tinybucket::Connection
5
+ include Tinybucket::Request
6
+
7
+ def initialize(config, options = {})
8
+ @config = filter_config(config)
9
+ @options = options
10
+ yield if block_given?
11
+ end
12
+
13
+ protected
14
+
15
+ def option(key)
16
+ @options[key.intern]
17
+ end
18
+
19
+ def config(key)
20
+ @config[key.intern]
21
+ end
22
+
23
+ private
24
+
25
+ def filter_config(config)
26
+ keys = %i(oauth_token oauth_secret)
27
+ config.select { |key, _| keys.include?(key) }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module Tinybucket
2
+ module Api
3
+ class BranchRestrictionsApi < BaseApi
4
+ include Tinybucket::Api::Helper::BranchRestrictionsHelper
5
+
6
+ attr_accessor :repo_owner, :repo_slug
7
+
8
+ def list(options = {})
9
+ list = get_path(path_to_list,
10
+ options,
11
+ Tinybucket::Parser::BranchRestrictionsParser)
12
+
13
+ list.next_proc = next_proc(:list, options)
14
+ inject_api_config(list)
15
+ end
16
+
17
+ def find(restriction_id, options = {})
18
+ m = get_path(path_to_find(restriction_id),
19
+ options,
20
+ Tinybucket::Parser::BranchRestrictionParser)
21
+
22
+ inject_api_config(m)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ module Tinybucket
2
+ module Api
3
+ class CommentsApi < BaseApi
4
+ include Tinybucket::Api::Helper::CommentsHelper
5
+
6
+ attr_accessor :repo_owner, :repo_slug
7
+
8
+ attr_accessor :commented_to
9
+
10
+ def list(options = {})
11
+ list = get_path(path_to_list,
12
+ options,
13
+ Tinybucket::Parser::CommentsParser)
14
+
15
+ list.next_proc = next_proc(:list, options)
16
+
17
+ associate_with_target(list)
18
+ inject_api_config(list)
19
+ end
20
+
21
+ def find(comment_id, options = {})
22
+ comment = get_path(path_to_find(comment_id),
23
+ options,
24
+ Tinybucket::Parser::CommentParser)
25
+
26
+ associate_with_target(comment)
27
+ inject_api_config(comment)
28
+ end
29
+
30
+ private
31
+
32
+ def associate_with_target(result)
33
+ case result
34
+ when Tinybucket::Model::Comment
35
+ result.commented_to = commented_to
36
+ when Tinybucket::Model::Page
37
+ result.items.map { |m| m.commented_to = commented_to }
38
+ else
39
+ fail ArgumentError, "Invalid result: #{result.inspect}"
40
+ end
41
+
42
+ result
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,26 @@
1
+ module Tinybucket
2
+ module Api
3
+ class CommitsApi < BaseApi
4
+ include Tinybucket::Api::Helper::CommitsHelper
5
+
6
+ attr_accessor :repo_owner, :repo_slug
7
+
8
+ def list(options = {})
9
+ list = get_path(path_to_list,
10
+ options,
11
+ Tinybucket::Parser::CommitsParser)
12
+
13
+ list.next_proc = next_proc(:list, options)
14
+ inject_api_config(list)
15
+ end
16
+
17
+ def find(revision, options = {})
18
+ m = get_path(path_to_find(revision),
19
+ options,
20
+ Tinybucket::Parser::CommitParser)
21
+
22
+ inject_api_config(m)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ module Tinybucket
2
+ module Api
3
+ class DiffApi < BaseApi
4
+ include Tinybucket::Api::Helper::DiffHelper
5
+
6
+ attr_accessor :repo_owner, :repo_slug
7
+
8
+ def find(spec, options = {})
9
+ get_path(path_to_find(spec), options)
10
+ end
11
+
12
+ def find_patch(spec, options = {})
13
+ get_path(path_to_patch(spec), options)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module Tinybucket
2
+ module Api
3
+ module Helper
4
+ extend ActiveSupport::Autoload
5
+
6
+ [
7
+ :ApiHelper,
8
+ :BranchRestrictionsHelper,
9
+ :CommitsHelper,
10
+ :CommentsHelper,
11
+ :DiffHelper,
12
+ :ReposHelper,
13
+ :RepoHelper,
14
+ :PullRequestsHelper,
15
+ :TeamHelper,
16
+ :UserHelper
17
+ ].each do |klass_name|
18
+ autoload klass_name
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ module Tinybucket
2
+ module Api
3
+ module Helper
4
+ module ApiHelper
5
+ private
6
+
7
+ def next_proc(method, options)
8
+ lambda do |next_page|
9
+ send(method, options.merge(page: next_page))
10
+ end
11
+ end
12
+
13
+ def inject_api_config(result)
14
+ case result
15
+ when Tinybucket::Model::Page
16
+ result.items.map { |m| m.api_config = @config.dup }
17
+ when Tinybucket::Model::Base
18
+ result.api_config = @config.dup
19
+ end
20
+
21
+ result
22
+ end
23
+
24
+ def urlencode(v, key)
25
+ if v.blank? || (escaped = CGI.escape(v.to_s)).blank?
26
+ msg = "Invalid #{key} parameter. (#{v})"
27
+ fail ArgumentError, msg
28
+ end
29
+
30
+ escaped
31
+ end
32
+
33
+ def build_path(base_path, *components)
34
+ components.reduce(base_path) do |path, component|
35
+ part = if component.is_a?(Array)
36
+ urlencode(*component)
37
+ else
38
+ component.to_s
39
+ end
40
+ path + '/' + part
41
+ end
42
+ rescue ArgumentError => e
43
+ raise ArgumentError, "Failed to build request URL: #{e}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,27 @@
1
+ module Tinybucket
2
+ module Api
3
+ module Helper
4
+ module BranchRestrictionsHelper
5
+ include ::Tinybucket::Api::Helper::ApiHelper
6
+
7
+ private
8
+
9
+ def path_to_list
10
+ base_path
11
+ end
12
+
13
+ def path_to_find(restriction_id)
14
+ build_path(base_path,
15
+ [restriction_id, 'restriction_id'])
16
+ end
17
+
18
+ def base_path
19
+ build_path('/repositories',
20
+ [repo_owner, 'repo_owner'],
21
+ [repo_slug, 'repo_slug'],
22
+ 'branch-restrictions')
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,49 @@
1
+ module Tinybucket
2
+ module Api
3
+ module Helper
4
+ module CommentsHelper
5
+ include ::Tinybucket::Api::Helper::ApiHelper
6
+
7
+ private
8
+
9
+ def path_to_list
10
+ base_path
11
+ end
12
+
13
+ def path_to_find(comment_id)
14
+ build_path(base_path,
15
+ [comment_id, 'comment_id'])
16
+ end
17
+
18
+ def base_path
19
+ case commented_to
20
+ when Tinybucket::Model::Commit
21
+ base_path_of_commit
22
+ when Tinybucket::Model::PullRequest
23
+ base_path_of_pullrequest
24
+ else
25
+ fail ArgumentError, 'commented_to must be a pull_request or commit'
26
+ end
27
+ end
28
+
29
+ def base_path_of_commit
30
+ build_path('/repositories',
31
+ [repo_owner, 'repo_owner'],
32
+ [repo_slug, 'repo_slug'],
33
+ 'commit',
34
+ [commented_to.hash, 'revision'],
35
+ 'comments')
36
+ end
37
+
38
+ def base_path_of_pullrequest
39
+ build_path('/repositories',
40
+ [repo_owner, 'repo_owner'],
41
+ [repo_slug, 'repo_slug'],
42
+ 'pullrequests',
43
+ [commented_to.id, 'pull_request_id'],
44
+ 'comments')
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end