pact_broker 2.27.6 → 2.29.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/.travis.yml +1 -2
  4. data/CHANGELOG.md +38 -0
  5. data/MATRIX.md +4 -0
  6. data/README.md +3 -2
  7. data/Rakefile +1 -2
  8. data/config/database.yml +5 -0
  9. data/lib/pact_broker/api/decorators/matrix_decorator.rb +7 -1
  10. data/lib/pact_broker/api/decorators/reason_decorator.rb +50 -0
  11. data/lib/pact_broker/api/resources/base_resource.rb +1 -1
  12. data/lib/pact_broker/api/resources/error_handler.rb +32 -9
  13. data/lib/pact_broker/app.rb +16 -1
  14. data/lib/pact_broker/domain/webhook_request.rb +1 -1
  15. data/lib/pact_broker/matrix/deployment_status_summary.rb +123 -44
  16. data/lib/pact_broker/matrix/head_row.rb +20 -0
  17. data/lib/pact_broker/matrix/integration.rb +49 -7
  18. data/lib/pact_broker/matrix/query_results.rb +3 -2
  19. data/lib/pact_broker/matrix/query_results_with_deployment_status_summary.rb +2 -2
  20. data/lib/pact_broker/matrix/reason.rb +74 -0
  21. data/lib/pact_broker/matrix/repository.rb +97 -61
  22. data/lib/pact_broker/matrix/resolved_selector.rb +126 -0
  23. data/lib/pact_broker/matrix/row.rb +8 -1
  24. data/lib/pact_broker/matrix/service.rb +2 -16
  25. data/lib/pact_broker/pacts/repository.rb +15 -5
  26. data/lib/pact_broker/repositories/helpers.rb +3 -2
  27. data/lib/pact_broker/ui/views/index/_navbar.haml +14 -0
  28. data/lib/pact_broker/ui/views/index/show-with-tags.haml +1 -12
  29. data/lib/pact_broker/ui/views/index/show.haml +1 -12
  30. data/lib/pact_broker/ui/views/layouts/main.haml +3 -0
  31. data/lib/pact_broker/version.rb +1 -1
  32. data/lib/pact_broker/webhooks/job.rb +11 -5
  33. data/lib/pact_broker/webhooks/service.rb +10 -2
  34. data/lib/pact_broker/webhooks/webhook.rb +4 -0
  35. data/lib/rack/pact_broker/database_transaction.rb +22 -0
  36. data/pact_broker.gemspec +25 -1
  37. data/script/restart.sh +18 -0
  38. data/script/watch.sh +7 -0
  39. data/spec/features/publish_verification_spec.rb +1 -1
  40. data/spec/integration/app_spec.rb +1 -1
  41. data/spec/integration/webhooks/certificate_spec.rb +10 -2
  42. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +2 -1
  43. data/spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb +59 -0
  44. data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +84 -21
  45. data/spec/lib/pact_broker/app_spec.rb +22 -0
  46. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +1 -1
  47. data/spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb +116 -28
  48. data/spec/lib/pact_broker/matrix/head_row_spec.rb +23 -0
  49. data/spec/lib/pact_broker/matrix/integration_spec.rb +242 -0
  50. data/spec/lib/pact_broker/matrix/repository_dependency_spec.rb +58 -0
  51. data/spec/lib/pact_broker/matrix/repository_spec.rb +40 -7
  52. data/spec/lib/pact_broker/matrix/service_spec.rb +0 -50
  53. data/spec/lib/pact_broker/pacts/repository_spec.rb +20 -4
  54. data/spec/lib/pact_broker/webhooks/job_spec.rb +9 -9
  55. data/spec/lib/pact_broker/webhooks/service_spec.rb +3 -3
  56. data/spec/lib/pact_broker/webhooks/webhook_spec.rb +39 -0
  57. data/spec/lib/rack/pact_broker/database_transaction_spec.rb +40 -0
  58. data/spec/service_consumers/pact_helper.rb +2 -0
  59. data/spec/spec_helper.rb +2 -3
  60. data/spec/support/jobs.rb +12 -0
  61. data/spec/support/migration_helpers.rb +1 -1
  62. data/spec/support/simplecov.rb +10 -0
  63. data/tasks/audit.rake +2 -0
  64. data/tasks/pact.rake +5 -1
  65. data/tasks/rspec.rake +14 -0
  66. metadata +50 -5
  67. data/db/pact_broker_database.sqlite3 +0 -0
  68. data/spec/lib/pact_broker/matrix/repository_find_integrations_spec.rb +0 -51
@@ -1,4 +1,5 @@
1
1
  require 'pact_broker/matrix/row'
2
+ require 'pact_broker/webhooks/webhook'
2
3
 
3
4
  module PactBroker
4
5
  module Matrix
@@ -29,6 +30,25 @@ module PactBroker
29
30
  end
30
31
  end
31
32
  end)
33
+
34
+ # When viewing the index, every webhook in the database will match at least one of the rows, so
35
+ # it makes sense to load the entire table and match each webhook to the appropriate row.
36
+ # This will only work when using eager loading. The keys are just blanked out to avoid errors.
37
+ # I don't understand how they work at all.
38
+ # It would be nice to do this declaratively.
39
+ many_to_many :webhooks, :left_key => [], left_primary_key: [], :eager_loader=>(proc do |eo_opts|
40
+ eo_opts[:rows].each do |row|
41
+ row.associations[:webhooks] = []
42
+ end
43
+
44
+ PactBroker::Webhooks::Webhook.each do | webhook |
45
+ eo_opts[:rows].each do | row |
46
+ if webhook.is_for?(row)
47
+ row.associations[:webhooks] << webhook
48
+ end
49
+ end
50
+ end
51
+ end)
32
52
  end
33
53
  end
34
54
  end
@@ -1,17 +1,22 @@
1
- #
2
- # Represents the integration relationship between a consumer and a provider
3
- #
1
+
2
+ # Represents the integration relationship between a consumer and a provider in the context
3
+ # of a matrix or can-i-deploy query.
4
+ # If the required flag is set, then one of the pacticipants (consumers) specified in the HTTP query
5
+ # requires the provider. It would not be required if a provider was specified, and it had an
6
+ # integration with a consumer.
7
+
4
8
  module PactBroker
5
9
  module Matrix
6
10
  class Integration
7
11
 
8
12
  attr_reader :consumer_name, :consumer_id, :provider_name, :provider_id
9
13
 
10
- def initialize consumer_id, consumer_name, provider_id, provider_name
14
+ def initialize consumer_id, consumer_name, provider_id, provider_name, required
11
15
  @consumer_id = consumer_id
12
16
  @consumer_name = consumer_name
13
17
  @provider_id = provider_id
14
18
  @provider_name = provider_name
19
+ @required = required
15
20
  end
16
21
 
17
22
  def self.from_hash hash
@@ -19,10 +24,23 @@ module PactBroker
19
24
  hash.fetch(:consumer_id),
20
25
  hash.fetch(:consumer_name),
21
26
  hash.fetch(:provider_id),
22
- hash.fetch(:provider_name)
27
+ hash.fetch(:provider_name),
28
+ hash.fetch(:required)
23
29
  )
24
30
  end
25
31
 
32
+ def consumer
33
+ @consumer ||= OpenStruct.new(name: consumer_name, id: consumer_id)
34
+ end
35
+
36
+ def provider
37
+ @provider ||= OpenStruct.new(name: provider_name, id: provider_id)
38
+ end
39
+
40
+ def required?
41
+ @required
42
+ end
43
+
26
44
  def == other
27
45
  consumer_id == other.consumer_id && provider_id == other.provider_id
28
46
  end
@@ -30,7 +48,7 @@ module PactBroker
30
48
  def <=> other
31
49
  comparison = consumer_name <=> other.consumer_name
32
50
  return comparison if comparison != 0
33
- provider_name <=> other.provider_name
51
+ comparison =provider_name <=> other.provider_name
34
52
  end
35
53
 
36
54
  def to_hash
@@ -47,7 +65,31 @@ module PactBroker
47
65
  end
48
66
 
49
67
  def to_s
50
- "Relationship between #{consumer_name} (id=#{consumer_id}) and #{provider_name} (id=#{provider_id})"
68
+ "Integration between #{consumer_name} (id=#{consumer_id}) and #{provider_name} (id=#{provider_id})"
69
+ end
70
+
71
+ def involves_consumer_with_id?(consumer_id)
72
+ self.consumer_id == consumer_id
73
+ end
74
+
75
+ def involves_consumer_with_names?(consumer_names)
76
+ consumer_names.include?(self.consumer_name)
77
+ end
78
+
79
+ def involves_provider_with_name?(provider_name)
80
+ self.provider_name == provider_name
81
+ end
82
+
83
+ def involves_consumer_with_name?(consumer_name)
84
+ self.consumer_name == consumer_name
85
+ end
86
+
87
+ def pacticipant_names
88
+ [consumer_name, provider_name]
89
+ end
90
+
91
+ def involves_pacticipant_with_name?(pacticipant_name)
92
+ pacticipant_names.include?(pacticipant_name)
51
93
  end
52
94
  end
53
95
  end
@@ -1,13 +1,14 @@
1
1
  module PactBroker
2
2
  module Matrix
3
3
  class QueryResults < Array
4
- attr_reader :selectors, :options, :resolved_selectors
4
+ attr_reader :selectors, :options, :resolved_selectors, :integrations
5
5
 
6
- def initialize rows, selectors, options, resolved_selectors
6
+ def initialize rows, selectors, options, resolved_selectors, integrations
7
7
  super(rows)
8
8
  @selectors = selectors
9
9
  @resolved_selectors = resolved_selectors
10
10
  @options = options
11
+ @integrations = integrations
11
12
  end
12
13
 
13
14
  def rows
@@ -5,8 +5,8 @@ module PactBroker
5
5
  class QueryResultsWithDeploymentStatusSummary < QueryResults
6
6
  attr_reader :deployment_status_summary
7
7
 
8
- def initialize rows, selectors, options, resolved_selectors, deployment_status_summary
9
- super(rows, selectors, options, resolved_selectors)
8
+ def initialize rows, selectors, options, resolved_selectors, integrations, deployment_status_summary
9
+ super(rows, selectors, options, resolved_selectors, integrations)
10
10
  @deployment_status_summary = deployment_status_summary
11
11
  end
12
12
  end
@@ -0,0 +1,74 @@
1
+ module PactBroker
2
+ module Matrix
3
+ class Reason
4
+ def == other
5
+ self.class == other.class
6
+ end
7
+ end
8
+
9
+ class ErrorReason < Reason; end
10
+
11
+ class ErrorReasonWithTwoSelectors < ErrorReason
12
+ attr_reader :consumer_selector, :provider_selector
13
+
14
+ def initialize(consumer_selector, provider_selector)
15
+ @consumer_selector = consumer_selector
16
+ @provider_selector = provider_selector
17
+ end
18
+
19
+ def == other
20
+ super(other) &&
21
+ consumer_selector == other.consumer_selector &&
22
+ provider_selector == other.provider_selector
23
+ end
24
+
25
+ def to_s
26
+ "#{self.class} consumer_selector=#{consumer_selector}, provider_selector=#{provider_selector}"
27
+ end
28
+ end
29
+
30
+ # The pact for the required consumer version
31
+ # has never been verified by the provider
32
+ # (a row in the matrix with a blank provider version)
33
+ class PactNotEverVerifiedByProvider < ErrorReasonWithTwoSelectors; end
34
+
35
+ # The pact for the required consumer verison
36
+ # has been verified by the provider, but not by
37
+ # the required provider version
38
+ # (this row is not included in the matrix, and it's
39
+ # absence must be inferred)
40
+ class PactNotVerifiedByRequiredProviderVersion < ErrorReasonWithTwoSelectors; end
41
+
42
+ # The pact verification has failed
43
+ class VerificationFailed < ErrorReasonWithTwoSelectors; end
44
+
45
+ class VerificationFailedWithRow < ErrorReasonWithTwoSelectors; end
46
+
47
+ # The specified pacticipant version does not exist
48
+ class SpecifiedVersionDoesNotExist < ErrorReason
49
+ attr_reader :selector
50
+
51
+ def initialize(selector)
52
+ @selector = selector
53
+ end
54
+
55
+ def == other
56
+ super(other) && selector == other.selector
57
+ end
58
+
59
+ def to_s
60
+ "#{self.class} selector=#{selector}"
61
+ end
62
+ end
63
+
64
+ # The pact for the required consumer version has been
65
+ # successfully verified by the required provider version
66
+ class Successful < Reason
67
+ end
68
+
69
+ # There aren't any rows, but there are also no missing
70
+ # provider verifications.
71
+ class NoDependenciesMissing < Reason
72
+ end
73
+ end
74
+ end
@@ -5,6 +5,7 @@ require 'pact_broker/error'
5
5
  require 'pact_broker/matrix/query_results'
6
6
  require 'pact_broker/matrix/integration'
7
7
  require 'pact_broker/matrix/query_results_with_deployment_status_summary'
8
+ require 'pact_broker/matrix/resolved_selector'
8
9
 
9
10
  module PactBroker
10
11
  module Matrix
@@ -48,10 +49,10 @@ module PactBroker
48
49
  end
49
50
 
50
51
  # Return the latest matrix row (pact/verification) for each consumer_version_number/provider_version_number
51
- def find selectors, options = {}
52
- resolved_selectors = resolve_selectors(selectors, options)
52
+ def find specified_selectors, options = {}
53
+ resolved_selectors = resolve_selectors(specified_selectors, options)
53
54
  lines = query_matrix(resolved_selectors, options)
54
- lines = apply_latestby(options, selectors, lines)
55
+ lines = apply_latestby(options, specified_selectors, lines)
55
56
 
56
57
  # This needs to be done after the latestby, so can't be done in the db unless
57
58
  # the latestby logic is moved to the db
@@ -59,7 +60,9 @@ module PactBroker
59
60
  lines = lines.select{ |l| options[:success].include?(l.success) }
60
61
  end
61
62
 
62
- QueryResults.new(lines.sort, selectors, options, resolved_selectors)
63
+ integrations = find_integrations_for_specified_selectors(resolved_selectors.select(&:specified?))
64
+
65
+ QueryResults.new(lines.sort, specified_selectors, options, resolved_selectors, integrations)
63
66
  end
64
67
 
65
68
  def find_for_consumer_and_provider pacticipant_1_name, pacticipant_2_name
@@ -72,18 +75,35 @@ module PactBroker
72
75
  find(selectors, latestby: 'cvpv').select{|line| line.success }
73
76
  end
74
77
 
75
- def find_integrations(pacticipant_names)
76
- selectors = pacticipant_names.collect{ | pacticipant_name | add_ids(pacticipant_name: pacticipant_name) }
78
+ # If one pacticipant is specified, find all the integrations that involve that pacticipant
79
+ # If two or more are specified, just return the integrations that involve the specified pacticipants
80
+ def find_integrations_for_specified_selectors(resolved_specified_selectors)
81
+ specified_pacticipant_names = resolved_specified_selectors.collect(&:pacticipant_name)
77
82
  Row
78
83
  .select(:consumer_name, :consumer_id, :provider_name, :provider_id)
79
- .matching_selectors(selectors)
84
+ .matching_selectors(resolved_specified_selectors)
80
85
  .distinct
81
86
  .all
82
- .collect{ |row | Integration.from_hash(row.to_hash) }.uniq
87
+ .collect do |row |
88
+ row.to_hash
89
+ end
90
+ .uniq
91
+ .collect do | hash |
92
+ required = is_a_row_for_this_integration_required?(specified_pacticipant_names, hash[:consumer_name])
93
+ Integration.from_hash(hash.merge(required: required))
94
+ end
83
95
  end
84
96
 
85
97
  private
86
98
 
99
+ # If one of the specified pacticipants is a consumer, then that provider is required to be deployed
100
+ # to the same environment before the consumer can be deployed.
101
+ # If one of the specified pacticipants is a provider, then the provider may be deployed
102
+ # without the consumer being present.
103
+ def is_a_row_for_this_integration_required?(specified_pacticipant_names, consumer_name)
104
+ specified_pacticipant_names.include?(consumer_name)
105
+ end
106
+
87
107
  def apply_latestby options, selectors, lines
88
108
  return lines unless options[:latestby]
89
109
  group_by_columns = case options[:latestby]
@@ -114,7 +134,7 @@ module PactBroker
114
134
  end
115
135
 
116
136
  def query_matrix selectors, options
117
- query = view_for(options).select_all.matching_selectors(selectors)
137
+ query = Row.select_all.matching_selectors(selectors)
118
138
  query = query.limit(options[:limit]) if options[:limit]
119
139
  query
120
140
  .order_by_names_ascending_most_recent_first
@@ -123,97 +143,113 @@ module PactBroker
123
143
  .all
124
144
  end
125
145
 
126
- def view_for(options)
127
- Row
128
- end
129
-
130
- def resolve_selectors(selectors, options)
131
- resolved_selectors = look_up_version_numbers(selectors, options)
146
+ def resolve_selectors(specified_selectors, options)
147
+ resolved_specified_selectors = resolve_versions_and_add_ids(specified_selectors, :specified)
132
148
  if options[:latest] || options[:tag]
133
- apply_latest_and_tag_to_inferred_selectors(resolved_selectors, options)
149
+ add_inferred_selectors(resolved_specified_selectors, options)
134
150
  else
135
- resolved_selectors
151
+ resolved_specified_selectors
136
152
  end
137
153
  end
138
154
 
139
155
  # Find the version number for selectors with the latest and/or tag specified
140
- def look_up_version_numbers(selectors, options)
156
+ def resolve_versions_and_add_ids(selectors, selector_type)
141
157
  selectors.collect do | selector |
142
- if selector[:tag] && selector[:latest]
143
- version = version_repository.find_by_pacticipant_name_and_latest_tag(selector[:pacticipant_name], selector[:tag])
144
- raise Error.new("No version of #{selector[:pacticipant_name]} found with tag #{selector[:tag]}") unless version
145
- # validation in resource should ensure we always have a version
146
- {
147
- pacticipant_name: selector[:pacticipant_name],
148
- pacticipant_version_number: version.number
149
- }
150
- elsif selector[:latest]
151
- version = version_repository.find_latest_by_pacticpant_name(selector[:pacticipant_name])
152
- raise Error.new("No version of #{selector[:pacticipant_name]} found") unless version
153
- {
154
- pacticipant_name: selector[:pacticipant_name],
155
- pacticipant_version_number: version.number
156
- }
157
- elsif selector[:tag]
158
- # validation in resource should ensure we always have at least one version
159
- versions = version_repository.find_by_pacticipant_name_and_tag(selector[:pacticipant_name], selector[:tag])
160
- raise Error.new("No version of #{selector[:pacticipant_name]} found with tag #{selector[:tag]}") unless versions.any?
161
- versions.collect do | version |
162
- {
163
- pacticipant_name: selector[:pacticipant_name],
164
- pacticipant_version_number: version.number
165
- }
158
+ pacticipant = PactBroker::Domain::Pacticipant.find(name: selector[:pacticipant_name])
159
+ versions = find_versions_for_selector(selector)
160
+ build_selectors_for_pacticipant_and_versions(pacticipant, versions, selector, selector_type)
161
+ end.flatten
162
+ end
163
+
164
+ def build_selectors_for_pacticipant_and_versions(pacticipant, versions, original_selector, selector_type)
165
+ if versions
166
+ versions.collect do | version |
167
+ if version
168
+ selector_for_version(pacticipant, version, original_selector, selector_type)
169
+ else
170
+ selector_for_non_existing_version(pacticipant, original_selector, selector_type)
166
171
  end
167
- else
168
- selector.dup
169
172
  end
170
- end.flatten.compact.collect do | selector |
171
- add_ids(selector)
173
+ else
174
+ selector_without_version(pacticipant, selector_type)
172
175
  end
173
176
  end
174
177
 
175
- def add_ids(selector)
178
+ def find_versions_for_selector(selector)
179
+ if selector[:tag] && selector[:latest]
180
+ version = version_repository.find_by_pacticipant_name_and_latest_tag(selector[:pacticipant_name], selector[:tag])
181
+ [version]
182
+ elsif selector[:latest]
183
+ version = version_repository.find_latest_by_pacticpant_name(selector[:pacticipant_name])
184
+ [version]
185
+ elsif selector[:tag]
186
+ versions = version_repository.find_by_pacticipant_name_and_tag(selector[:pacticipant_name], selector[:tag])
187
+ versions.any? ? versions : [nil]
188
+ elsif selector[:pacticipant_version_number]
189
+ version = version_repository.find_by_pacticipant_name_and_number(selector[:pacticipant_name], selector[:pacticipant_version_number])
190
+ [version]
191
+ else
192
+ nil
193
+ end
194
+ end
195
+
196
+ def add_ids_to_selector(selector)
176
197
  if selector[:pacticipant_name]
177
198
  pacticipant = PactBroker::Domain::Pacticipant.find(name: selector[:pacticipant_name])
178
199
  selector[:pacticipant_id] = pacticipant ? pacticipant.id : nil
179
200
  end
180
201
 
181
- if selector[:pacticipant_name] && selector[:pacticipant_version_number]
202
+ if selector[:pacticipant_name] && selector[:pacticipant_version_number] && !selector[:pacticipant_version_id]
182
203
  version = version_repository.find_by_pacticipant_name_and_number(selector[:pacticipant_name], selector[:pacticipant_version_number])
183
204
  selector[:pacticipant_version_id] = version ? version.id : nil
184
205
  end
185
206
 
186
- if selector[:pacticipant_version_number].nil?
187
- selector[:pacticipant_version_id] = nil
207
+ if !selector.key?(:pacticipant_version_id)
208
+ selector[:pacticipant_version_id] = nil
188
209
  end
189
210
  selector
190
211
  end
191
212
 
192
- # eg. when checking to see if Foo version 2 can be deployed to prod,
193
- # need to look up all the 'partner' pacticipants, and determine their latest prod versions
194
- def apply_latest_and_tag_to_inferred_selectors(selectors, options)
195
- all_pacticipant_names = all_pacticipant_names_in_specified_matrix(selectors)
196
- specified_names = selectors.collect{ |s| s[:pacticipant_name] }
197
- inferred_names = all_pacticipant_names - specified_names
213
+ # When only one selector is specified, (eg. checking to see if Foo version 2 can be deployed to prod),
214
+ # need to look up all integrated pacticipants, and determine their relevant (eg. latest prod) versions
215
+ def add_inferred_selectors(resolved_specified_selectors, options)
216
+ integrations = find_integrations_for_specified_selectors(resolved_specified_selectors)
217
+ all_pacticipant_names = integrations.collect(&:pacticipant_names).flatten.uniq
218
+ specified_names = resolved_specified_selectors.collect{ |s| s[:pacticipant_name] }
219
+ inferred_pacticipant_names = all_pacticipant_names - specified_names
220
+ resolved_specified_selectors + build_inferred_selectors(inferred_pacticipant_names, options)
221
+ end
198
222
 
199
- inferred_selectors = inferred_names.collect do | pacticipant_name |
223
+ def build_inferred_selectors(inferred_pacticipant_names, options)
224
+ selectors = inferred_pacticipant_names.collect do | pacticipant_name |
200
225
  selector = {
201
- pacticipant_name: pacticipant_name,
226
+ pacticipant_name: pacticipant_name
202
227
  }
203
228
  selector[:tag] = options[:tag] if options[:tag]
204
229
  selector[:latest] = options[:latest] if options[:latest]
205
230
  selector
206
231
  end
207
-
208
- selectors + look_up_version_numbers(inferred_selectors, options)
232
+ resolve_versions_and_add_ids(selectors, :inferred)
209
233
  end
210
234
 
211
235
  def all_pacticipant_names_in_specified_matrix(selectors)
212
- find_integrations(selectors.collect{|s| s[:pacticipant_name]})
236
+ find_integrations_for_specified_selectors(selectors)
213
237
  .collect(&:pacticipant_names)
214
238
  .flatten
215
239
  .uniq
216
240
  end
241
+
242
+ def selector_for_non_existing_version(pacticipant, original_selector, selector_type)
243
+ ResolvedSelector.for_pacticipant_and_non_existing_version(pacticipant, original_selector, selector_type)
244
+ end
245
+
246
+ def selector_for_version(pacticipant, version, original_selector, selector_type)
247
+ ResolvedSelector.for_pacticipant_and_version(pacticipant, version, original_selector, selector_type)
248
+ end
249
+
250
+ def selector_without_version(pacticipant, selector_type)
251
+ ResolvedSelector.for_pacticipant(pacticipant, selector_type)
252
+ end
217
253
  end
218
254
  end
219
255
  end