13
13
require 'pact_broker/matrix/head_row'
14
14
require 'pact_broker/pacts/latest_pact_publication_id_for_consumer_version'
15
15
require 'pact_broker/pacts/verifiable_pact'
16
+ require 'pact_broker/repositories/helpers'
16
17
17
18
module PactBroker
18
19
module Pacts
19
20
class Repository
20
21
21
22
include PactBroker ::Logging
22
23
include PactBroker ::Repositories
24
+ include PactBroker ::Repositories ::Helpers
23
25
24
26
def create params
25
27
pact_version = find_or_create_pact_version (
@@ -125,36 +127,60 @@ def find_latest_pact_versions_for_provider provider_name, tag = nil
125
127
end
126
128
end
127
129
130
+ def find_all_pact_versions_for_provider_with_tags provider_name , consumer_version_tag_names
131
+ provider = pacticipant_repository . find_by_name ( provider_name )
132
+
133
+ PactPublication
134
+ . select_all_qualified
135
+ . select_append ( Sequel [ :cv ] [ :order ] . as ( :consumer_version_order ) )
136
+ . remove_overridden_revisions
137
+ . join_consumer_versions ( :cv )
138
+ . join_consumer_version_tags_with_names ( consumer_version_tag_names )
139
+ . where ( provider : provider )
140
+ . eager ( :consumer )
141
+ . eager ( :consumer_version )
142
+ . eager ( :provider )
143
+ . eager ( :pact_version )
144
+ . all
145
+ . group_by ( &:pact_version_id )
146
+ . values
147
+ . collect { | pacts | pacts . sort_by { |pact | pact . values . fetch ( :consumer_version_order ) } . last }
148
+ . collect ( &:to_domain )
149
+ end
150
+
128
151
# To find the work in progress pacts for this verification execution:
129
152
# For each provider tag that will be applied to this verification result (usually there will just be one, but
130
153
# we have to allow for multiple tags),
131
154
# find the head pacts (the pacts that are the latest for their tag) that have been successfully
132
155
# verified against the provider tag.
133
156
# Then, find all the head pacts, and remove the ones that have been successfully verified by ALL
134
- # of the provider tags supplied.
157
+ # of the provider tags supplied, and the ones that were published before the include_wip_pacts_since date .
135
158
# Then, for all of the head pacts that are remaining (these are the WIP ones) work out which
136
159
# provider tags they are pending for.
137
- # Don't include pact publications that were created
160
+ # Don't include pact publications that were created before the provider tag was first used
161
+ # (that is, before the provider's git branch was created).
138
162
def find_wip_pact_versions_for_provider provider_name , provider_tags_names = [ ] , options = { }
163
+ # TODO not sure about this
139
164
return [ ] if provider_tags_names . empty?
140
165
141
166
provider = pacticipant_repository . find_by_name ( provider_name )
142
167
143
- # Hash of provider tag names => list of head pacts
144
- successfully_verified_head_pacts_for_provider_tags = find_successfully_verified_head_pacts_by_provider_tag ( provider_name , provider_tags_names , options )
168
+ # Hash of provider tag name => list of head pacts that have been successfully verified by that tag
169
+ successfully_verified_head_pacts_for_provider_tags = find_successfully_verified_head_pacts_by_provider_tag ( provider . id , provider_tags_names , options )
170
+ # Create hash of provider tag name => list of pact publication ids
145
171
successfully_verified_head_pact_publication_ids_for_each_provider_tag = successfully_verified_head_pacts_for_provider_tags . each_with_object ( { } ) do | ( provider_tag_name , head_pacts ) , hash |
146
- hash [ provider_tag_name ] = head_pacts . collect ( &:id )
172
+ hash [ provider_tag_name ] = head_pacts . collect ( &:id ) . uniq
147
173
end
148
174
149
- # list of pact_publication_ids that are NOT work in progress
150
- head_pact_publication_ids_successully_verified_by_all_provider_tags = successfully_verified_head_pacts_for_provider_tags . values . collect { |head_pacts | head_pacts . collect ( &:id ) } . reduce ( :& )
175
+ # list of head pact_publication_ids that are NOT work in progress because they've been verified by all of the provider version tags supplied
176
+ non_wip_pact_publication_ids = successfully_verified_head_pacts_for_provider_tags . values . collect { |head_pacts | head_pacts . collect ( &:id ) } . reduce ( :& )
151
177
152
- pact_publication_ids = find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags (
153
- provider_name ,
154
- head_pact_publication_ids_successully_verified_by_all_provider_tags ,
178
+ wip_pact_publication_ids = find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags (
179
+ provider . id ,
180
+ non_wip_pact_publication_ids ,
155
181
options )
156
182
157
- pacts = AllPactPublications . where ( id : pact_publication_ids ) . order_ignore_case ( :consumer_name ) . order_append ( :consumer_version_order )
183
+ wip_pacts = AllPactPublications . where ( id : wip_pact_publication_ids ) . order_ignore_case ( :consumer_name ) . order_append ( :consumer_version_order )
158
184
159
185
# The first instance (by date) of each provider tag with that name
160
186
provider_tag_collection = PactBroker ::Domain ::Tag
@@ -166,7 +192,7 @@ def find_wip_pact_versions_for_provider provider_name, provider_tags_names = [],
166
192
. where ( name : provider_tags_names )
167
193
. all
168
194
169
- pacts . collect do | pact |
195
+ wip_pacts . collect do | pact |
170
196
pending_tag_names = find_provider_tags_for_which_pact_publication_id_is_pending ( pact , successfully_verified_head_pact_publication_ids_for_each_provider_tag )
171
197
pre_existing_tag_names = find_provider_tag_names_that_were_first_used_before_pact_published ( pact , provider_tag_collection )
172
198
@@ -313,13 +339,33 @@ def find_previous_pacts pact
313
339
314
340
# Returns a list of Domain::Pact objects the represent pact publications
315
341
def find_for_verification ( provider_name , consumer_version_selectors )
342
+ find_pacts_for_which_the_latest_version_or_latest_version_for_the_tag_is_required ( provider_name , consumer_version_selectors ) +
343
+ find_pacts_for_which_all_versions_for_the_tag_are_required ( provider_name , consumer_version_selectors )
344
+ end
345
+
346
+ private
347
+
348
+ def find_pacts_for_which_the_latest_version_or_latest_version_for_the_tag_is_required ( provider_name , consumer_version_selectors )
349
+ # The tags for which only the latest version is specified
316
350
latest_tags = consumer_version_selectors . any? ?
317
351
consumer_version_selectors . select ( &:latest ) . collect ( &:tag ) :
318
352
nil
353
+
319
354
find_latest_pact_versions_for_provider ( provider_name , latest_tags )
320
355
end
321
356
322
- private
357
+ def find_pacts_for_which_all_versions_for_the_tag_are_required ( provider_name , consumer_version_selectors )
358
+ # The tags for which all versions are specified
359
+ all_tags = consumer_version_selectors . any? ?
360
+ consumer_version_selectors . reject ( &:latest ) . collect ( &:tag ) :
361
+ nil
362
+
363
+ if all_tags
364
+ find_all_pact_versions_for_provider_with_tags ( provider_name , all_tags )
365
+ else
366
+ [ ]
367
+ end
368
+ end
323
369
324
370
def find_previous_distinct_pact_by_sha pact
325
371
current_pact_content_sha =
@@ -389,27 +435,35 @@ def to_datetime string_or_datetime
389
435
end
390
436
end
391
437
392
- def find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags ( provider_name , pact_publication_ids_successfully_verified_by_all_provider_tags , options )
438
+ def find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags ( provider_id , pact_publication_ids_successfully_verified_by_all_provider_tags , options )
393
439
# Exclude the head pacts that have been successfully verified by all the specified provider tags
394
- pact_publication_ids = LatestTaggedPactPublications
395
- . provider ( provider_name )
396
- . exclude ( id : pact_publication_ids_successfully_verified_by_all_provider_tags )
440
+ LatestTaggedPactPublications
441
+ . where ( provider_id : provider_id )
397
442
. where ( Sequel . lit ( 'latest_tagged_pact_publications.created_at > ?' , options . fetch ( :include_wip_pacts_since ) ) )
443
+ . exclude ( id : pact_publication_ids_successfully_verified_by_all_provider_tags )
398
444
. select_for_subquery ( :id )
399
445
end
400
446
401
- # Find the head pacts that have been successfully verified by a provider version with the specified tags
402
- # Returns a Hash of provider_tag => LatestTaggedPactPublications with only id and tag_name populated
403
- def find_successfully_verified_head_pacts_by_provider_tag ( provider_name , provider_tags , options )
447
+ # Find the head pacts that have been successfully verified by a provider version with the specified
448
+ # provider version tags.
449
+ # Returns a Hash of provider_tag => LatestTaggedPactPublications with only pact publication id and tag_name populated
450
+ # This is the list of pacts we are EXCLUDING from the WIP list because they have already been verified successfully
451
+ def find_successfully_verified_head_pacts_by_provider_tag ( provider_id , provider_tags , options )
404
452
provider_tags . compact . each_with_object ( { } ) do | provider_tag , hash |
453
+ verifications_join = {
454
+ pact_version_id : :pact_version_id ,
455
+ Sequel [ :verifications ] [ :success ] => true ,
456
+ Sequel [ :verifications ] [ :provider_id ] => provider_id
457
+ }
458
+ tags_join = {
459
+ Sequel [ :verifications ] [ :provider_version_id ] => Sequel [ :provider_tags ] [ :version_id ] ,
460
+ Sequel [ :provider_tags ] [ :name ] => provider_tag
461
+ }
405
462
head_pacts = LatestTaggedPactPublications
406
- . join ( :verifications , { pact_version_id : :pact_version_id } )
407
- . join ( :tags , { Sequel [ :verifications ] [ :provider_version_id ] => Sequel [ :provider_tags ] [ :version_id ] } , { table_alias : :provider_tags } )
408
- . where ( Sequel [ :provider_tags ] [ :name ] => provider_tag )
409
- . provider ( provider_name )
410
- . where ( Sequel [ :verifications ] [ :success ] => true )
411
- . or ( Sequel . lit ( 'latest_tagged_pact_publications.created_at < ?' , options . fetch ( :include_wip_pacts_since ) ) )
412
- . select ( Sequel [ :latest_tagged_pact_publications ] [ :id ] . as ( :id ) , :tag_name )
463
+ . select ( Sequel [ :latest_tagged_pact_publications ] [ :id ] . as ( :id ) )
464
+ . join ( :verifications , verifications_join )
465
+ . join ( :tags , tags_join , { table_alias : :provider_tags } )
466
+ . where ( Sequel [ :latest_tagged_pact_publications ] [ :provider_id ] => provider_id )
413
467
. all
414
468
hash [ provider_tag ] = head_pacts
415
469
end
0 commit comments