pact_broker 2.105.0 → 2.106.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -1
  3. data/README.md +1 -1
  4. data/db/migrations/20221130_add_provider_version_id_index_to_verifications.rb +28 -0
  5. data/db/migrations/20221208_add_index_to_pact_version_provider_tag_successful_verifications.rb +21 -0
  6. data/db/migrations/20221215_add_prov_ver_id_ndx_to_latest_verifi_id_for_pact_ver_and_prov_ver.rb +21 -0
  7. data/db/migrations/20230131_add_cons_ver_id_ndx_to_latest_pp_id_for_cons_ver.rb +17 -0
  8. data/docs/CONFIGURATION.md +1 -1
  9. data/docs/api/PAGINATION.md +43 -0
  10. data/lib/pact_broker/api/contracts/publish_contracts_schema.rb +13 -1
  11. data/lib/pact_broker/api/contracts/utf_8_validation.rb +17 -0
  12. data/lib/pact_broker/api/contracts/webhook_contract.rb +2 -0
  13. data/lib/pact_broker/api/decorators/custom_error_problem_json_decorator.rb +36 -0
  14. data/lib/pact_broker/api/decorators/pacticipant_collection_decorator.rb +3 -0
  15. data/lib/pact_broker/api/decorators/pagination_links.rb +11 -0
  16. data/lib/pact_broker/api/decorators/runtime_error_problem_json_decorator.rb +34 -0
  17. data/lib/pact_broker/api/decorators/validation_errors_problem_json_decorator.rb +66 -0
  18. data/lib/pact_broker/api/resources/badge_methods.rb +1 -1
  19. data/lib/pact_broker/api/resources/base_resource.rb +28 -48
  20. data/lib/pact_broker/api/resources/error_handling_methods.rb +57 -0
  21. data/lib/pact_broker/api/resources/error_response_generator.rb +70 -0
  22. data/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb +1 -1
  23. data/lib/pact_broker/api/resources/pact_version.rb +1 -1
  24. data/lib/pact_broker/api/resources/pacticipants.rb +4 -1
  25. data/lib/pact_broker/api/resources/pagination_methods.rb +8 -4
  26. data/lib/pact_broker/api/resources/publish_contracts.rb +1 -1
  27. data/lib/pact_broker/api/resources/versions.rb +5 -12
  28. data/lib/pact_broker/api.rb +3 -4
  29. data/lib/pact_broker/app.rb +0 -2
  30. data/lib/pact_broker/application_context.rb +4 -4
  31. data/lib/pact_broker/db/clean_incremental.rb +67 -59
  32. data/lib/pact_broker/index/service.rb +1 -1
  33. data/lib/pact_broker/locale/en.yml +1 -0
  34. data/lib/pact_broker/pacticipants/repository.rb +4 -11
  35. data/lib/pact_broker/pacticipants/service.rb +4 -8
  36. data/lib/pact_broker/pacts/selected_pact.rb +4 -0
  37. data/lib/pact_broker/repositories/helpers.rb +11 -0
  38. data/lib/pact_broker/repositories/page.rb +24 -0
  39. data/lib/pact_broker/string_refinements.rb +4 -0
  40. data/lib/pact_broker/tasks/clean_task.rb +7 -3
  41. data/lib/pact_broker/ui/views/matrix/show.haml +1 -1
  42. data/lib/pact_broker/verifications/repository.rb +14 -11
  43. data/lib/pact_broker/version.rb +1 -1
  44. data/lib/pact_broker/versions/repository.rb +12 -0
  45. data/lib/pact_broker/versions/service.rb +4 -0
  46. data/lib/rack/pact_broker/request_target.rb +1 -1
  47. data/lib/webmachine/application_monkey_patch.rb +10 -0
  48. data/lib/webmachine/render_error_monkey_patch.rb +70 -0
  49. data/pact_broker.gemspec +1 -1
  50. metadata +19 -7
  51. data/lib/pact_broker/api/resources/error_response_body_generator.rb +0 -41
  52. data/lib/rack/pact_broker/convert_404_to_hal.rb +0 -20
@@ -0,0 +1,70 @@
1
+ require "pact_broker/configuration"
2
+ require "pact_broker/api/decorators/runtime_error_problem_json_decorator"
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Resources
7
+ class ErrorResponseGenerator
8
+ include PactBroker::Logging
9
+
10
+ # @param error [StandardError]
11
+ # @param error_reference [String] an error reference to display to the user
12
+ # @param env [Hash] the rack env
13
+ # @return [Hash, String] the response headers to set, the response body to set
14
+ def self.call error, error_reference, env = {}
15
+ body = response_body_hash(error, error_reference, env, display_message(error, obfuscated_error_message(error_reference)))
16
+ return headers(env), body.to_json
17
+ end
18
+
19
+ def self.display_message(error, obfuscated_message)
20
+ if PactBroker.configuration.show_backtrace_in_error_response?
21
+ error.message || obfuscated_message
22
+ else
23
+ PactBroker::Errors.reportable_error?(error) ? obfuscated_message : error.message
24
+ end
25
+ end
26
+
27
+ private_class_method def self.response_body_hash(error, error_reference, env, message)
28
+ if problem_json?(env)
29
+ problem_json_response_body(message, env)
30
+ else
31
+ hal_json_response_body(error, error_reference, message)
32
+ end
33
+ end
34
+
35
+ private_class_method def self.hal_json_response_body(error, error_reference, message)
36
+ response_body = {
37
+ error: {
38
+ message: message,
39
+ reference: error_reference
40
+ }
41
+ }
42
+ if PactBroker.configuration.show_backtrace_in_error_response?
43
+ response_body[:error][:backtrace] = error.backtrace
44
+ end
45
+ response_body
46
+ end
47
+
48
+ private_class_method def self.problem_json_response_body(message, env)
49
+ PactBroker::Api::Decorators::RuntimeErrorProblemJSONDecorator.new(message).to_hash(user_options: { base_url: env["pactbroker.base_url" ] })
50
+ end
51
+
52
+ private_class_method def self.obfuscated_error_message(error_reference)
53
+ "An error has occurred. The details have been logged with the reference #{error_reference}"
54
+ end
55
+
56
+ private_class_method def self.headers(env)
57
+ if problem_json?(env)
58
+ { "Content-Type" => "application/problem+json;charset=utf-8" }
59
+ else
60
+ { "Content-Type" => "application/hal+json;charset=utf-8" }
61
+ end
62
+ end
63
+
64
+ private_class_method def self.problem_json?(env)
65
+ env["HTTP_ACCEPT"]&.include?("application/problem+json")
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -27,7 +27,7 @@ module PactBroker
27
27
  end
28
28
 
29
29
  def policy_name
30
- :'verifications::verifications'
30
+ :'pacticipants::pacticipant'
31
31
  end
32
32
 
33
33
  private
@@ -11,7 +11,7 @@ module PactBroker
11
11
  ["GET", "OPTIONS"]
12
12
  end
13
13
 
14
- def decorator_options(options)
14
+ def decorator_options(options = {})
15
15
  super(options.merge(consumer_versions: consumer_versions_from_metadata&.reverse))
16
16
  end
17
17
  end
@@ -3,12 +3,15 @@ require "pact_broker/api/decorators/pacticipant_decorator"
3
3
  require "pact_broker/domain/pacticipant"
4
4
  require "pact_broker/hash_refinements"
5
5
  require "pact_broker/api/contracts/pacticipant_create_schema"
6
+ require "pact_broker/api/resources/pagination_methods"
6
7
 
7
8
  module PactBroker
8
9
  module Api
9
10
  module Resources
10
11
  class Pacticipants < BaseResource
11
12
  using PactBroker::HashRefinements
13
+ include PaginationMethods
14
+
12
15
 
13
16
  def content_types_provided
14
17
  [["application/hal+json", :to_json]]
@@ -44,7 +47,7 @@ module PactBroker
44
47
  end
45
48
 
46
49
  def to_json
47
- generate_json(pacticipant_service.find_all_pacticipants)
50
+ generate_json(pacticipant_service.find_all_pacticipants(pagination_options))
48
51
  end
49
52
 
50
53
  def generate_json pacticipants
@@ -3,10 +3,14 @@ module PactBroker
3
3
  module Resources
4
4
  module PaginationMethods
5
5
  def pagination_options
6
- {
7
- page_number: request.query["pageNumber"]&.to_i,
8
- page_size: request.query["pageSize"]&.to_i
9
- }.compact
6
+ if request.query["pageNumber"] || request.query["pageSize"]
7
+ {
8
+ page_number: request.query["pageNumber"]&.to_i || 1,
9
+ page_size: request.query["pageSize"]&.to_i || 100
10
+ }
11
+ else
12
+ {}
13
+ end
10
14
  end
11
15
  end
12
16
  end
@@ -40,7 +40,7 @@ module PactBroker
40
40
  :'contracts::contracts'
41
41
  end
42
42
 
43
- # for Pactflow
43
+ # for PactFlow
44
44
  def policy_record
45
45
  @policy_record ||= pacticipant_service.find_pacticipant_by_name(parsed_contracts.pacticipant_name)
46
46
  end
@@ -1,11 +1,15 @@
1
1
  require "pact_broker/api/resources/base_resource"
2
2
  require "pact_broker/configuration"
3
3
  require "pact_broker/api/decorators/versions_decorator"
4
+ require "pact_broker/api/resources/pagination_methods"
5
+
4
6
 
5
7
  module PactBroker
6
8
  module Api
7
9
  module Resources
8
10
  class Versions < BaseResource
11
+ include PaginationMethods
12
+
9
13
  def content_types_provided
10
14
  [["application/hal+json", :to_json]]
11
15
  end
@@ -23,23 +27,12 @@ module PactBroker
23
27
  end
24
28
 
25
29
  def versions
26
- @versions ||= pacticipant_service.find_all_pacticipant_versions_in_reverse_order(pacticipant_name, pagination_options)
30
+ @versions ||= version_service.find_all_pacticipant_versions_in_reverse_order(pacticipant_name, pagination_options)
27
31
  end
28
32
 
29
33
  def policy_name
30
34
  :'versions::versions'
31
35
  end
32
-
33
- def pagination_options
34
- if request.query["pageNumber"] || request.query["pageSize"]
35
- {
36
- page_number: request.query["pageNumber"]&.to_i || 1,
37
- page_size: request.query["pageSize"]&.to_i || 100
38
- }
39
- else
40
- nil
41
- end
42
- end
43
36
  end
44
37
  end
45
38
  end
@@ -1,4 +1,6 @@
1
1
  require "webmachine/adapters/rack_mapped"
2
+ require "webmachine/application_monkey_patch"
3
+ require "webmachine/render_error_monkey_patch"
2
4
  require "pact_broker/db/models"
3
5
  require "pact_broker/api/resources"
4
6
  require "pact_broker/api/decorators"
@@ -140,10 +142,7 @@ module PactBroker
140
142
  end
141
143
  end
142
144
 
143
- # naughty, but better than setting each route manually
144
- pact_api.routes.each do | route |
145
- route.instance_variable_get(:@bindings)[:application_context] = application_context
146
- end
145
+ pact_api.application_context = application_context
147
146
 
148
147
  pact_api.configure do |config|
149
148
  config.adapter = :RackMapped
@@ -20,7 +20,6 @@ require "rack/pact_broker/ui_request_filter"
20
20
  require "rack/pact_broker/ui_authentication"
21
21
  require "rack/pact_broker/configurable_make_it_later"
22
22
  require "rack/pact_broker/no_auth"
23
- require "rack/pact_broker/convert_404_to_hal"
24
23
  require "rack/pact_broker/reset_thread_data"
25
24
  require "rack/pact_broker/add_vary_header"
26
25
  require "rack/pact_broker/use_when"
@@ -256,7 +255,6 @@ module PactBroker
256
255
  api_apps.unshift(@custom_api) if @custom_api
257
256
  builder = ::Rack::Builder.new
258
257
  builder.use @make_it_later_api_auth
259
- builder.use Rack::PactBroker::Convert404ToHal
260
258
  builder.use Rack::PactBroker::DatabaseTransaction, configuration.database_connection
261
259
  builder.run Rack::Cascade.new(api_apps, [404])
262
260
  builder
@@ -3,7 +3,7 @@ require "pact_broker/api/contracts/configuration"
3
3
  require "pact_broker/api/decorators/decorator_context_creator"
4
4
  require "pact_broker/webhooks/execution_configuration_creator"
5
5
  require "pact_broker/errors/error_logger"
6
- require "pact_broker/api/resources/error_response_body_generator"
6
+ require "pact_broker/api/resources/error_response_generator"
7
7
 
8
8
  module PactBroker
9
9
  class ApplicationContext
@@ -15,7 +15,7 @@ module PactBroker
15
15
  :before_resource,
16
16
  :after_resource,
17
17
  :error_logger,
18
- :error_response_body_generator
18
+ :error_response_generator
19
19
 
20
20
  def initialize(params = {})
21
21
  params_with_defaults = {
@@ -24,7 +24,7 @@ module PactBroker
24
24
  decorator_context_creator: PactBroker::Api::Decorators::DecoratorContextCreator,
25
25
  webhook_execution_configuration_creator: PactBroker::Webhooks::ExecutionConfigurationCreator,
26
26
  error_logger: PactBroker::Errors::ErrorLogger,
27
- error_response_body_generator: PactBroker::Api::Resources::ErrorResponseBodyGenerator
27
+ error_response_generator: PactBroker::Api::Resources::ErrorResponseGenerator
28
28
  }.merge(params)
29
29
 
30
30
  @decorator_configuration = params_with_defaults[:decorator_configuration]
@@ -35,7 +35,7 @@ module PactBroker
35
35
  @before_resource = params_with_defaults[:before_resource]
36
36
  @after_resource = params_with_defaults[:after_resource]
37
37
  @error_logger = params_with_defaults[:error_logger]
38
- @error_response_body_generator = params_with_defaults[:error_response_body_generator]
38
+ @error_response_generator = params_with_defaults[:error_response_generator]
39
39
 
40
40
  end
41
41
 
@@ -25,6 +25,36 @@ module PactBroker
25
25
  @options = options
26
26
  end
27
27
 
28
+ def call
29
+ require "pact_broker/db/models"
30
+
31
+ if dry_run?
32
+ dry_run_results
33
+ else
34
+ execute_clean
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :db, :options
41
+
42
+ def execute_clean
43
+ db.transaction do
44
+ before_counts = current_counts
45
+ PactBroker::Domain::Version.where(id: versions_to_delete.from_self.select_map(:id)).delete
46
+ delete_orphan_pact_versions
47
+ after_counts = current_counts
48
+
49
+ TABLES.each_with_object({}) do | table_name, comparison_counts |
50
+ comparison_counts[table_name.to_s] = {
51
+ "deleted" => before_counts[table_name] - after_counts[table_name],
52
+ "kept" => after_counts[table_name]
53
+ }
54
+ end
55
+ end
56
+ end
57
+
28
58
  def logger
29
59
  options[:logger] || PactBroker.logger
30
60
  end
@@ -42,47 +72,20 @@ module PactBroker
42
72
  options[:limit] || 1000
43
73
  end
44
74
 
45
- def resolve_ids(query, column_name = :id)
46
- query.collect { |h| h[column_name] }
47
- end
48
-
49
- def version_ids_to_delete
50
- db[:versions].where(id: version_ids_to_keep).invert.limit(limit).order(Sequel.asc(:id))
75
+ def versions_to_delete(columns = [:id])
76
+ fully_qualified_columns = columns.collect { |col| Sequel[:versions][col] }
77
+ PactBroker::Domain::Version
78
+ .select(*fully_qualified_columns)
79
+ .left_outer_join(version_ids_to_keep, { Sequel[:versions][:id] => Sequel[:keep_versions][:id] }, table_alias: :keep_versions)
80
+ .where(Sequel[:keep_versions][:id] => nil)
81
+ .order(Sequel.asc( Sequel[:versions][:id]))
82
+ .limit(limit)
51
83
  end
52
84
 
53
85
  def version_ids_to_keep
54
- @version_ids_to_keep ||= selected_versions_to_keep.reduce(&:union)
86
+ @version_ids_to_keep ||= keep.collect { |selector| PactBroker::Domain::Version.select(:id).for_selector(selector) }.reduce(&:union)
55
87
  end
56
88
 
57
- def selected_versions_to_keep
58
- keep.collect do | selector |
59
- PactBroker::Domain::Version.select(:id).for_selector(selector)
60
- end
61
- end
62
-
63
- def call
64
- require "pact_broker/db/models"
65
-
66
- if dry_run?
67
- dry_run_results
68
- else
69
- db.transaction do
70
- before_counts = current_counts
71
- PactBroker::Domain::Version.where(id: resolve_ids(version_ids_to_delete)).delete
72
- delete_orphan_pact_versions
73
- after_counts = current_counts
74
-
75
- TABLES.each_with_object({}) do | table_name, comparison_counts |
76
- comparison_counts[table_name.to_s] = { "deleted" => before_counts[table_name] - after_counts[table_name], "kept" => after_counts[table_name] }
77
- end
78
- end
79
- end
80
- end
81
-
82
- private
83
-
84
- attr_reader :db, :options
85
-
86
89
  def current_counts
87
90
  TABLES.each_with_object({}) do | table_name, counts |
88
91
  counts[table_name] = db[table_name].count
@@ -122,8 +125,8 @@ module PactBroker
122
125
  end
123
126
 
124
127
  def dry_run_results
125
- to_delete = dry_run_to_delete
126
- to_keep = dry_run_to_keep
128
+ to_delete = dry_run_to_delete_by_pacticipant
129
+ to_keep = dry_run_to_keep_by_pacticipant
127
130
 
128
131
  kept_per_selector = keep.collect do | selector |
129
132
  {
@@ -141,7 +144,7 @@ module PactBroker
141
144
 
142
145
  total_versions_count = PactBroker::Domain::Version.count
143
146
  versions_to_keep_count = version_ids_to_keep.count
144
- versions_to_delete_count = version_ids_to_delete.count
147
+ versions_to_delete_count = versions_to_delete.count
145
148
 
146
149
  {
147
150
  "counts" => {
@@ -155,9 +158,15 @@ module PactBroker
155
158
  }
156
159
  end
157
160
 
158
- def dry_run_latest_versions_to_keep
159
- latest_undeleted_versions_by_order = PactBroker::Domain::Version.where(id: version_ids_to_delete.select(:id))
160
- .invert
161
+ def expected_remaining_versions
162
+ PactBroker::Domain::Version
163
+ .left_outer_join(versions_to_delete, { Sequel[:versions][:id] => Sequel[:delete_versions][:id] }, table_alias: :delete_versions )
164
+ .where(Sequel[:delete_versions][:id] => nil)
165
+ end
166
+
167
+ # Returns the latest version that will be kept for each pacticipant
168
+ def dry_run_latest_versions_to_keep_by_pacticipant
169
+ latest_undeleted_versions_by_order = expected_remaining_versions
161
170
  .select_group(:pacticipant_id)
162
171
  .select_append{ max(order).as(latest_order) }
163
172
 
@@ -171,9 +180,9 @@ module PactBroker
171
180
  .join(latest_undeleted_versions_by_order, lv_versions_join, { table_alias: :lv })
172
181
  end
173
182
 
174
- def dry_run_earliest_versions_to_keep
175
- earliest_undeleted_versions_by_order = PactBroker::Domain::Version.where(id: version_ids_to_delete.select(:id))
176
- .invert
183
+ # Returns the earliest version that will be kept for each pacticipant
184
+ def dry_run_earliest_versions_to_keep_by_pacticipant
185
+ earliest_undeleted_versions_by_order = expected_remaining_versions
177
186
  .select_group(:pacticipant_id)
178
187
  .select_append{ min(order).as(first_order) }
179
188
 
@@ -187,13 +196,16 @@ module PactBroker
187
196
  .join(earliest_undeleted_versions_by_order, ev_versions_join, { table_alias: :lv })
188
197
  end
189
198
 
190
- def dry_run_to_delete
191
- PactBroker::Domain::Version
192
- .where(id: version_ids_to_delete.select(:id))
199
+ # Returns Hash of pacticipant name => Hash, where the Hash value contains the count, fromVersion and toVersion
200
+ # that will be deleted.
201
+ # @return Hash
202
+ def dry_run_to_delete_by_pacticipant
203
+ versions_to_delete
204
+ .select(Sequel[:versions].*)
193
205
  .all
194
206
  .group_by{ | v | v.pacticipant_id }
195
- .each_with_object({}) do | (_pacticipant_id, versions), thing |
196
- thing[versions.first.pacticipant.name] = {
207
+ .each_with_object({}) do | (_pacticipant_id, versions), hash |
208
+ hash[versions.first.pacticipant.name] = {
197
209
  "count" => versions.count,
198
210
  "fromVersion" => version_info(versions.first),
199
211
  "toVersion" => version_info(versions.last)
@@ -202,14 +214,14 @@ module PactBroker
202
214
  end
203
215
 
204
216
  # rubocop: disable Metrics/CyclomaticComplexity
205
- def dry_run_to_keep
206
- latest_to_keep = dry_run_latest_versions_to_keep.eager(:tags).each_with_object({}) do | version, r |
217
+ def dry_run_to_keep_by_pacticipant
218
+ latest_to_keep = dry_run_latest_versions_to_keep_by_pacticipant.eager(:tags).each_with_object({}) do | version, r |
207
219
  r[version.pacticipant_id] = {
208
220
  "firstVersion" => version_info(version)
209
221
  }
210
222
  end
211
223
 
212
- earliest_to_keep = dry_run_earliest_versions_to_keep.eager(:tags).each_with_object({}) do | version, r |
224
+ earliest_to_keep = dry_run_earliest_versions_to_keep_by_pacticipant.eager(:tags).each_with_object({}) do | version, r |
213
225
  r[version.pacticipant_id] = {
214
226
  "latestVersion" => version_info(version)
215
227
  }
@@ -226,14 +238,10 @@ module PactBroker
226
238
  # rubocop: enable Metrics/CyclomaticComplexity
227
239
 
228
240
  def counts_to_keep
229
- db[:versions].where(id: version_ids_to_delete.select(:id))
230
- .invert
241
+ expected_remaining_versions
231
242
  .select_group(:pacticipant_id)
232
243
  .select_append{ count(1).as(count) }
233
- .all
234
- .each_with_object({}) do | row, counts |
235
- counts[row[:pacticipant_id]] = row[:count]
236
- end
244
+ .as_hash(:pacticipant_id, :count)
237
245
  end
238
246
 
239
247
  def pacticipants
@@ -18,7 +18,7 @@ module PactBroker
18
18
  DEFAULT_PAGE_NUMBER = 1
19
19
 
20
20
  # This method provides data for both the OSS server side rendered index (with and without tags)
21
- # and the Pactflow UI. It really needs to be broken into to separate methods, as it's getting too messy
21
+ # and the PactFlow UI. It really needs to be broken into to separate methods, as it's getting too messy
22
22
  # supporting both
23
23
 
24
24
  def self.pact_publication_scope
@@ -109,6 +109,7 @@ en:
109
109
  new_line_in_url_path: URL path cannot contain a new line character.
110
110
  tab_in_url_path: URL path cannot contain a tab character.
111
111
  non_utf_8_char_in_request_body: "Request body has a non UTF-8 character at char %{char_number} and cannot be parsed as JSON. Fragment preceding invalid character is: '%{fragment}'"
112
+ non_utf_8_char_in_contract: "Contract has a non UTF-8 character at char %{char_number} and cannot be parsed as JSON. Fragment preceding invalid character is: '%{fragment}'"
112
113
 
113
114
  "400":
114
115
  title: 400 Malformed Request
@@ -26,21 +26,14 @@ module PactBroker
26
26
  PactBroker::Domain::Pacticipant.where(id: id).single_record
27
27
  end
28
28
 
29
- def find_all
30
- find
29
+ def find_all(pagination_options = {})
30
+ find({}, pagination_options)
31
31
  end
32
32
 
33
- def find options = {}
33
+ def find(options = {}, pagination_options = {})
34
34
  query = PactBroker::Domain::Pacticipant.select_all_qualified
35
35
  query = query.label(options[:label_name]) if options[:label_name]
36
- query.order_ignore_case(Sequel[:pacticipants][:name]).eager(:labels).eager(:latest_version).all
37
- end
38
-
39
- def find_all_pacticipant_versions_in_reverse_order name, pagination_options = nil
40
- pacticipant = pacticipant_repository.find_by_name!(name)
41
- query = PactBroker::Domain::Version.where(pacticipant: pacticipant).reverse_order(:order)
42
- query = query.paginate(pagination_options[:page_number], pagination_options[:page_size]) if pagination_options
43
- query
36
+ query.order_ignore_case(Sequel[:pacticipants][:name]).eager(:labels).eager(:latest_version).all_with_pagination_options(pagination_options)
44
37
  end
45
38
 
46
39
  def find_by_name_or_create name
@@ -32,8 +32,8 @@ module PactBroker
32
32
  } .collect{ | name | pacticipant_repository.find_by_name(name) }
33
33
  end
34
34
 
35
- def self.find_all_pacticipants
36
- pacticipant_repository.find_all
35
+ def self.find_all_pacticipants(pagination_options = {})
36
+ pacticipant_repository.find_all(pagination_options)
37
37
  end
38
38
 
39
39
  def self.find_pacticipant_by_name(name)
@@ -48,12 +48,8 @@ module PactBroker
48
48
  pacticipant_repository.find_by_id(id)
49
49
  end
50
50
 
51
- def self.find(options)
52
- pacticipant_repository.find options
53
- end
54
-
55
- def self.find_all_pacticipant_versions_in_reverse_order(name, pagination_options = nil)
56
- pacticipant_repository.find_all_pacticipant_versions_in_reverse_order(name, pagination_options)
51
+ def self.find(options, pagination_options = {})
52
+ pacticipant_repository.find(options, pagination_options)
57
53
  end
58
54
 
59
55
  def self.find_pacticipant_repository_url_by_pacticipant_name(name)
@@ -2,9 +2,13 @@ require "delegate"
2
2
 
3
3
  module PactBroker
4
4
  module Pacts
5
+
5
6
  class SelectedPact < SimpleDelegator
6
7
  attr_reader :pact, :selectors
7
8
 
9
+ # @param pact [PactBroker::Domain::Pact]
10
+ # @param selectors [PactBroker::Pacts::Selectors<PactBroker::Pacts::Selector::ResolvedSelector>] the Selectors object
11
+ # containing the ResolvedSelector objects that caused the pact to be selected.
8
12
  def initialize(pact, selectors)
9
13
  super(pact)
10
14
  @pact = pact
@@ -1,3 +1,5 @@
1
+ require "pact_broker/repositories/page"
2
+
1
3
  Sequel.extension :escaped_like
2
4
 
3
5
  module PactBroker
@@ -6,6 +8,15 @@ module PactBroker
6
8
 
7
9
  extend self
8
10
 
11
+ def all_with_pagination_options(pagination_options)
12
+ if pagination_options&.any?
13
+ query = paginate(pagination_options[:page_number], pagination_options[:page_size])
14
+ Page.new(query.all, query)
15
+ else
16
+ all
17
+ end
18
+ end
19
+
9
20
  def all_forbidding_lazy_load
10
21
  all.each{ | row | row.forbid_lazy_load if row.respond_to?(:forbid_lazy_load) }
11
22
  end
@@ -0,0 +1,24 @@
1
+ require "forwardable"
2
+
3
+ # An array that provides the pagination details
4
+
5
+ module PactBroker
6
+ module Repositories
7
+ module Helpers
8
+ class Page < Array
9
+ extend Forwardable
10
+
11
+ attr_reader :query
12
+
13
+ PAGE_PROPERTIES = [:page_size, :page_count, :page_range, :current_page, :next_page, :prev_page, :first_page?, :last_page?, :pagination_record_count, :current_page_record_count, :current_page_record_range]
14
+
15
+ delegate PAGE_PROPERTIES => :query
16
+
17
+ def initialize(array, query)
18
+ super(array)
19
+ @query = query
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -59,6 +59,10 @@ module PactBroker
59
59
  .downcase
60
60
  end
61
61
 
62
+ def dasherize
63
+ snakecase.tr("_", "-")
64
+ end
65
+
62
66
  # ripped from rubyworks/facets, thank you
63
67
  def camelcase(*separators)
64
68
  case separators.first
@@ -44,7 +44,7 @@ module PactBroker
44
44
  raise PactBroker::Error.new("You must specify which versions to keep")
45
45
  else
46
46
  add_defaults_to_keep_selectors
47
- output "#{prefix}Deleting oldest #{version_deletion_limit} versions, keeping versions that match the configured selectors", keep_version_selectors
47
+ output "#{prefix}Deleting oldest #{version_deletion_limit} versions, keeping versions that match the configured selectors", keep_version_selectors.collect(&:to_hash)
48
48
  end
49
49
 
50
50
  start_time = Time.now
@@ -68,11 +68,15 @@ module PactBroker
68
68
 
69
69
  def add_defaults_to_keep_selectors
70
70
  if keep_version_selectors.none?(&:currently_deployed?)
71
- keep_version_selectors << PactBroker::DB::Clean::Selector.new(deployed: true)
71
+ selector = PactBroker::DB::Clean::Selector.new(deployed: true)
72
+ output("Automatically adding #{selector.to_hash} to keep version selectors")
73
+ keep_version_selectors << selector
72
74
  end
73
75
 
74
76
  if keep_version_selectors.none?(&:currently_supported?)
75
- keep_version_selectors << PactBroker::DB::Clean::Selector.new(released: true)
77
+ selector = PactBroker::DB::Clean::Selector.new(released: true)
78
+ output("Automatically adding #{ selector.to_hash } to keep version selectors")
79
+ keep_version_selectors << selector
76
80
  end
77
81
  end
78
82
  end
@@ -195,7 +195,7 @@
195
195
  .tag-parent{"title": tag.tooltip, "data-toggle": "tooltip", "data-placement": "right"}
196
196
  %a{href: tag.url}
197
197
  .tag.badge.badge-primary
198
- = "tag:" + ellipsisize(tag.name)
198
+ = "tag: " + ellipsisize(tag.name)
199
199
  - line.other_provider_version_tags.each do | tag |
200
200
  .tag-parent{"title": tag.tooltip, "data-toggle": "tooltip", "data-placement": "right"}
201
201
  %a{href: tag.url}