pact_broker 2.47.1 → 2.48.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/Dockerfile +0 -1
- data/README.md +1 -1
- data/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb +11 -0
- data/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb +1 -0
- data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +4 -39
- data/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb +9 -2
- data/lib/pact_broker/api/decorators/version_decorator.rb +1 -1
- data/lib/pact_broker/api/resources/verification.rb +6 -1
- data/lib/pact_broker/pacts/build_verifiable_pact_notices.rb +35 -0
- data/lib/pact_broker/pacts/repository.rb +71 -17
- data/lib/pact_broker/pacts/selected_pact.rb +9 -18
- data/lib/pact_broker/pacts/selector.rb +66 -10
- data/lib/pact_broker/pacts/selectors.rb +44 -0
- data/lib/pact_broker/pacts/service.rb +2 -2
- data/lib/pact_broker/pacts/squash_pacts_for_verification.rb +4 -6
- data/lib/pact_broker/pacts/verifiable_pact.rb +3 -12
- data/lib/pact_broker/pacts/verifiable_pact_messages.rb +63 -11
- data/lib/pact_broker/test/test_data_builder.rb +6 -0
- data/lib/pact_broker/verifications/repository.rb +4 -0
- data/lib/pact_broker/verifications/service.rb +5 -0
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/webhooks/service.rb +4 -0
- data/spec/features/delete_verification_spec.rb +29 -0
- data/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb +29 -0
- data/spec/lib/pact_broker/api/decorators/verifiable_pact_decorator_spec.rb +18 -40
- data/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb +20 -6
- data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +4 -0
- data/spec/lib/pact_broker/api/resources/provider_pacts_for_verification_spec.rb +2 -2
- data/spec/lib/pact_broker/pacts/build_verifiable_pact_notices_spec.rb +76 -0
- data/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb +73 -0
- data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +10 -12
- data/spec/lib/pact_broker/pacts/selector_spec.rb +28 -0
- data/spec/lib/pact_broker/pacts/selectors_spec.rb +30 -0
- data/spec/lib/pact_broker/pacts/service_spec.rb +2 -2
- data/spec/lib/pact_broker/pacts/squash_pacts_for_verification_spec.rb +2 -5
- data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +32 -24
- data/spec/support/verification_job.rb +1 -0
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdda99358c4d4d8ca43f6e53e0e314fd24f475f1ff85fd0511743d8982224bca
|
4
|
+
data.tar.gz: 4f61ab3a051164ac3db85d7eef44fa088053873b2381f4c4104f4822c47bd651
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3d9f86596a6d4aa776c13f28e84af1976485dc9eff3bef98accf6e372d379cb591270354a252c88a6b2c08ac928391e2ddcf8ee19d3db6f9832a667b4a81184
|
7
|
+
data.tar.gz: d4b2273ab789165a3f0ca7ce8f5fdb2220814d222ea172fa02fe77d19ce6e9e251277a6c621483a41b6b9911ab207b6d59861a39d2168ecdf5b0db64d1477d9f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
<a name="v2.48.0"></a>
|
2
|
+
### v2.48.0 (2020-02-07)
|
3
|
+
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* **pacts for verification**
|
8
|
+
* include a short description of the pact's selectors in the response ([41c6d91f](/../../commit/41c6d91f))
|
9
|
+
* update inclusion reason to support fallback tag explanation ([43081170](/../../commit/43081170))
|
10
|
+
* allow a fallback tag to be specified ([113180c1](/../../commit/113180c1))
|
11
|
+
* update the inclusion notice text to handle 'all pacts for tag' ([59ec8c8a](/../../commit/59ec8c8a))
|
12
|
+
|
13
|
+
* support DELETE for verification results ([70392e53](/../../commit/70392e53))
|
14
|
+
|
15
|
+
|
16
|
+
#### Bug Fixes
|
17
|
+
|
18
|
+
* a url typo (#328) ([482264fa](/../../commit/482264fa))
|
19
|
+
* correct URL of tag relation in pacticipant version resource ([ec24e999](/../../commit/ec24e999))
|
20
|
+
|
21
|
+
|
1
22
|
<a name="v2.47.1"></a>
|
2
23
|
### v2.47.1 (2020-02-01)
|
3
24
|
|
data/Dockerfile
CHANGED
data/README.md
CHANGED
@@ -12,7 +12,7 @@ The Pact Broker is an application for sharing for consumer driven contracts and
|
|
12
12
|
<a href="https:/pactflow.io/?utm_source=github&utm_campaign=pact_broker_intro"><img src="docs/images/Pactflow logo - black small.png"></a>
|
13
13
|
<br/>
|
14
14
|
|
15
|
-
You can try out a Pact Broker for free at <a href="https
|
15
|
+
You can try out a Pact Broker for free at <a href="https://pactflow.io/?utm_source=github&utm_campaign=pact_broker_intro"/>pactflow.io</a>. Built by a group of core Pact maintainers, Pactflow is a fork of the OSS Pact Broker with extra goodies like an improved UI, field level verification results and federated login.
|
16
16
|
|
17
17
|
**Why do I need a Pact Broker?**
|
18
18
|
|
@@ -17,8 +17,19 @@ module PactBroker
|
|
17
17
|
optional(:providerVersionTags).maybe(:array?)
|
18
18
|
optional(:consumerVersionSelectors).each do
|
19
19
|
schema do
|
20
|
+
# configure do
|
21
|
+
# def self.messages
|
22
|
+
# super.merge(en: { errors: { fallbackTagMustBeForLatest: 'can only be set if latest=true' }})
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
|
20
26
|
required(:tag).filled(:str?)
|
21
27
|
optional(:latest).filled(included_in?: [true, false])
|
28
|
+
optional(:fallbackTag).filled(:str?)
|
29
|
+
|
30
|
+
# rule(fallbackTagMustBeForLatest: [:fallbackTag, :latest]) do | fallback_tag, latest |
|
31
|
+
# fallback_tag.filled?.then(latest.eql?(true))
|
32
|
+
# end
|
22
33
|
end
|
23
34
|
end
|
24
35
|
optional(:includePendingStatus).filled(included_in?: [true, false])
|
@@ -1,26 +1,15 @@
|
|
1
1
|
require_relative 'base_decorator'
|
2
2
|
require 'pact_broker/api/pact_broker_urls'
|
3
|
-
require '
|
4
|
-
require 'pact_broker/pacts/verifiable_pact_messages'
|
3
|
+
require 'pact_broker/pacts/build_verifiable_pact_notices'
|
5
4
|
|
6
5
|
module PactBroker
|
7
6
|
module Api
|
8
7
|
module Decorators
|
9
8
|
class VerifiablePactDecorator < BaseDecorator
|
10
9
|
|
11
|
-
|
12
|
-
# a nested verification_properties object for Reform
|
13
|
-
class Reshaper < SimpleDelegator
|
14
|
-
def verification_properties
|
15
|
-
__getobj__()
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(verifiable_pact)
|
20
|
-
super(Reshaper.new(verifiable_pact))
|
21
|
-
end
|
10
|
+
property :shortDescription, getter: -> (context) { PactBroker::Pacts::VerifiablePactMessages.new(context[:represented], nil).pact_version_short_description }
|
22
11
|
|
23
|
-
|
12
|
+
nested :verificationProperties do
|
24
13
|
include PactBroker::Api::PactBrokerUrls
|
25
14
|
|
26
15
|
property :pending,
|
@@ -31,32 +20,8 @@ module PactBroker
|
|
31
20
|
property :noteToDevelopers, getter: -> (_) { "Please print out the text from the 'notices' rather than using the inclusionReason and the pendingReason fields. These will be removed when this API moves out of beta."}
|
32
21
|
|
33
22
|
def notices(user_options)
|
34
|
-
# TODO move this out of the decorator
|
35
23
|
pact_url = pact_version_url(represented, user_options[:base_url])
|
36
|
-
|
37
|
-
|
38
|
-
the_notices = [{
|
39
|
-
when: 'before_verification',
|
40
|
-
text: messages.inclusion_reason
|
41
|
-
}]
|
42
|
-
|
43
|
-
if user_options[:include_pending_status]
|
44
|
-
append_notice(the_notices, 'before_verification', messages.pending_reason)
|
45
|
-
append_notice(the_notices, 'after_verification:success_true_published_false', messages.verification_success_true_published_false)
|
46
|
-
append_notice(the_notices, 'after_verification:success_false_published_false', messages.verification_success_false_published_false)
|
47
|
-
append_notice(the_notices, 'after_verification:success_true_published_true', messages.verification_success_true_published_true)
|
48
|
-
append_notice(the_notices, 'after_verification:success_false_published_true', messages.verification_success_false_published_true)
|
49
|
-
end
|
50
|
-
the_notices
|
51
|
-
end
|
52
|
-
|
53
|
-
def append_notice the_notices, the_when, text
|
54
|
-
if text
|
55
|
-
the_notices << {
|
56
|
-
when: the_when,
|
57
|
-
text: text
|
58
|
-
}
|
59
|
-
end
|
24
|
+
PactBroker::Pacts::BuildVerifiablePactNotices.call(represented, pact_url, include_pending_status: user_options[:include_pending_status])
|
60
25
|
end
|
61
26
|
end
|
62
27
|
|
@@ -2,6 +2,8 @@ require_relative 'base_decorator'
|
|
2
2
|
require_relative 'verifiable_pact_decorator'
|
3
3
|
require 'pact_broker/api/pact_broker_urls'
|
4
4
|
require 'pact_broker/hash_refinements'
|
5
|
+
require 'pact_broker/pacts/selector'
|
6
|
+
require 'pact_broker/pacts/selectors'
|
5
7
|
|
6
8
|
module PactBroker
|
7
9
|
module Api
|
@@ -11,12 +13,13 @@ module PactBroker
|
|
11
13
|
|
12
14
|
collection :provider_version_tags, default: []
|
13
15
|
|
14
|
-
collection :consumer_version_selectors, default:
|
16
|
+
collection :consumer_version_selectors, default: PactBroker::Pacts::Selectors.new, class: PactBroker::Pacts::Selector do
|
15
17
|
property :tag
|
16
18
|
property :latest,
|
17
19
|
setter: ->(fragment:, represented:, **) {
|
18
20
|
represented.latest = (fragment == 'true' || fragment == true)
|
19
21
|
}
|
22
|
+
property :fallback_tag
|
20
23
|
end
|
21
24
|
|
22
25
|
property :include_pending_status, default: false,
|
@@ -31,7 +34,11 @@ module PactBroker
|
|
31
34
|
|
32
35
|
def from_hash(hash)
|
33
36
|
# This handles both the snakecase keys from the GET query and the camelcase JSON POST body
|
34
|
-
super(hash&.snakecase_keys)
|
37
|
+
result = super(hash&.snakecase_keys)
|
38
|
+
if result.consumer_version_selectors && !result.consumer_version_selectors.is_a?(PactBroker::Pacts::Selectors)
|
39
|
+
result.consumer_version_selectors = PactBroker::Pacts::Selectors.new(result.consumer_version_selectors)
|
40
|
+
end
|
41
|
+
result
|
35
42
|
end
|
36
43
|
end
|
37
44
|
end
|
@@ -28,7 +28,7 @@ module PactBroker
|
|
28
28
|
|
29
29
|
link :'pb:tag' do | options |
|
30
30
|
{
|
31
|
-
href:
|
31
|
+
href: version_url(options.fetch(:base_url), represented) + '/tags/{tag}',
|
32
32
|
title: "Get, create or delete a tag for this pacticipant version",
|
33
33
|
templated: true
|
34
34
|
}
|
@@ -20,7 +20,7 @@ module PactBroker
|
|
20
20
|
# Remember to update latest_verification_id_for_pact_version_and_provider_version
|
21
21
|
# if/when DELETE is implemented
|
22
22
|
def allowed_methods
|
23
|
-
["GET", "OPTIONS"]
|
23
|
+
["GET", "OPTIONS", "DELETE"]
|
24
24
|
end
|
25
25
|
|
26
26
|
def resource_exists?
|
@@ -40,6 +40,11 @@ module PactBroker
|
|
40
40
|
extended_decorator_for(verification).to_json(user_options: { base_url: base_url })
|
41
41
|
end
|
42
42
|
|
43
|
+
def delete_resource
|
44
|
+
verification_service.delete(verification)
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
43
48
|
private
|
44
49
|
|
45
50
|
def verification
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pact_broker/pacts/verifiable_pact_messages'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Pacts
|
5
|
+
class BuildVerifiablePactNotices
|
6
|
+
|
7
|
+
def self.call(verifiable_pact, pact_url, options)
|
8
|
+
messages = VerifiablePactMessages.new(verifiable_pact, pact_url)
|
9
|
+
|
10
|
+
notices = [{
|
11
|
+
when: 'before_verification',
|
12
|
+
text: messages.inclusion_reason
|
13
|
+
}]
|
14
|
+
|
15
|
+
if options[:include_pending_status]
|
16
|
+
append_notice(notices, 'before_verification', messages.pending_reason)
|
17
|
+
append_notice(notices, 'after_verification:success_true_published_false', messages.verification_success_true_published_false)
|
18
|
+
append_notice(notices, 'after_verification:success_false_published_false', messages.verification_success_false_published_false)
|
19
|
+
append_notice(notices, 'after_verification:success_true_published_true', messages.verification_success_true_published_true)
|
20
|
+
append_notice(notices, 'after_verification:success_false_published_true', messages.verification_success_false_published_true)
|
21
|
+
end
|
22
|
+
notices
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.append_notice notices, the_when, text
|
26
|
+
if text
|
27
|
+
notices << {
|
28
|
+
when: the_when,
|
29
|
+
text: text
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -16,6 +16,7 @@ require 'pact_broker/pacts/verifiable_pact'
|
|
16
16
|
require 'pact_broker/repositories/helpers'
|
17
17
|
require 'pact_broker/pacts/selected_pact'
|
18
18
|
require 'pact_broker/pacts/selector'
|
19
|
+
require 'pact_broker/pacts/selectors'
|
19
20
|
|
20
21
|
module PactBroker
|
21
22
|
module Pacts
|
@@ -150,7 +151,7 @@ module PactBroker
|
|
150
151
|
.collect do | pact_publications |
|
151
152
|
selector_tag_names = pact_publications.collect{ | p| p.values.fetch(:consumer_version_tag_name) }
|
152
153
|
latest_pact_publication = pact_publications.sort_by{ |p| p.values.fetch(:consumer_version_order) }.last
|
153
|
-
selectors =
|
154
|
+
selectors = Selectors.create_for_all_of_each_tag(selector_tag_names)
|
154
155
|
SelectedPact.new(latest_pact_publication.to_domain, selectors)
|
155
156
|
end
|
156
157
|
end
|
@@ -206,7 +207,8 @@ module PactBroker
|
|
206
207
|
pre_existing_pending_tags = pending_tag_names & pre_existing_tag_names
|
207
208
|
|
208
209
|
if pre_existing_pending_tags.any?
|
209
|
-
|
210
|
+
selectors = Selectors.create_for_latest_of_each_tag(pact.head_tag_names)
|
211
|
+
VerifiablePact.new(pact.to_domain, selectors, true, pre_existing_pending_tags, [], true)
|
210
212
|
end
|
211
213
|
end.compact
|
212
214
|
end
|
@@ -349,16 +351,36 @@ module PactBroker
|
|
349
351
|
selected_pacts = find_pacts_for_which_the_latest_version_is_required(provider_name, consumer_version_selectors) +
|
350
352
|
find_pacts_for_which_the_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors) +
|
351
353
|
find_pacts_for_which_all_versions_for_the_tag_are_required(provider_name, consumer_version_selectors)
|
354
|
+
|
355
|
+
selected_pacts = selected_pacts + find_pacts_for_fallback_tags(selected_pacts, provider_name, consumer_version_selectors)
|
356
|
+
|
352
357
|
selected_pacts
|
353
358
|
.group_by(&:pact_version_sha)
|
354
359
|
.values
|
355
360
|
.collect do | selected_pacts_for_pact_version_id |
|
356
361
|
SelectedPact.merge(selected_pacts_for_pact_version_id)
|
357
362
|
end
|
363
|
+
|
358
364
|
end
|
359
365
|
|
360
366
|
private
|
361
367
|
|
368
|
+
def find_pacts_for_fallback_tags(selected_pacts, provider_name, consumer_version_selectors)
|
369
|
+
# TODO at the moment, the validation doesn't stop fallback being used with 'all' selectors
|
370
|
+
selectors_with_fallback_tags = consumer_version_selectors.select(&:fallback_tag?)
|
371
|
+
selectors_missing_a_pact = selectors_with_fallback_tags.reject do | selector |
|
372
|
+
selected_pacts.any? do | selected_pact |
|
373
|
+
selected_pact.latest_for_tag?(selector.tag)
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
if selectors_missing_a_pact.any?
|
378
|
+
find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(provider_name, selectors_missing_a_pact)
|
379
|
+
else
|
380
|
+
[]
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
362
384
|
def find_pacts_for_which_the_latest_version_is_required(provider_name, consumer_version_selectors)
|
363
385
|
if consumer_version_selectors.empty?
|
364
386
|
LatestPactPublications
|
@@ -366,7 +388,7 @@ module PactBroker
|
|
366
388
|
.order_ignore_case(:consumer_name)
|
367
389
|
.collect do | latest_pact_publication |
|
368
390
|
pact_publication = PactPublication.find(id: latest_pact_publication.id)
|
369
|
-
SelectedPact.new(pact_publication.to_domain,
|
391
|
+
SelectedPact.new(pact_publication.to_domain, Selectors.create_for_overall_latest)
|
370
392
|
end
|
371
393
|
else
|
372
394
|
[]
|
@@ -375,38 +397,70 @@ module PactBroker
|
|
375
397
|
|
376
398
|
def find_pacts_for_which_the_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors)
|
377
399
|
# The tags for which only the latest version is specified
|
378
|
-
|
400
|
+
tag_names = consumer_version_selectors.tag_names_of_selectors_for_latest_pacts
|
379
401
|
|
380
402
|
# TODO make this an efficient query!
|
381
403
|
# These are not yet de-duped. Should make the behaviour consistent between this and find_pacts_for_which_all_versions_for_the_tag_are_required ?
|
382
|
-
if
|
404
|
+
if tag_names.any?
|
383
405
|
LatestTaggedPactPublications
|
384
406
|
.provider(provider_name)
|
385
|
-
.
|
386
|
-
.where(tag_name: latest_tags)
|
407
|
+
.where(tag_name: tag_names)
|
387
408
|
.all
|
388
409
|
.group_by(&:pact_version_id)
|
389
410
|
.values
|
390
411
|
.collect do | pact_publications |
|
391
|
-
|
392
|
-
last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
|
393
|
-
pact_publication = PactPublication.find(id: last_pact_publication.id)
|
394
|
-
SelectedPact.new(
|
395
|
-
pact_publication.to_domain,
|
396
|
-
selector_tag_names.collect{ | tag_name| Selector.latest_for_tag(tag_name) }
|
397
|
-
)
|
412
|
+
create_selected_pact(pact_publications)
|
398
413
|
end
|
399
414
|
else
|
400
415
|
[]
|
401
416
|
end
|
402
417
|
end
|
403
418
|
|
419
|
+
def create_selected_pact(pact_publications)
|
420
|
+
selector_tag_names = pact_publications.collect(&:tag_name)
|
421
|
+
selectors = Selectors.create_for_latest_of_each_tag(selector_tag_names)
|
422
|
+
last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
|
423
|
+
pact_publication = PactPublication.find(id: last_pact_publication.id)
|
424
|
+
SelectedPact.new(
|
425
|
+
pact_publication.to_domain,
|
426
|
+
selectors
|
427
|
+
)
|
428
|
+
end
|
429
|
+
|
430
|
+
def create_fallback_selected_pact(pact_publications, consumer_version_selectors)
|
431
|
+
selector_tag_names = pact_publications.collect(&:tag_name)
|
432
|
+
selectors = Selectors.create_for_latest_fallback_of_each_tag(selector_tag_names)
|
433
|
+
last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
|
434
|
+
pact_publication = PactPublication.find(id: last_pact_publication.id)
|
435
|
+
SelectedPact.new(
|
436
|
+
pact_publication.to_domain,
|
437
|
+
selectors
|
438
|
+
)
|
439
|
+
end
|
440
|
+
|
441
|
+
def find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(provider_name, selectors)
|
442
|
+
selectors.collect do | selector |
|
443
|
+
LatestTaggedPactPublications
|
444
|
+
.provider(provider_name)
|
445
|
+
.where(tag_name: selector.fallback_tag)
|
446
|
+
.all
|
447
|
+
.collect do | latest_tagged_pact_publication |
|
448
|
+
pact_publication = PactPublication.find(id: latest_tagged_pact_publication.id)
|
449
|
+
SelectedPact.new(
|
450
|
+
pact_publication.to_domain,
|
451
|
+
Selectors.new(selector)
|
452
|
+
)
|
453
|
+
end
|
454
|
+
end.flatten
|
455
|
+
end
|
456
|
+
|
457
|
+
|
404
458
|
def find_pacts_for_which_all_versions_for_the_tag_are_required(provider_name, consumer_version_selectors)
|
405
459
|
# The tags for which all versions are specified
|
406
|
-
|
460
|
+
tag_names = consumer_version_selectors.tag_names_of_selectors_for_all_pacts
|
407
461
|
|
408
|
-
if
|
409
|
-
find_all_pact_versions_for_provider_with_consumer_version_tags(provider_name,
|
462
|
+
if tag_names.any?
|
463
|
+
find_all_pact_versions_for_provider_with_consumer_version_tags(provider_name, tag_names)
|
410
464
|
else
|
411
465
|
[]
|
412
466
|
end
|
@@ -11,31 +11,22 @@ module PactBroker
|
|
11
11
|
@selectors = selectors
|
12
12
|
end
|
13
13
|
|
14
|
-
# might actually be, but this code doesn't know it.
|
15
|
-
def overall_latest?
|
16
|
-
selectors.any?(&:overall_latest?)
|
17
|
-
end
|
18
|
-
|
19
|
-
def latest_for_tag?
|
20
|
-
selectors.any?(&:latest_for_tag?)
|
21
|
-
end
|
22
|
-
|
23
14
|
def self.merge(selected_pacts)
|
24
15
|
latest_selected_pact = selected_pacts.sort_by(&:consumer_version_order).last
|
25
|
-
selectors = selected_pacts.collect(&:selectors).
|
16
|
+
selectors = selected_pacts.collect(&:selectors).reduce(&:+)
|
26
17
|
SelectedPact.new(latest_selected_pact.pact, selectors)
|
27
18
|
end
|
28
19
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
20
|
+
def tag_names_of_selectors_for_latest_pacts
|
21
|
+
selectors.tag_names_of_selectors_for_latest_pacts
|
22
|
+
end
|
23
|
+
|
24
|
+
def overall_latest?
|
25
|
+
selectors.overall_latest?
|
35
26
|
end
|
36
27
|
|
37
|
-
def
|
38
|
-
selectors.
|
28
|
+
def latest_for_tag? potential_tag = nil
|
29
|
+
selectors.latest_for_tag?(potential_tag)
|
39
30
|
end
|
40
31
|
|
41
32
|
def consumer_version_order
|