gapic-generator 0.45.2 → 0.45.3
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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 271aec2d05b52adb5498c05c65461142789397a22d3b9a99d1d09f1559e8cf4f
|
4
|
+
data.tar.gz: 16e8bbbf90f2c0eb2174939cc7972fa37552cb807cfd24ecc0d74c9ed252a642
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e46aeb79a605c9395704b0cc14d4b8b540c34c119c9ee7d33178fc8d1a384d91fecfc42e92311e7197e36f9cec7cf21cb85e3a29850256643d348eae6571e8d2
|
7
|
+
data.tar.gz: 9f953a7d82a33f19a6309b6ca6abdf5da4b0f5bec294f6f1da8b0aadec47466f335a4df091c8021dd87a9596b0a310bdfa006fd617f03af8e167067a76712d47
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Release History for gapic-generator
|
2
2
|
|
3
|
+
### 0.45.3 / 2025-06-21
|
4
|
+
|
5
|
+
* Fix: correct pagination heuristic for Compute
|
6
|
+
* Fix: add libyaml to checks and configure for the prebuilt binary
|
7
|
+
* Fix: update Ruby prebuilt binary (version 3.4.3)
|
8
|
+
|
3
9
|
### 0.45.2 / 2025-06-04
|
4
10
|
|
5
11
|
* Fix: update Ruby prebuilt binary, version 3.4.3
|
@@ -160,7 +160,7 @@ module Gapic
|
|
160
160
|
selector = setting[SELECTOR]
|
161
161
|
methods = service_config.apis.filter_map do |api|
|
162
162
|
# Removes API prefix and trailing period.
|
163
|
-
selector[api.name.length + 1..].downcase if selector.start_with? api.name
|
163
|
+
selector[(api.name.length + 1)..].downcase if selector.start_with? api.name
|
164
164
|
end
|
165
165
|
if !methods.nil? && setting.key?(AUTO_POPULATED_FIELDS)
|
166
166
|
@auto_populated_fields_by_method_name[methods.first] = setting[AUTO_POPULATED_FIELDS]
|
@@ -14,20 +14,80 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require "gapic/model/model_error"
|
18
|
+
|
17
19
|
module Gapic
|
18
20
|
module Presenters
|
19
21
|
module Method
|
20
22
|
##
|
21
|
-
#
|
23
|
+
# Compute-specific pagination info determined from the proto method
|
24
|
+
#
|
25
|
+
# This implements the Compute-specific pagination heuristic
|
26
|
+
#
|
27
|
+
# The following steps are followed for this heuristic:
|
28
|
+
# 1. The method should not be server-streamed
|
29
|
+
# 2. The request should have a page token and page size fields
|
30
|
+
# 3. The response should have a next page token and contain a valid results field
|
31
|
+
#
|
32
|
+
# Now determining the valid results field is its own complicated sub-heuristic that should be run last.
|
33
|
+
# This sub-heuristic cannot end in "not paginated". It should either determine the results field or throw an error
|
34
|
+
#
|
35
|
+
# The following steps are followed for this sub-heuristic:
|
36
|
+
# 0. Check the exception dictionary. If the method is there as a key, use the value as the results field.
|
37
|
+
# 1. If there is exactly one map field, that field is the results field.
|
38
|
+
#
|
39
|
+
# NB: at this point the response contains either 0 or 2+ map fields
|
40
|
+
#
|
41
|
+
# 2. If there are no repeated fields there is no results field and we shall throw an error
|
42
|
+
# 3. If there is exactly one repeated field, that field is the results field.
|
43
|
+
# 4. If there are exactly 2 repeated fields, one is of message type, and the other is of type
|
44
|
+
# "String", the field of message type is the results field.
|
45
|
+
#
|
46
|
+
# At this point there are either 2 repeated fields in wrong configuration, or 3 or more repeated
|
47
|
+
# fields. The method should have been in the exception dictionary (see step 0).
|
48
|
+
# Since the method is NOT in the exception dictionary we should throw an error to prevent
|
49
|
+
# accidentally releasing a Compute library with incorrect pagination.
|
22
50
|
#
|
23
51
|
class ComputePaginationInfo
|
24
52
|
include Gapic::Helpers::NamespaceHelper
|
53
|
+
|
54
|
+
# @private Field name for Pagination Request page token
|
55
|
+
PAGE_TOKEN_NAME = "page_token"
|
56
|
+
private_constant :PAGE_TOKEN_NAME
|
57
|
+
# @private Field type for Pagination Request page token
|
58
|
+
PAGE_TOKEN_TYPE = :TYPE_STRING
|
59
|
+
private_constant :PAGE_TOKEN_TYPE
|
60
|
+
|
61
|
+
# @private Field names for Pagination Request page size
|
62
|
+
PAGE_SIZE_NAMES = ["page_size", "max_results"].freeze
|
63
|
+
private_constant :PAGE_SIZE_NAMES
|
64
|
+
# @private Field types for Pagination Request page size
|
65
|
+
PAGE_SIZE_TYPES = [:TYPE_UINT32, :TYPE_INT32].freeze
|
66
|
+
private_constant :PAGE_SIZE_TYPES
|
67
|
+
|
68
|
+
# @private Field name for Pagination Response next page token
|
69
|
+
NEXT_PAGE_TOKEN_NAME = "next_page_token"
|
70
|
+
private_constant :NEXT_PAGE_TOKEN_NAME
|
71
|
+
# @private Field type for Pagination Response next page token
|
72
|
+
NEXT_PAGE_TOKEN_TYPE = :TYPE_STRING
|
73
|
+
private_constant :NEXT_PAGE_TOKEN_TYPE
|
74
|
+
|
75
|
+
# @private A dictionary of special response messages of paginated methods and their repeated fields
|
76
|
+
# Curently contains only UsableSubnetworksAggregatedList which is a paginated field with 3 repeated fields,
|
77
|
+
# 2 of which are message-typed fields
|
78
|
+
REPEATED_FIELD_SPECIAL_DICTIONARY = {
|
79
|
+
"google.cloud.compute.v1.UsableSubnetworksAggregatedList" => "items",
|
80
|
+
"google.cloud.compute.v1beta.UsableSubnetworksAggregatedList" => "items"
|
81
|
+
}.freeze
|
82
|
+
private_constant :REPEATED_FIELD_SPECIAL_DICTIONARY
|
83
|
+
|
25
84
|
##
|
26
85
|
# @param proto_method [Gapic::Schema::Method] the method to derive pagination info from
|
27
86
|
# @param api [Gapic::Schema::Api]
|
28
87
|
#
|
29
88
|
def initialize proto_method, api
|
30
89
|
@api = api
|
90
|
+
@method_full_name = proto_method.full_name
|
31
91
|
@request = proto_method.input
|
32
92
|
@response = proto_method.output
|
33
93
|
@server_streaming = proto_method.server_streaming
|
@@ -38,7 +98,10 @@ module Gapic
|
|
38
98
|
#
|
39
99
|
# @return [Boolean]
|
40
100
|
def paged?
|
41
|
-
!server_streaming? && paged_request? &&
|
101
|
+
paged_candidate = !server_streaming? && paged_request? && paged_response_candidate?
|
102
|
+
|
103
|
+
# `paged_response?` can raise and should be evaluated last
|
104
|
+
paged_candidate && paged_response?
|
42
105
|
end
|
43
106
|
|
44
107
|
##
|
@@ -111,7 +174,7 @@ module Gapic
|
|
111
174
|
def request_page_token_field
|
112
175
|
# Has a String page_token field which specifies the actual (next) page to retrieve.
|
113
176
|
@request_page_token_field ||= @request.fields.find do |f|
|
114
|
-
f.name ==
|
177
|
+
f.name == PAGE_TOKEN_NAME && f.type == PAGE_TOKEN_TYPE
|
115
178
|
end
|
116
179
|
end
|
117
180
|
|
@@ -123,14 +186,8 @@ module Gapic
|
|
123
186
|
def request_page_size_field
|
124
187
|
@request_page_size_field ||=
|
125
188
|
begin
|
126
|
-
page_size_names = ["page_size", "max_results"]
|
127
|
-
|
128
|
-
# Has the int32 page_size or int32 max_results field
|
129
|
-
# which defines the maximum number of paginated resources to return in the response.
|
130
|
-
page_size_types = [:TYPE_UINT32, :TYPE_INT32]
|
131
|
-
|
132
189
|
field = @request.fields.find do |f|
|
133
|
-
|
190
|
+
PAGE_SIZE_NAMES.include?(f.name) && PAGE_SIZE_TYPES.include?(f.type)
|
134
191
|
end
|
135
192
|
|
136
193
|
field
|
@@ -143,9 +200,23 @@ module Gapic
|
|
143
200
|
#
|
144
201
|
# @return [Boolean]
|
145
202
|
def paged_response?
|
146
|
-
# Has the string next_page_token field to be used in the next request as
|
147
|
-
#
|
148
|
-
|
203
|
+
# Has the string next_page_token field to be used in the next request as
|
204
|
+
# page_token to retrieve the next page.
|
205
|
+
# Passes the heuristic for paginated response
|
206
|
+
# Order is important here, since paginated response heuristic can raise and should be evaluated last
|
207
|
+
paged_response_candidate? && !response_results_field.nil?
|
208
|
+
end
|
209
|
+
|
210
|
+
##
|
211
|
+
# Whether the response message for the REGAPIC rpc satisfies the criteria
|
212
|
+
# to be a candidate for pagination. This is intentinally split from evaluating
|
213
|
+
# the paged response heuristic since that heuristic can raise.
|
214
|
+
#
|
215
|
+
# @return [Boolean]
|
216
|
+
def paged_response_candidate?
|
217
|
+
# Has the string next_page_token field to be used in the next request as
|
218
|
+
# page_token to retrieve the next page.
|
219
|
+
!response_next_page_token_field.nil?
|
149
220
|
end
|
150
221
|
|
151
222
|
##
|
@@ -153,38 +224,102 @@ module Gapic
|
|
153
224
|
#
|
154
225
|
# @return [Gapic::Schema::Field, nil]
|
155
226
|
def response_next_page_token_field
|
156
|
-
# Has the string next_page_token field to be used in the next request as
|
227
|
+
# Has the string next_page_token field to be used in the next request as
|
228
|
+
# page_token to retrieve the next page.
|
157
229
|
@response_next_page_token_field ||= @response.fields.find do |f|
|
158
|
-
f.name ==
|
230
|
+
f.name == NEXT_PAGE_TOKEN_NAME && f.type == NEXT_PAGE_TOKEN_TYPE
|
159
231
|
end
|
160
232
|
end
|
161
233
|
|
234
|
+
|
235
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
236
|
+
# The heuristic in `response_results_field` would be more confusing if spread across several methods
|
237
|
+
|
162
238
|
##
|
163
239
|
# The field in the response that holds the results
|
164
|
-
# For Regapic can be either a vanilla repeated field or a map
|
240
|
+
# For Compute Regapic can be either a vanilla repeated field or a map
|
165
241
|
#
|
166
242
|
# @return [Gapic::Schema::Field, nil]
|
167
243
|
def response_results_field
|
244
|
+
# This sub-heuristic cannot end in "not paginated".
|
245
|
+
# It should either determine the results field or throw an error.
|
168
246
|
@response_results_field ||= begin
|
169
247
|
map_fields = @response.fields.find_all(&:map?)
|
170
248
|
repeated_fields = @response.fields.find_all do |f|
|
171
249
|
!f.map? && f.label == :LABEL_REPEATED
|
172
250
|
end
|
173
251
|
|
174
|
-
|
175
|
-
|
176
|
-
|
252
|
+
# The following steps are followed for this sub-heuristic:
|
253
|
+
# 0. Check the exception dictionary. If the method is there as key, use the value as the results field.
|
254
|
+
if REPEATED_FIELD_SPECIAL_DICTIONARY.key? @response.full_name
|
255
|
+
field_name = REPEATED_FIELD_SPECIAL_DICTIONARY[@response.full_name]
|
256
|
+
field = map_fields.find do |f|
|
257
|
+
f.name == field_name
|
258
|
+
end || repeated_fields.find do |f|
|
259
|
+
f.name == field_name
|
260
|
+
end
|
261
|
+
|
262
|
+
unless field
|
263
|
+
error_text = "A field of name \"#{field_name}\" is included in the special dictionary for " \
|
264
|
+
"the response type \"#{@response.full_name}\". However this field is not a map " \
|
265
|
+
"or repeated field. Failing, as the generator cannot continue."
|
266
|
+
|
267
|
+
raise ::Gapic::Model::ModelError, error_text
|
268
|
+
end
|
269
|
+
|
270
|
+
field
|
271
|
+
elsif map_fields.count == 1
|
272
|
+
# 1. If there is exactly one map field, that field is the results field.
|
177
273
|
map_fields.first
|
178
|
-
|
179
|
-
|
180
|
-
#
|
274
|
+
# NB: at this point the response contains either 0 or 2 map fields.
|
275
|
+
elsif repeated_fields.count.zero?
|
276
|
+
# 2. If there are no repeated fields there is no results field and we shall throw an error
|
277
|
+
error_text = "A response message \"#{@response.full_name}\" has a next page token field and " \
|
278
|
+
"is being evaluated as a candidate for pagination. However it has " \
|
279
|
+
"#{map_fields.count} (!= 1) map fields and no repeated fields. " \
|
280
|
+
"Failing, as the generator should not continue."
|
281
|
+
|
282
|
+
raise ::Gapic::Model::ModelError, error_text
|
283
|
+
elsif repeated_fields.count == 1
|
284
|
+
# 3. If there is exactly one repeated field, that field is the results field.
|
181
285
|
repeated_fields.first
|
286
|
+
elsif repeated_fields.count == 2
|
287
|
+
# 4. If there are exactly 2 repeated fields, one is of message type, and the other is of type
|
288
|
+
# "String", the field of message type is the results field.
|
289
|
+
pagination_field = repeated_fields.find(&:message?)
|
290
|
+
string_field = repeated_fields.find { |f| f.type == :TYPE_STRING }
|
291
|
+
|
292
|
+
unless pagination_field && string_field
|
293
|
+
# At this point if there are 2 repeated fields of different configuration, or 3 or more repeated
|
294
|
+
# fields the method should have been in the exception dictionary (see step 0).
|
295
|
+
error_text = "A response message \"#{@response.full_name}\" has a next page token " \
|
296
|
+
"field and is being evaluated as a candidate for pagination. However it should have " \
|
297
|
+
"a configuration of exactly 2 repeated fields, one is of message type, and the other " \
|
298
|
+
"of type \"String\". Failing, as the generator cannot continue. \n" \
|
299
|
+
"As a developer, please evaluate the message that fails this heuristic and either " \
|
300
|
+
"change the heuristic or add the message to the special dictionary."
|
301
|
+
|
302
|
+
raise ::Gapic::Model::ModelError, error_text
|
303
|
+
end
|
304
|
+
|
305
|
+
pagination_field
|
306
|
+
else
|
307
|
+
# At this point there are 3 or more repeated fields, and the method should have been in the
|
308
|
+
# exception dictionary (see step 0).
|
309
|
+
error_text = "A response message \"#{@response.full_name}\" has a next page token " \
|
310
|
+
"field and is being evaluated as a candidate for pagination. However it has " \
|
311
|
+
"#{repeated_fields.count} (>= 3) repeated fields, and not in the special dictionary " \
|
312
|
+
"for exceptions. Failing, as the generator cannot continue. \n" \
|
313
|
+
"As a developer, please evaluate the message that fails this heuristic and either " \
|
314
|
+
"change the heuristic or add the message to the special dictionary."
|
315
|
+
|
316
|
+
raise ::Gapic::Model::ModelError, error_text
|
182
317
|
end
|
183
|
-
# If the response message contains more than one repeated field or does not have repeated fields at all
|
184
|
-
# but has more than one map<string, ?> field, do not generate any paginated methods for such rpc.
|
185
318
|
end
|
186
319
|
end
|
187
320
|
|
321
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
322
|
+
|
188
323
|
# @private
|
189
324
|
FIELD_TYPE_MAPPING = {
|
190
325
|
TYPE_DOUBLE: "::Float",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gapic-generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.45.
|
4
|
+
version: 0.45.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ernest Landrito
|
@@ -87,14 +87,14 @@ dependencies:
|
|
87
87
|
requirements:
|
88
88
|
- - "~>"
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: 1.31.
|
90
|
+
version: 1.31.1
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: 1.31.
|
97
|
+
version: 1.31.1
|
98
98
|
email:
|
99
99
|
- landrito@google.com
|
100
100
|
- quartzmo@gmail.com
|