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,18 +49,18 @@ def find_ids_for_pacticipant_names params
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
58
59
if options . key? ( :success )
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
+ QueryResults . new ( lines . sort , specified_selectors , options , resolved_selectors )
63
64
end
64
65
65
66
def find_for_consumer_and_provider pacticipant_1_name , pacticipant_2_name
@@ -73,13 +74,19 @@ def find_compatible_pacticipant_versions selectors
73
74
end
74
75
75
76
def find_integrations ( pacticipant_names )
76
- selectors = pacticipant_names . collect { | pacticipant_name | add_ids ( pacticipant_name : pacticipant_name ) }
77
+ selectors = pacticipant_names . collect { | pacticipant_name | add_ids_to_selector ( pacticipant_name : pacticipant_name ) }
77
78
Row
78
79
. select ( :consumer_name , :consumer_id , :provider_name , :provider_id )
79
80
. matching_selectors ( selectors )
80
81
. distinct
81
82
. all
82
- . collect { |row | Integration . from_hash ( row . to_hash ) } . uniq
83
+ . collect do |row |
84
+ row . to_hash
85
+ end
86
+ . uniq
87
+ . collect do | hash |
88
+ Integration . from_hash ( hash . merge ( required : pacticipant_names . include? ( hash [ :consumer_name ] ) ) )
89
+ end
83
90
end
84
91
85
92
private
@@ -127,85 +134,102 @@ def view_for(options)
127
134
Row
128
135
end
129
136
130
- def resolve_selectors ( selectors , options )
131
- resolved_selectors = look_up_version_numbers ( selectors , options )
137
+ def resolve_selectors ( specified_selectors , options )
138
+ resolved_specified_selectors = resolve_versions_and_add_ids ( specified_selectors , options )
132
139
if options [ :latest ] || options [ :tag ]
133
- apply_latest_and_tag_to_inferred_selectors ( resolved_selectors , options )
140
+ add_inferred_selectors ( resolved_specified_selectors , options )
134
141
else
135
- resolved_selectors
142
+ resolved_specified_selectors
136
143
end
137
144
end
138
145
139
146
# Find the version number for selectors with the latest and/or tag specified
140
- def look_up_version_numbers ( selectors , options )
147
+ def resolve_versions_and_add_ids ( selectors , options , required = true )
141
148
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?
149
+ pacticipant = PactBroker ::Domain ::Pacticipant . find ( name : selector [ :pacticipant_name ] )
150
+
151
+ versions = find_versions_for_selector ( selector , required )
152
+
153
+ if versions
161
154
versions . collect do | version |
162
- {
163
- pacticipant_name : selector [ :pacticipant_name ] ,
164
- pacticipant_version_number : version . number
165
- }
155
+ if version
156
+ selector_for_version ( pacticipant , version )
157
+ else
158
+ selector_for_non_existing_version ( pacticipant )
159
+ end
166
160
end
167
161
else
168
- selector . dup
162
+ selector_without_version ( pacticipant )
169
163
end
170
- end . flatten . compact . collect do | selector |
171
- add_ids ( selector )
164
+ end . flatten
165
+ end
166
+
167
+ def find_versions_for_selector ( selector , required )
168
+ if selector [ :tag ] && selector [ :latest ]
169
+ version = version_repository . find_by_pacticipant_name_and_latest_tag ( selector [ :pacticipant_name ] , selector [ :tag ] )
170
+ # raise Error.new("No version of #{selector[:pacticipant_name]} found with tag #{selector[:tag]}") if required && !version
171
+ [ version ]
172
+ elsif selector [ :latest ]
173
+ version = version_repository . find_latest_by_pacticpant_name ( selector [ :pacticipant_name ] )
174
+ # raise Error.new("No version of #{selector[:pacticipant_name]} found") if required && !version
175
+ [ version ]
176
+ elsif selector [ :tag ]
177
+ versions = version_repository . find_by_pacticipant_name_and_tag ( selector [ :pacticipant_name ] , selector [ :tag ] )
178
+ # raise Error.new("No version of #{selector[:pacticipant_name]} found with tag #{selector[:tag]}") if required && versions.empty?
179
+ versions . any? ? versions : [ nil ]
180
+ elsif selector [ :pacticipant_version_number ]
181
+ version = version_repository . find_by_pacticipant_name_and_number ( selector [ :pacticipant_name ] , selector [ :pacticipant_version_number ] )
182
+ # raise Error.new("No version #{selector[:pacticipant_version_number]} of #{selector[:pacticipant_name]} found") if required && !version
183
+ [ version ]
184
+ else
185
+ nil
172
186
end
173
187
end
174
188
175
- def add_ids ( selector )
189
+ def add_ids_to_selector ( selector )
176
190
if selector [ :pacticipant_name ]
177
191
pacticipant = PactBroker ::Domain ::Pacticipant . find ( name : selector [ :pacticipant_name ] )
178
192
selector [ :pacticipant_id ] = pacticipant ? pacticipant . id : nil
179
193
end
180
194
181
- if selector [ :pacticipant_name ] && selector [ :pacticipant_version_number ]
195
+ if selector [ :pacticipant_name ] && selector [ :pacticipant_version_number ] && ! selector [ :pacticipant_version_id ]
182
196
version = version_repository . find_by_pacticipant_name_and_number ( selector [ :pacticipant_name ] , selector [ :pacticipant_version_number ] )
183
197
selector [ :pacticipant_version_id ] = version ? version . id : nil
184
198
end
185
199
186
- if selector [ :pacticipant_version_number ] . nil?
187
- selector [ :pacticipant_version_id ] = nil
200
+ if ! selector . key? ( :pacticipant_version_id )
201
+ selector [ :pacticipant_version_id ] = nil
188
202
end
189
203
selector
190
204
end
191
205
192
206
# eg. when checking to see if Foo version 2 can be deployed to prod,
193
207
# 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
208
+ def add_inferred_selectors ( resolved_specified_selectors , options )
209
+ integrations = find_integrations ( resolved_specified_selectors . collect { |s | s [ :pacticipant_name ] } )
210
+ all_pacticipant_names = integrations . collect ( &:pacticipant_names ) . flatten . uniq
211
+ specified_names = resolved_specified_selectors . collect { |s | s [ :pacticipant_name ] }
212
+ inferred_pacticipant_names = all_pacticipant_names - specified_names
213
+ # Inferred providers are required for a consumer to be deployed
214
+ required_inferred_pacticipant_names = inferred_pacticipant_names . select { | n | integrations . any? { |i | i . involves_provider_with_name? ( n ) } }
215
+ # Inferred consumers are NOT required for a provider to be deployed
216
+ optional_inferred_pacticipant_names = inferred_pacticipant_names - required_inferred_pacticipant_names
217
+
218
+ resolved_specified_selectors +
219
+ build_inferred_selectors ( required_inferred_pacticipant_names , options , true ) +
220
+ build_inferred_selectors ( optional_inferred_pacticipant_names , options , false )
221
+ end
198
222
199
- inferred_selectors = inferred_names . collect do | pacticipant_name |
223
+ def build_inferred_selectors ( inferred_pacticipant_names , options , required )
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 , options , required )
209
233
end
210
234
211
235
def all_pacticipant_names_in_specified_matrix ( selectors )
@@ -214,6 +238,18 @@ def all_pacticipant_names_in_specified_matrix(selectors)
214
238
. flatten
215
239
. uniq
216
240
end
241
+
242
+ def selector_for_non_existing_version ( pacticipant )
243
+ ResolvedSelector . for_pacticipant_and_non_existing_version ( pacticipant )
244
+ end
245
+
246
+ def selector_for_version ( pacticipant , version )
247
+ ResolvedSelector . for_pacticipant_and_version ( pacticipant , version )
248
+ end
249
+
250
+ def selector_without_version ( pacticipant )
251
+ ResolvedSelector . for_pacticipant ( pacticipant )
252
+ end
217
253
end
218
254
end
219
255
end
0 commit comments