gapic-generator 0.9.1 → 0.10.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/lib/gapic/generator/version.rb +1 -1
  4. data/lib/gapic/generators/default_generator.rb +1 -1
  5. data/lib/gapic/generators/default_generator_parameters.rb +3 -1
  6. data/lib/gapic/presenters/gem_presenter.rb +12 -1
  7. data/lib/gapic/presenters/method/rest_pagination_info.rb +246 -0
  8. data/lib/gapic/presenters/method_presenter.rb +13 -2
  9. data/lib/gapic/presenters/method_rest_presenter.rb +60 -2
  10. data/lib/gapic/presenters/resource_presenter.rb +8 -0
  11. data/lib/gapic/presenters/service_presenter.rb +51 -0
  12. data/lib/gapic/presenters/service_rest_presenter.rb +42 -16
  13. data/lib/gapic/presenters/snippet_presenter.rb +1 -1
  14. data/lib/gapic/schema/api.rb +6 -1
  15. data/lib/gapic/schema/wrappers.rb +26 -0
  16. data/templates/default/lib/rest/_rest.erb +0 -2
  17. data/templates/default/service/client/_client.erb +17 -19
  18. data/templates/default/service/client/_config.erb +13 -14
  19. data/templates/default/service/client/_paths.erb +1 -1
  20. data/templates/default/service/client/method/_def.erb +2 -0
  21. data/templates/default/service/client/method/def/_options_defaults.erb +3 -1
  22. data/templates/default/service/client/method/docs/_deprecated.erb +5 -0
  23. data/templates/default/service/client/method/docs/_snippets.erb +6 -0
  24. data/templates/default/service/rest/client/_client.erb +14 -23
  25. data/templates/default/service/rest/client/_config.erb +48 -0
  26. data/templates/default/service/rest/client/method/_def.erb +1 -1
  27. data/templates/default/service/rest/client/method/def/_options_defaults.erb +5 -2
  28. data/templates/default/service/rest/client/method/def/_response.erb +6 -0
  29. data/templates/default/service/rest/client/method/def/_response_normal.erb +4 -15
  30. data/templates/default/service/rest/client/method/def/_response_paged.erb +7 -0
  31. data/templates/default/service/rest/client/method/docs/_result.erb +3 -3
  32. data/templates/default/service/rest/service_stub.erb +6 -0
  33. data/templates/default/service/rest/service_stub/_service_stub.erb +25 -0
  34. data/templates/default/service/rest/{grpc_transcoding/method → service_stub/grpc_transcoding_method}/_def.erb +4 -1
  35. data/templates/default/service/rest/{grpc_transcoding/method → service_stub/grpc_transcoding_method}/def/_query_string_param.erb +0 -0
  36. data/templates/default/service/rest/service_stub/method/_def.erb +20 -0
  37. data/templates/default/service/rest/service_stub/method/def/_request.erb +2 -0
  38. data/templates/default/service/rest/service_stub/method/def/_response.erb +17 -0
  39. data/templates/default/service/rest/test/client.erb +1 -1
  40. data/templates/default/service/test/client_paths.erb +1 -1
  41. metadata +19 -11
  42. data/templates/default/service/rest/client/_requires.erb +0 -1
  43. data/templates/default/service/rest/grpc_transcoding/_grpc_transcoding.erb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61762b2051b75312bfc67ef070e136d8cf95cad1635e1b22270ed8a5b6cfbc99
4
- data.tar.gz: cd867c0065831c6b5252dc0b5097417f24a74716f4e15cd243a1371ac80e5a5d
3
+ metadata.gz: 36abe40caa29f9c1368fc86632e1c57703d98346ab5dd70ad1a87ba7e73b277c
4
+ data.tar.gz: 60479a28e6d38873d21f06200f554e874ae2df926929e6eaef0a33e9b3099de5
5
5
  SHA512:
6
- metadata.gz: b8c833fe9bbb2d35c8fb0e7b307e1f0aeb0f5774fe0f174e2505bc0460fcc13ae06bf6e2761fe1e00d7e44079327fbc761f7423b72c51e58ef23c4f4220edebb
7
- data.tar.gz: 89e7871eac1c9e01d870c2e367e67e16ac5c49580259d828c922324250a88955da88014496a8da7ff22964e18941046153158df4d8a023a7fb9a158a86c06cea
6
+ metadata.gz: 970f3a69d280a1cdad3bd53554d48d89524528ae65033e9a469ce4be3ccd9da83d8bd1bb4a28a6d45d9989456398b8421876eaaa39e1eaf179e28573b6ded107
7
+ data.tar.gz: 41b9678039126730f3295f63cdd20d298516060b3965091888c47cec944863f7dba01d7d5254327c13477053bdcc4425e500a42cf63e620befda2addb0e85c7b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Release History for gapic-generator
2
2
 
3
+ ### 0.10.0 / 2021-08-09
4
+
5
+ * New: Enabled per-RPC configuration for generated REST libraries
6
+ * New: Generated docs include the deprecated YARD tag for deprecated protos
7
+ * New: Scopes can be passed to self-signed JWTs
8
+ * Fixed: Generated gRPC clients honor the client-default timeout config
9
+ * Fixed: Generated docs now use YARD example tags for inline samples related to configuration
10
+ * Fixed: Generated REST clients now require google/cloud/errors
11
+ * Generated libraries now require gapic-common 0.7.0 or later
12
+
13
+ ### 0.9.2 / 2021-07-27
14
+
15
+ * REST libraries are now generated with pagination hepers
16
+ * REST libraries are now generated with correct examples in README.md and other documentation files
17
+ * It is now possible to generate inline snippets in yardocs
18
+ * Fixed the require path in the generated standalone snippets so it reflects the recommended require root rather than the service-specific require path.
19
+ * Prevent "duplicate" resources (with the same name but different namespaces) from producing duplicate helper methods.
20
+
3
21
  ### 0.9.1 / 2021-07-07
4
22
 
5
23
  * Detect multiple resource parents for patterns used by multiple resources
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Gapic
18
18
  module Generator
19
- VERSION = "0.9.1"
19
+ VERSION = "0.10.0"
20
20
  end
21
21
  end
@@ -60,7 +60,7 @@ module Gapic
60
60
  files << g("service/paths.erb", "lib/#{service.paths_file_path}", service: service) if service.paths?
61
61
  files << g("service/operations.erb", "lib/#{service.operations_file_path}", service: service) if service.lro? && !@api.generate_rest_clients?
62
62
  files << g("service/rest/client.erb", "lib/#{service.rest.client_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
63
- files << g("service/rest/grpc_transcoding.erb", "lib/#{service.rest.transcoding_helper_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
63
+ files << g("service/rest/service_stub.erb", "lib/#{service.rest.service_stub_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
64
64
  files << g("service/rest/test/client.erb", "test/#{service.rest.test_client_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
65
65
  files << g("service/test/client.erb", "test/#{service.test_client_file_path}", service: service) unless @api.generate_rest_clients?
66
66
  files << g("service/test/client_paths.erb", "test/#{service.test_paths_file_path}", service: service) if service.paths?
@@ -24,7 +24,9 @@ module Gapic
24
24
  ":gem.:free_tier",
25
25
  ":gem.:yard_strict",
26
26
  ":gem.:generic_endpoint",
27
- ":generate_metadata"
27
+ ":generate_metadata",
28
+ ":generate_standalone_snippets",
29
+ ":generate_yardoc_snippets"
28
30
  ].freeze
29
31
 
30
32
  STRING_PARAMETERS = [
@@ -192,7 +192,7 @@ module Gapic
192
192
 
193
193
  def dependencies
194
194
  @dependencies ||= begin
195
- deps = { "gapic-common" => [">= 0.5", "< 2.a"] }
195
+ deps = { "gapic-common" => [">= 0.7", "< 2.a"] }
196
196
  deps["grpc-google-iam-v1"] = [">= 0.6.10", "< 2.a"] if iam_dependency?
197
197
  extra_deps = gem_config_dependencies
198
198
  deps.merge! extra_deps if extra_deps
@@ -239,6 +239,17 @@ module Gapic
239
239
  result || first_non_common_service
240
240
  end
241
241
 
242
+ ##
243
+ # Whether the "Enabling (gRPC) Logging" section of the readme should
244
+ # appear. This is true if there is a quick-start service displayed in the
245
+ # readme, AND it uses gRPC.
246
+ #
247
+ # @return [Boolean]
248
+ #
249
+ def show_grpc_logging_docs?
250
+ packages? && quick_start_service.usable_service_presenter.is_a?(ServicePresenter)
251
+ end
252
+
242
253
  private
243
254
 
244
255
  def gem_config key
@@ -0,0 +1,246 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Gapic
18
+ module Presenters
19
+ module Method
20
+ ##
21
+ # Pagination info determined from the proto method
22
+ #
23
+ class RestPaginationInfo
24
+ include Gapic::Helpers::NamespaceHelper
25
+ ##
26
+ # @param proto_method [Gapic::Schema::Method] the method to derive pagination info from
27
+ # @param api [Gapic::Schema::Api]
28
+ #
29
+ def initialize proto_method, api
30
+ @api = api
31
+ @request = proto_method.input
32
+ @response = proto_method.output
33
+ @server_streaming = proto_method.server_streaming
34
+ end
35
+
36
+ ##
37
+ # Whether the method should be generated as paged
38
+ #
39
+ # @return [Boolean]
40
+ def paged?
41
+ !server_streaming? && paged_request? && paged_response?
42
+ end
43
+
44
+ ##
45
+ # Name of the request's field used for page size
46
+ # For Regapic can be either `page_size` or `max_results`
47
+ #
48
+ # @return [String, nil]
49
+ def request_page_size_name
50
+ request_page_size_field&.name
51
+ end
52
+
53
+ ##
54
+ # Name of the repeated field in the response message
55
+ # For REST gapics can be either a vanilla repeated field or a map
56
+ #
57
+ # @return [String, nil]
58
+ def response_repeated_field_name
59
+ response_results_field&.name
60
+ end
61
+
62
+ ##
63
+ # Whether the repeated field in the response message is a map
64
+ #
65
+ # @return [Boolean, nil]
66
+ def repeated_field_is_a_map?
67
+ response_results_field&.map?
68
+ end
69
+
70
+ ##
71
+ # Proto type of the repeated field in the response message
72
+ #
73
+ # @return [String, nil]
74
+ def paged_element_doc_type
75
+ return nil if response_results_field.nil?
76
+ field_paginated_elem_doc_type response_results_field
77
+ end
78
+
79
+ private
80
+
81
+ # Whether the underlying proto rpc is a server streaming rpc
82
+ # @return [Boolean]
83
+ attr_accessor :server_streaming
84
+
85
+ ##
86
+ # Whether the underlying proto rpc is a server streaming rpc
87
+ #
88
+ # @return [Boolean]
89
+ def server_streaming?
90
+ @server_streaming
91
+ end
92
+
93
+ ##
94
+ # Whether the request message for the REGAPIC rpc satisfies the criteria
95
+ # for the rpc to be classified and implemented as paged
96
+ #
97
+ # @return [Boolean]
98
+ def paged_request?
99
+ # Has a String page_token field which specifies the actual (next) page to retrieve.
100
+ # Has an int32 page_size or int32 max_results field
101
+ # which defines the maximum number of paginated resources to return in the response.
102
+ !request_page_token_field.nil? && !request_page_size_field.nil?
103
+ end
104
+
105
+ ##
106
+ # The field in the request that holds a page_token
107
+ #
108
+ # @return[Gapic::Schema::Field, nil]
109
+ def request_page_token_field
110
+ # Has a String page_token field which specifies the actual (next) page to retrieve.
111
+ @request_page_token_field ||= @request.fields.find do |f|
112
+ f.name == "page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
113
+ end
114
+ end
115
+
116
+ ##
117
+ # The field in the request that holds a page_size
118
+ # For Regapic can have a name of either `page_size` or `max_results`
119
+ #
120
+ # @return[Gapic::Schema::Field, nil]
121
+ def request_page_size_field
122
+ @request_page_size_field ||=
123
+ begin
124
+ page_size_names = ["page_size", "max_results"]
125
+
126
+ # Has the int32 page_size or int32 max_results field
127
+ # which defines the maximum number of paginated resources to return in the response.
128
+ page_size_types = [
129
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT32,
130
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32
131
+ ]
132
+
133
+ field = @request.fields.find do |f|
134
+ page_size_names.include?(f.name) && page_size_types.include?(f.type)
135
+ end
136
+
137
+ field
138
+ end
139
+ end
140
+
141
+ ##
142
+ # Whether the response message for the REGAPIC rpc satisfies the criteria
143
+ # for the rpc to be classified and implemented as paged
144
+ #
145
+ # @return [Boolean]
146
+ def paged_response?
147
+ # Has the string next_page_token field to be used in the next request as page_token to retrieve the next page.
148
+ # Has only one repeated or map<string, ?> field containing a list of paginated resources.
149
+ !response_next_page_token_field.nil? && !response_results_field.nil?
150
+ end
151
+
152
+ ##
153
+ # The field in the response that holds a next page_token
154
+ #
155
+ # @return[Gapic::Schema::Field, nil]
156
+ def response_next_page_token_field
157
+ # Has the string next_page_token field to be used in the next request as page_token to retrieve the next page.
158
+ @response_next_page_token_field ||= @response.fields.find do |f|
159
+ f.name == "next_page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
160
+ end
161
+ end
162
+
163
+ ##
164
+ # The field in the response that holds the results
165
+ # For Regapic can be either a vanilla repeated field or a map
166
+ #
167
+ # @return [Gapic::Schema::Field, nil]
168
+ def response_results_field
169
+ @response_results_field ||= begin
170
+ map_fields = @response.fields.find_all(&:map?)
171
+ repeated_fields = @response.fields.find_all do |f|
172
+ !f.map? &&
173
+ f.label == Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED
174
+ end
175
+
176
+ if map_fields.count == 1
177
+ # If the response message has only one map<string, ?> field
178
+ # treat it as the one with paginated resources (i.e. ignore the repeated fields if any).
179
+ map_fields.first
180
+ elsif repeated_fields.count == 1 && map_fields.empty?
181
+ # If the response message contains only one repeated field,
182
+ # treat that field as the one containing the paginated resources.
183
+ repeated_fields.first
184
+ end
185
+ # If the response message contains more than one repeated field or does not have repeated fields at all
186
+ # but has more than one map<string, ?> field, do not generate any paginated methods for such rpc.
187
+ end
188
+ end
189
+
190
+ ##
191
+ # A helper to get a Ruby doc-type for a paginated element.
192
+ #
193
+ # @param field [Gapic::Schema::Field]
194
+ #
195
+ # @return [String]
196
+ def field_paginated_elem_doc_type field
197
+ return field_paginated_elem_map_type field if field.map?
198
+ if field.message?
199
+ message_ruby_type field.message
200
+ elsif field.enum?
201
+ # TODO: handle when arg message is nil and enum is the type
202
+ message_ruby_type field.enum
203
+ else
204
+ case field.type
205
+ when 1, 2 then "::Float"
206
+ when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "::Integer"
207
+ when 9, 12 then "::String"
208
+ when 8 then "::Boolean"
209
+ else
210
+ "::Object"
211
+ end
212
+ end
213
+ end
214
+
215
+ ##
216
+ # A helper to get a Ruby doc-type for a proto map's paginated element.
217
+ #
218
+ # @param field [Gapic::Schema::Field]
219
+ #
220
+ # @return [String]
221
+ def field_paginated_elem_map_type field
222
+ key_field = field.map_key_field
223
+ value_field = field.map_val_field
224
+
225
+ if key_field && value_field
226
+ key_type = field_paginated_elem_doc_type key_field
227
+ value_type = field_paginated_elem_doc_type value_field
228
+ "#{key_type}, #{value_type}"
229
+ else
230
+ class_name
231
+ end
232
+ end
233
+
234
+ ##
235
+ # A helper to get a Ruby type for a proto message.
236
+ #
237
+ # @param message [Gapic::Schema::Message]
238
+ #
239
+ # @return [String]
240
+ def message_ruby_type message
241
+ ruby_namespace @api, message.address.join(".")
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end
@@ -40,7 +40,7 @@ module Gapic
40
40
  @service_presenter = service_presenter
41
41
  @api = api
42
42
  @method = method
43
- @rest = MethodRestPresenter.new self
43
+ @rest = MethodRestPresenter.new self, api
44
44
  end
45
45
 
46
46
  ##
@@ -54,6 +54,10 @@ module Gapic
54
54
  SnippetPresenter.new self, @api
55
55
  end
56
56
 
57
+ def generate_yardoc_snippets?
58
+ @api.generate_yardoc_snippets?
59
+ end
60
+
57
61
  def name
58
62
  @name ||= begin
59
63
  candidate = ActiveSupport::Inflector.underscore @method.name
@@ -93,6 +97,13 @@ module Gapic
93
97
  ret
94
98
  end
95
99
 
100
+ ##
101
+ # @return [Boolean]
102
+ #
103
+ def is_deprecated?
104
+ @method.is_deprecated?
105
+ end
106
+
96
107
  def arguments
97
108
  arguments = @method.input.fields.reject(&:output_only?)
98
109
  arguments.map { |arg| FieldPresenter.new @api, @method.input, arg }
@@ -175,7 +186,7 @@ module Gapic
175
186
  def lro?
176
187
  return paged_response_type == "::Google::Longrunning::Operation" if paged?
177
188
 
178
- message_ruby_type(@method.output) == "::Google::Longrunning::Operation"
189
+ return_type == "::Google::Longrunning::Operation"
179
190
  end
180
191
 
181
192
  def client_streaming?
@@ -14,6 +14,7 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
+ require "gapic/presenters/method/rest_pagination_info"
17
18
  require "gapic/uri_template"
18
19
 
19
20
  module Gapic
@@ -22,9 +23,19 @@ module Gapic
22
23
  # A presenter for rpc methods (REST submethods)
23
24
  #
24
25
  class MethodRestPresenter
25
- def initialize main_method
26
+ # @return [Gapic::Presenters::Method::RestPaginationInfo]
27
+ attr_reader :pagination
28
+
29
+ ##
30
+ # @param main_method [Gapic::Presenters::MethodPresenter] the main presenter for this method.
31
+ # @param api [Gapic::Schema::Api]
32
+ #
33
+ def initialize main_method, api
34
+ @api = api
26
35
  @main_method = main_method
27
36
  @proto_method = main_method.method
37
+
38
+ @pagination = Gapic::Presenters::Method::RestPaginationInfo.new @proto_method, api
28
39
  end
29
40
 
30
41
  ##
@@ -187,7 +198,54 @@ module Gapic
187
198
  #
188
199
  # @return [String]
189
200
  def transcoding_helper_name
190
- "transcode_#{@main_method.name}"
201
+ "transcode_#{name}_request"
202
+ end
203
+
204
+ ##
205
+ # Method name
206
+ #
207
+ # @return [String]
208
+ #
209
+ def name
210
+ @main_method.name
211
+ end
212
+
213
+ ##
214
+ # Full class name of the request type
215
+ #
216
+ # @return [String]
217
+ #
218
+ def request_type
219
+ @main_method.request_type
220
+ end
221
+
222
+ ##
223
+ # Full class name of the raw return type of the RPC
224
+ #
225
+ # @return [String]
226
+ #
227
+ def return_type
228
+ @main_method.return_type
229
+ end
230
+
231
+ ##
232
+ # Full class name of the return type of the method
233
+ # (including LRO and Paged cases)
234
+ #
235
+ # @return [String]
236
+ #
237
+ def doc_response_type
238
+ return "::Gapic::Rest::PagedEnumerable<#{pagination.paged_element_doc_type}>" if paged?
239
+ return_type
240
+ end
241
+
242
+ ##
243
+ # Whether the REGAPIC method should be rendered as paged
244
+ #
245
+ # @return [Boolean]
246
+ #
247
+ def paged?
248
+ @pagination.paged?
191
249
  end
192
250
  end
193
251
  end