horn_of_plenty 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE.txt +19 -0
  5. data/README.md +36 -0
  6. data/lib/horn_of_plenty.rb +22 -0
  7. data/lib/horn_of_plenty/adapters/github/client.rb +82 -0
  8. data/lib/horn_of_plenty/adapters/github/collections/card.rb +46 -0
  9. data/lib/horn_of_plenty/adapters/github/configuration.rb +38 -0
  10. data/lib/horn_of_plenty/adapters/github/error.rb +44 -0
  11. data/lib/horn_of_plenty/adapters/github/parsers/board.rb +52 -0
  12. data/lib/horn_of_plenty/adapters/github/parsers/card.rb +91 -0
  13. data/lib/horn_of_plenty/adapters/github/parsers/issue.rb +95 -0
  14. data/lib/horn_of_plenty/adapters/github/parsers/lane.rb +50 -0
  15. data/lib/horn_of_plenty/adapters/github/parsers/pull_request.rb +38 -0
  16. data/lib/horn_of_plenty/adapters/github/queries/list_boards.rb +18 -0
  17. data/lib/horn_of_plenty/adapters/github/queries/list_cards.rb +19 -0
  18. data/lib/horn_of_plenty/adapters/github/queries/list_issues.rb +22 -0
  19. data/lib/horn_of_plenty/adapters/github/queries/list_lanes.rb +19 -0
  20. data/lib/horn_of_plenty/adapters/github/queries/list_pull_requests.rb +22 -0
  21. data/lib/horn_of_plenty/adapters/github/repositories/board.rb +24 -0
  22. data/lib/horn_of_plenty/adapters/github/repositories/card.rb +24 -0
  23. data/lib/horn_of_plenty/adapters/github/repositories/issue.rb +24 -0
  24. data/lib/horn_of_plenty/adapters/github/repositories/lane.rb +24 -0
  25. data/lib/horn_of_plenty/adapters/github/repositories/pull_request.rb +24 -0
  26. data/lib/horn_of_plenty/adapters/github/requests/list_boards.rb +50 -0
  27. data/lib/horn_of_plenty/adapters/github/requests/list_cards.rb +52 -0
  28. data/lib/horn_of_plenty/adapters/github/requests/list_issues.rb +50 -0
  29. data/lib/horn_of_plenty/adapters/github/requests/list_lanes.rb +52 -0
  30. data/lib/horn_of_plenty/adapters/github/requests/list_pull_requests.rb +50 -0
  31. data/lib/horn_of_plenty/adapters/github/response.rb +16 -0
  32. data/lib/horn_of_plenty/adapters/github/responses/list_boards.rb +17 -0
  33. data/lib/horn_of_plenty/adapters/github/responses/list_cards.rb +23 -0
  34. data/lib/horn_of_plenty/adapters/github/responses/list_issues.rb +18 -0
  35. data/lib/horn_of_plenty/adapters/github/responses/list_lanes.rb +17 -0
  36. data/lib/horn_of_plenty/adapters/github/responses/list_pull_requests.rb +17 -0
  37. data/lib/horn_of_plenty/collection.rb +60 -0
  38. data/lib/horn_of_plenty/core_ext/string.rb +95 -0
  39. data/lib/horn_of_plenty/models/board.rb +32 -0
  40. data/lib/horn_of_plenty/models/card.rb +51 -0
  41. data/lib/horn_of_plenty/models/issue.rb +46 -0
  42. data/lib/horn_of_plenty/models/lane.rb +30 -0
  43. data/lib/horn_of_plenty/models/parsable.rb +44 -0
  44. data/lib/horn_of_plenty/models/pull_request.rb +12 -0
  45. data/lib/horn_of_plenty/null_objects/board.rb +10 -0
  46. data/lib/horn_of_plenty/null_objects/card.rb +10 -0
  47. data/lib/horn_of_plenty/null_objects/issue.rb +10 -0
  48. data/lib/horn_of_plenty/null_objects/lane.rb +10 -0
  49. data/lib/horn_of_plenty/null_objects/pull_request.rb +10 -0
  50. data/lib/horn_of_plenty/paginator.rb +109 -0
  51. data/lib/horn_of_plenty/parsers/hash.rb +95 -0
  52. data/lib/horn_of_plenty/queries/fetch.rb +36 -0
  53. data/lib/horn_of_plenty/repositories/board.rb +26 -0
  54. data/lib/horn_of_plenty/repositories/card.rb +26 -0
  55. data/lib/horn_of_plenty/repositories/issue.rb +26 -0
  56. data/lib/horn_of_plenty/repositories/lane.rb +26 -0
  57. data/lib/horn_of_plenty/repositories/pull_request.rb +26 -0
  58. data/lib/horn_of_plenty/repository.rb +29 -0
  59. data/lib/horn_of_plenty/request.rb +32 -0
  60. data/lib/horn_of_plenty/response.rb +44 -0
  61. data/lib/horn_of_plenty/version.rb +4 -0
  62. data/spec/fixtures/responses/board_github.json +29 -0
  63. data/spec/fixtures/responses/card_github.json +7 -0
  64. data/spec/fixtures/responses/issue_github.json +163 -0
  65. data/spec/fixtures/responses/lane_github.json +7 -0
  66. data/spec/fixtures/responses/pull_request_github.json +361 -0
  67. data/spec/lib/horn_of_plenty/adapters/github/client_spec.rb +12 -0
  68. data/spec/lib/horn_of_plenty/adapters/github/collections/card_spec.rb +14 -0
  69. data/spec/lib/horn_of_plenty/adapters/github/configuration_spec.rb +12 -0
  70. data/spec/lib/horn_of_plenty/adapters/github/error_spec.rb +35 -0
  71. data/spec/lib/horn_of_plenty/adapters/github/parsers/board_spec.rb +39 -0
  72. data/spec/lib/horn_of_plenty/adapters/github/parsers/card_spec.rb +64 -0
  73. data/spec/lib/horn_of_plenty/adapters/github/parsers/issue_spec.rb +47 -0
  74. data/spec/lib/horn_of_plenty/adapters/github/parsers/lane_spec.rb +38 -0
  75. data/spec/lib/horn_of_plenty/adapters/github/parsers/pull_request_spec.rb +50 -0
  76. data/spec/lib/horn_of_plenty/adapters/github/queries/list_boards_spec.rb +19 -0
  77. data/spec/lib/horn_of_plenty/adapters/github/queries/list_cards_spec.rb +19 -0
  78. data/spec/lib/horn_of_plenty/adapters/github/queries/list_issues_spec.rb +19 -0
  79. data/spec/lib/horn_of_plenty/adapters/github/queries/list_lanes_spec.rb +19 -0
  80. data/spec/lib/horn_of_plenty/adapters/github/queries/list_pull_requests_spec.rb +19 -0
  81. data/spec/lib/horn_of_plenty/adapters/github/repositories/board_spec.rb +22 -0
  82. data/spec/lib/horn_of_plenty/adapters/github/repositories/card_spec.rb +67 -0
  83. data/spec/lib/horn_of_plenty/adapters/github/repositories/issue_spec.rb +22 -0
  84. data/spec/lib/horn_of_plenty/adapters/github/repositories/lane_spec.rb +25 -0
  85. data/spec/lib/horn_of_plenty/adapters/github/repositories/pull_request_spec.rb +24 -0
  86. data/spec/lib/horn_of_plenty/adapters/github/requests/list_boards_spec.rb +42 -0
  87. data/spec/lib/horn_of_plenty/adapters/github/requests/list_cards_spec.rb +51 -0
  88. data/spec/lib/horn_of_plenty/adapters/github/requests/list_issues_spec.rb +42 -0
  89. data/spec/lib/horn_of_plenty/adapters/github/requests/list_lanes_spec.rb +51 -0
  90. data/spec/lib/horn_of_plenty/adapters/github/requests/list_pull_requests_spec.rb +42 -0
  91. data/spec/lib/horn_of_plenty/adapters/github/responses/list_boards_spec.rb +78 -0
  92. data/spec/lib/horn_of_plenty/adapters/github/responses/list_cards_spec.rb +86 -0
  93. data/spec/lib/horn_of_plenty/adapters/github/responses/list_issues_spec.rb +104 -0
  94. data/spec/lib/horn_of_plenty/adapters/github/responses/list_lanes_spec.rb +86 -0
  95. data/spec/lib/horn_of_plenty/adapters/github/responses/list_pull_requests_spec.rb +109 -0
  96. data/spec/lib/horn_of_plenty/models/board_spec.rb +10 -0
  97. data/spec/lib/horn_of_plenty/models/card_spec.rb +10 -0
  98. data/spec/lib/horn_of_plenty/models/issue_spec.rb +10 -0
  99. data/spec/lib/horn_of_plenty/models/lane_spec.rb +10 -0
  100. data/spec/lib/horn_of_plenty/models/pull_request_spec.rb +10 -0
  101. data/spec/lib/horn_of_plenty/null_objects/board_spec.rb +10 -0
  102. data/spec/lib/horn_of_plenty/null_objects/card_spec.rb +10 -0
  103. data/spec/lib/horn_of_plenty/null_objects/issue_spec.rb +10 -0
  104. data/spec/lib/horn_of_plenty/null_objects/lane_spec.rb +10 -0
  105. data/spec/lib/horn_of_plenty/null_objects/pull_request_spec.rb +10 -0
  106. data/spec/lib/horn_of_plenty/queries/fetch_spec.rb +15 -0
  107. data/spec/lib/horn_of_plenty/repositories/board_spec.rb +48 -0
  108. data/spec/lib/horn_of_plenty/repositories/card_spec.rb +51 -0
  109. data/spec/lib/horn_of_plenty/repositories/issue_spec.rb +48 -0
  110. data/spec/lib/horn_of_plenty/repositories/lane_spec.rb +51 -0
  111. data/spec/lib/horn_of_plenty/repositories/pull_request_spec.rb +50 -0
  112. data/spec/support/patterns.rb +1 -0
  113. metadata +396 -0
  114. metadata.gz.sig +0 -0
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ require 'digest'
3
+ require 'horn_of_plenty/models/parsable'
4
+
5
+ module HornOfPlenty
6
+ module Models
7
+ class Board
8
+ include Parsable
9
+
10
+ parsable_attributes :id,
11
+ :author_id,
12
+ :title,
13
+ :description,
14
+ :created_at,
15
+ :updated_at
16
+ def to_h
17
+ {
18
+ id: id,
19
+ author_id: author_id,
20
+ title: title,
21
+ description: description,
22
+ created_at: created_at,
23
+ updated_at: updated_at,
24
+ }
25
+ end
26
+
27
+ def to_sha
28
+ @sha ||= Digest::SHA2.hexdigest(to_h.to_s)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+ require 'digest'
3
+ require 'horn_of_plenty/models/parsable'
4
+
5
+ module HornOfPlenty
6
+ module Models
7
+ class Card
8
+ include Parsable
9
+
10
+ parsable_attributes :id,
11
+ :lane_id,
12
+ :repository,
13
+ :status,
14
+ :content_type,
15
+ :content_id,
16
+ :title,
17
+ :description,
18
+ :labels,
19
+ :created_at,
20
+ :updated_at
21
+
22
+ def labels
23
+ @labels || []
24
+ end
25
+
26
+ def status
27
+ @status || nil
28
+ end
29
+
30
+ def to_h
31
+ {
32
+ id: id,
33
+ lane_id: lane_id,
34
+ repository: repository,
35
+ status: status,
36
+ content_type: content_type,
37
+ content_id: content_id,
38
+ title: title,
39
+ description: description,
40
+ labels: labels,
41
+ created_at: created_at,
42
+ updated_at: updated_at,
43
+ }
44
+ end
45
+
46
+ def to_sha
47
+ @sha ||= Digest::SHA2.hexdigest(to_h.to_s)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+ require 'digest'
3
+ require 'horn_of_plenty/models/parsable'
4
+
5
+ module HornOfPlenty
6
+ module Models
7
+ class Issue
8
+ include Parsable
9
+
10
+ parsable_attributes :id,
11
+ :author_id,
12
+ :assignee_ids,
13
+ :closer_id,
14
+ :repository,
15
+ :status,
16
+ :title,
17
+ :description,
18
+ :labels,
19
+ :closed_at,
20
+ :has_pull_request?,
21
+ :created_at,
22
+ :updated_at
23
+ def to_h
24
+ {
25
+ id: id,
26
+ author_id: author_id,
27
+ assignee_ids: assignee_ids,
28
+ closer_id: closer_id,
29
+ repository: repository,
30
+ status: status,
31
+ title: title,
32
+ description: description,
33
+ labels: labels,
34
+ closed_at: closed_at,
35
+ has_pull_request: has_pull_request?,
36
+ created_at: created_at,
37
+ updated_at: updated_at,
38
+ }
39
+ end
40
+
41
+ def to_sha
42
+ @sha ||= Digest::SHA2.hexdigest(to_h.to_s)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ require 'digest'
3
+ require 'horn_of_plenty/models/parsable'
4
+
5
+ module HornOfPlenty
6
+ module Models
7
+ class Lane
8
+ include Parsable
9
+
10
+ parsable_attributes :id,
11
+ :board_id,
12
+ :title,
13
+ :created_at,
14
+ :updated_at
15
+ def to_h
16
+ {
17
+ id: id,
18
+ board_id: board_id,
19
+ title: title,
20
+ created_at: created_at,
21
+ updated_at: updated_at,
22
+ }
23
+ end
24
+
25
+ def to_sha
26
+ @sha ||= Digest::SHA2.hexdigest(to_h.to_s)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ module HornOfPlenty
3
+ module Parsable
4
+ module ClassMethods
5
+ def from_parser(parser:)
6
+ new(parser: parser)
7
+ end
8
+
9
+ def parsable_attributes(*attribute_list)
10
+ attribute_list.each do |attribute|
11
+ instance_variable_name = "@#{attribute.to_s.gsub(/[\?]/, '')}".to_sym
12
+
13
+ define_method attribute do
14
+ if instance_variable_get(instance_variable_name).nil?
15
+ parser.__send__(attribute)
16
+ else
17
+ instance_variable_get(instance_variable_name)
18
+ end
19
+ end
20
+
21
+ define_method "#{attribute}=" do |other|
22
+ instance_variable_set(instance_variable_name, other)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ attr_accessor :parser
29
+
30
+ def initialize(parser: nil, **args)
31
+ self.parser = parser
32
+
33
+ if defined?(super) && args.empty?
34
+ super()
35
+ elsif defined?(super)
36
+ super(**args)
37
+ end
38
+ end
39
+
40
+ def self.included(base)
41
+ base.extend ClassMethods
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require 'digest'
3
+ require 'horn_of_plenty/models/parsable'
4
+ require 'horn_of_plenty/models/issue'
5
+
6
+ module HornOfPlenty
7
+ module Models
8
+ class PullRequest < Issue
9
+ parsable_attributes :merger_id
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require 'null_and_void/nullified'
3
+
4
+ module HornOfPlenty
5
+ module NullObjects
6
+ class Board
7
+ include NullAndVoid::Nullified
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require 'null_and_void/nullified'
3
+
4
+ module HornOfPlenty
5
+ module NullObjects
6
+ class Card
7
+ include NullAndVoid::Nullified
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require 'null_and_void/nullified'
3
+
4
+ module HornOfPlenty
5
+ module NullObjects
6
+ class Issue
7
+ include NullAndVoid::Nullified
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require 'null_and_void/nullified'
3
+
4
+ module HornOfPlenty
5
+ module NullObjects
6
+ class Lane
7
+ include NullAndVoid::Nullified
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require 'null_and_void/nullified'
3
+
4
+ module HornOfPlenty
5
+ module NullObjects
6
+ class PullRequest
7
+ include NullAndVoid::Nullified
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+ require 'forwardable'
3
+
4
+ module HornOfPlenty
5
+ class Paginator
6
+ include Enumerable
7
+ extend Forwardable
8
+
9
+ def_delegators :items,
10
+ :length,
11
+ :size,
12
+ :count,
13
+ :empty?,
14
+ :[],
15
+ :first
16
+
17
+ def initialize(client:,
18
+ request:,
19
+ items_per_page: nil,
20
+ current_page: nil,
21
+ autopage: true)
22
+
23
+ self.client = client
24
+ self.request = request
25
+
26
+ self.items_per_page = items_per_page || 500
27
+ self.current_page = current_page || 1
28
+ self.autopage = autopage
29
+ end
30
+
31
+ def all
32
+ items
33
+ end
34
+
35
+ def each(_options = {})
36
+ loop do
37
+ items.each do |item|
38
+ yield item
39
+ end
40
+
41
+ break unless autopage && go_to_next_page
42
+ end
43
+ end
44
+
45
+ def each_page
46
+ loop do
47
+ yield items
48
+
49
+ break unless go_to_next_page
50
+ end
51
+ end
52
+
53
+ def go_to_next_page
54
+ return false if items.count < items_per_page
55
+
56
+ go_to_page(current_page + 1)
57
+ end
58
+
59
+ def go_to_previous_page
60
+ go_to_page(current_page - 1)
61
+ end
62
+
63
+ def go_to_page(page_number)
64
+ page_number = 1 if page_number < 1
65
+
66
+ self.current_page = page_number
67
+ end
68
+
69
+ def items
70
+ @items ||= retrieval_result.result
71
+ end
72
+
73
+ protected
74
+
75
+ attr_accessor :client,
76
+ :request,
77
+ :autopage
78
+ attr_reader :items_per_page,
79
+ :current_page,
80
+ :current_offset
81
+
82
+ def items_per_page=(value)
83
+ @items_per_page = value.to_i
84
+ @retrieval_result = nil
85
+ end
86
+
87
+ def current_page=(value)
88
+ @current_page = value.to_i
89
+ @current_offset = (@current_page - 1) * items_per_page
90
+ @retrieval_result = nil
91
+ @items = nil
92
+ end
93
+
94
+ private
95
+
96
+ def retrieval_result
97
+ request.pagination = pagination_parameters
98
+
99
+ client.request(request)
100
+ end
101
+
102
+ def pagination_parameters
103
+ {
104
+ limit: items_per_page,
105
+ offset: current_offset,
106
+ }
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable Style/OptionHash
3
+ module HornOfPlenty
4
+ module Parsers
5
+ module Hash
6
+ private
7
+
8
+ def parse_text(hash, key, options = {}, &user_block)
9
+ parse_key(hash, key, ->(value) { value.to_s }, options, &user_block)
10
+ end
11
+
12
+ def parse_html(hash, key, options = {}, &user_block)
13
+ converter = ->(value) { CGI.unescape_html(value.to_s) }
14
+
15
+ parse_key(hash, key, converter, options, &user_block)
16
+ end
17
+
18
+ def parse_integer(hash, key, options = {}, &user_block)
19
+ parse_key(hash, key, ->(value) { value.to_i }, options, &user_block)
20
+ end
21
+
22
+ def parse_float(hash, key, options = {}, &user_block)
23
+ parse_key(hash, key, ->(value) { value.to_f }, options, &user_block)
24
+ end
25
+
26
+ def parse_time(hash, key, options = {}, &user_block)
27
+ parse_key(hash, key, ->(value) { Time.iso8601(value).round }, options, &user_block)
28
+ end
29
+
30
+ def parse_url(hash, key, options = {}, &user_block)
31
+ parse_key(hash, key, ->(value) { URI.parse(value) }, options, &user_block)
32
+ end
33
+
34
+ def parse_phone(hash, key, options = {}, &user_block)
35
+ parse_key(hash, key, ->(value) { value.gsub(/[^x\d]/, '') }, options, &user_block)
36
+ end
37
+
38
+ def parse_existance(hash, key, options = {}, &user_block)
39
+ parse_key(hash, key, ->(value) { value }, options, &user_block)
40
+ end
41
+
42
+ def parse_boolean(hash, key, options = {}, &user_block)
43
+ converter = lambda do |value|
44
+ if value
45
+ %w{true TRUE True t T yes YES Yes y Y 1}.include?(value) ? true : false
46
+ end
47
+ end
48
+
49
+ parse_key(hash, key, converter, options, &user_block)
50
+ end
51
+
52
+ def parse_percentage(hash, key, options = {}, &user_block)
53
+ parse_key(hash, key, ->(value) { (value.to_f / 100).round(4) }, options, &user_block)
54
+ end
55
+
56
+ # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
57
+ def parse_key(hash, key, converter = nil, options = {})
58
+ default_value = if options[:default_value]
59
+ options[:default_value]
60
+ elsif options[:array]
61
+ []
62
+ end
63
+
64
+ value = hash.dig(*key.split('/:/'))
65
+ value = if value.to_s.empty?
66
+ default_value
67
+ else
68
+ value
69
+ end
70
+ value = if options[:array] && value.respond_to?(:split)
71
+ value.split(',')
72
+ else
73
+ value
74
+ end
75
+ value = if value.respond_to?(:map) && converter
76
+ value.map do |item|
77
+ converter.call(item)
78
+ end
79
+ elsif value && converter
80
+ converter.call(value)
81
+ else
82
+ value
83
+ end
84
+
85
+ if block_given? && (value || options[:yield_if_nil])
86
+ yield value
87
+ else
88
+ value
89
+ end
90
+ end
91
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
92
+ end
93
+ end
94
+ end
95
+ # rubocop:enable Style/OptionHash