gapic-generator 0.7.2 → 0.7.4
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 +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/gapic/generator/version.rb +1 -1
- data/lib/gapic/generators/default_generator.rb +8 -5
- data/lib/gapic/generators/default_generator_parameters.rb +8 -4
- data/lib/gapic/presenters.rb +2 -0
- data/lib/gapic/presenters/field_presenter.rb +44 -0
- data/lib/gapic/presenters/gem_presenter.rb +4 -1
- data/lib/gapic/presenters/method_presenter.rb +32 -16
- data/lib/gapic/presenters/method_rest_presenter.rb +186 -0
- data/lib/gapic/presenters/package_presenter.rb +18 -0
- data/lib/gapic/presenters/service_presenter.rb +42 -4
- data/lib/gapic/presenters/service_rest_presenter.rb +157 -0
- data/lib/gapic/schema/api.rb +44 -16
- data/lib/gapic/schema/request_param_parser.rb +44 -10
- data/templates/default/lib/_package.erb +11 -1
- data/templates/default/lib/_service.erb +31 -1
- data/templates/default/lib/rest/_rest.erb +11 -0
- data/templates/default/service/rest.erb +6 -0
- data/templates/default/service/rest/client.erb +6 -0
- data/templates/default/service/rest/client/_client.erb +115 -0
- data/templates/default/service/rest/client/_config.erb +74 -0
- data/templates/default/service/rest/client/_requires.erb +1 -0
- data/templates/default/service/rest/client/method/_def.erb +18 -0
- data/templates/default/service/rest/client/method/def/_options_defaults.erb +14 -0
- data/templates/default/service/rest/client/method/def/_rescue.erb +3 -0
- data/templates/default/service/rest/client/method/def/_response_normal.erb +17 -0
- data/templates/default/service/rest/client/method/docs/_error.erb +2 -0
- data/templates/default/service/rest/client/method/docs/_request.erb +27 -0
- data/templates/default/service/rest/client/method/docs/_result.erb +6 -0
- data/templates/default/service/rest/grpc_transcoding.erb +6 -0
- data/templates/default/service/rest/grpc_transcoding/_grpc_transcoding.erb +9 -0
- data/templates/default/service/rest/grpc_transcoding/method/_def.erb +21 -0
- data/templates/default/service/rest/grpc_transcoding/method/def/_query_string_param.erb +8 -0
- metadata +22 -3
@@ -54,7 +54,10 @@ module Gapic
|
|
54
54
|
namespace.split("::").last
|
55
55
|
end
|
56
56
|
|
57
|
+
##
|
57
58
|
# Services whose clients should be generated in this package namespace.
|
59
|
+
# @return [Enumerable<Gapic::Presenters::ServicePresenter>]
|
60
|
+
#
|
58
61
|
def services
|
59
62
|
@services ||= begin
|
60
63
|
files = @api.generate_files.select { |f| f.package == @package }
|
@@ -117,6 +120,21 @@ module Gapic
|
|
117
120
|
services: services.map { |s| [s.grpc_service_name, s.drift_manifest] }.to_h
|
118
121
|
}
|
119
122
|
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# How comments in the generated libraries refer to the GRPC client
|
126
|
+
# if no REST code is generated, this should just be "client",
|
127
|
+
# if REST code is generated, this should be disambiguated into the "GRPC client"
|
128
|
+
#
|
129
|
+
# Since we are using first service for an indication of whether package generates
|
130
|
+
# REST code, it's OK to defer this to the first service as well.
|
131
|
+
# For packages with no services the value of this does not really matter as
|
132
|
+
# no client generation docs will be generated.
|
133
|
+
#
|
134
|
+
# @return [String]
|
135
|
+
def grpc_client_designation
|
136
|
+
services.first&.grpc_client_designation || ""
|
137
|
+
end
|
120
138
|
end
|
121
139
|
end
|
122
140
|
end
|
@@ -27,11 +27,15 @@ module Gapic
|
|
27
27
|
include Gapic::Helpers::FilepathHelper
|
28
28
|
include Gapic::Helpers::NamespaceHelper
|
29
29
|
|
30
|
+
# @return [Gapic::Presenters::ServiceRestPresenter]
|
31
|
+
attr_reader :rest
|
32
|
+
|
30
33
|
def initialize gem_presenter, api, service, parent_service: nil
|
31
34
|
@gem_presenter = gem_presenter
|
32
35
|
@api = api
|
33
36
|
@service = service
|
34
37
|
@parent_service = parent_service
|
38
|
+
@rest = ServiceRestPresenter.new self, api
|
35
39
|
end
|
36
40
|
|
37
41
|
def gem
|
@@ -46,10 +50,11 @@ module Gapic
|
|
46
50
|
PackagePresenter.new @gem_presenter, @api, @service.parent.package
|
47
51
|
end
|
48
52
|
|
53
|
+
##
|
54
|
+
# @return [Enumerable<Gapic::Presenters::MethodPresenter>]
|
55
|
+
#
|
49
56
|
def methods
|
50
|
-
@methods ||=
|
51
|
-
@service.methods.map { |m| MethodPresenter.new self, @api, m }
|
52
|
-
end
|
57
|
+
@methods ||= @service.methods.map { |m| MethodPresenter.new self, @api, m }
|
53
58
|
end
|
54
59
|
|
55
60
|
def address
|
@@ -271,6 +276,29 @@ module Gapic
|
|
271
276
|
ruby_file_path @api, "#{service_name_full}::#{paths_name}"
|
272
277
|
end
|
273
278
|
|
279
|
+
def generate_rest_clients?
|
280
|
+
@api.generate_rest_clients?
|
281
|
+
end
|
282
|
+
|
283
|
+
def generate_grpc_clients?
|
284
|
+
@api.generate_grpc_clients?
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# @return [Boolean] whether this service contains any methods with REST bindings
|
289
|
+
#
|
290
|
+
def methods_rest_bindings?
|
291
|
+
methods_rest_bindings.any?
|
292
|
+
end
|
293
|
+
|
294
|
+
##
|
295
|
+
# @return [Enumerable<Gapic::Presenters::MethodPresenter>]
|
296
|
+
# List of mods for which REST bindings are present and REST methods can be generated
|
297
|
+
#
|
298
|
+
def methods_rest_bindings
|
299
|
+
methods.select { |method| method.rest.path? && method.rest.verb? }
|
300
|
+
end
|
301
|
+
|
274
302
|
def test_client_file_path
|
275
303
|
service_file_path.sub ".rb", "_test.rb"
|
276
304
|
end
|
@@ -361,12 +389,22 @@ module Gapic
|
|
361
389
|
# their names are returned together in an array.
|
362
390
|
# For Ruby currently we have 1:1 proto to code
|
363
391
|
# correspondence for methods, so our generation is easier
|
364
|
-
|
392
|
+
rpcs: methods.map { |m| [m.grpc_method_name, m.drift_manifest] }.to_h
|
365
393
|
}
|
366
394
|
}
|
367
395
|
}
|
368
396
|
end
|
369
397
|
|
398
|
+
##
|
399
|
+
# How comments in the generated libraries refer to the GRPC client
|
400
|
+
# if no REST code is generated, this should just be "client",
|
401
|
+
# if REST code is generated, this should be disambiguated into the "GRPC client"
|
402
|
+
#
|
403
|
+
# @return [String]
|
404
|
+
def grpc_client_designation
|
405
|
+
generate_rest_clients? ? "GRPC client" : "client"
|
406
|
+
end
|
407
|
+
|
370
408
|
private
|
371
409
|
|
372
410
|
def default_config key
|
@@ -0,0 +1,157 @@
|
|
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
|
+
require "active_support/inflector"
|
18
|
+
require "gapic/helpers/filepath_helper"
|
19
|
+
require "gapic/helpers/namespace_helper"
|
20
|
+
|
21
|
+
module Gapic
|
22
|
+
module Presenters
|
23
|
+
##
|
24
|
+
# A presenter for proto service (REST submethods)
|
25
|
+
#
|
26
|
+
class ServiceRestPresenter
|
27
|
+
include Gapic::Helpers::FilepathHelper
|
28
|
+
include Gapic::Helpers::NamespaceHelper
|
29
|
+
|
30
|
+
##
|
31
|
+
# @param main_service [Gapic::Presenters::ServicePresenter]
|
32
|
+
# @param api [Gapic::Schema::Api]
|
33
|
+
#
|
34
|
+
def initialize main_service, api
|
35
|
+
@main_service = main_service
|
36
|
+
@api = api
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
def service_name_full
|
43
|
+
fix_namespace api, "#{main_service.service_name_full}::Rest"
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# @return [String]
|
48
|
+
#
|
49
|
+
def client_name
|
50
|
+
main_service.client_name
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# @return [String]
|
55
|
+
#
|
56
|
+
def client_name_full
|
57
|
+
fix_namespace api, "#{service_name_full}::#{client_name}"
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# @return [String]
|
62
|
+
#
|
63
|
+
def client_require
|
64
|
+
ruby_file_path api, client_name_full
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# @return [String]
|
69
|
+
#
|
70
|
+
def client_file_path
|
71
|
+
"#{client_require}.rb"
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_client_call
|
75
|
+
"#{client_name_full}.new"
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# @return [String]
|
80
|
+
#
|
81
|
+
def service_stub_name
|
82
|
+
"ServiceStub"
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# @return [String]
|
87
|
+
#
|
88
|
+
def service_stub_name_full
|
89
|
+
fix_namespace api, "#{service_name_full}::#{service_stub_name}"
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# @return [String]
|
94
|
+
#
|
95
|
+
def service_stub_require
|
96
|
+
ruby_file_path api, service_stub_name_full
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# @return [String]
|
101
|
+
#
|
102
|
+
def service_stub_file_path
|
103
|
+
"#{service_stub_require}.rb"
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
107
|
+
# @return [String]
|
108
|
+
#
|
109
|
+
def service_rest_require
|
110
|
+
ruby_file_path api, service_name_full
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# @return [String]
|
115
|
+
#
|
116
|
+
def service_rest_file_path
|
117
|
+
"#{service_rest_require}.rb"
|
118
|
+
end
|
119
|
+
|
120
|
+
##
|
121
|
+
# @return [String]
|
122
|
+
#
|
123
|
+
def transcoding_helper_name
|
124
|
+
"GrpcTranscoding"
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# @return [String]
|
129
|
+
#
|
130
|
+
def transcoding_helper_name_full
|
131
|
+
fix_namespace api, "#{service_name_full}::#{transcoding_helper_name}"
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# @return [String]
|
136
|
+
#
|
137
|
+
def transcoding_helper_require
|
138
|
+
ruby_file_path api, transcoding_helper_name_full
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# @return [String]
|
143
|
+
#
|
144
|
+
def transcoding_helper_file_path
|
145
|
+
"#{transcoding_helper_require}.rb"
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
# @return [Gapic::Presenters::ServicePresenter]
|
152
|
+
attr_reader :main_service
|
153
|
+
# @return [Gapic::Schema::Api]
|
154
|
+
attr_reader :api
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
data/lib/gapic/schema/api.rb
CHANGED
@@ -144,11 +144,9 @@ module Gapic
|
|
144
144
|
# @return [Array<Hash>]
|
145
145
|
# An array of the sample file hashes.
|
146
146
|
def samples
|
147
|
-
@samples ||=
|
148
|
-
|
149
|
-
|
150
|
-
end.compact
|
151
|
-
end
|
147
|
+
@samples ||= protoc_options["samples"].to_s.split(";").flat_map do |sample_path|
|
148
|
+
YAML.load_file sample_path
|
149
|
+
end.compact
|
152
150
|
end
|
153
151
|
|
154
152
|
# Structured representation of the standalone samples configuration files.
|
@@ -174,10 +172,10 @@ module Gapic
|
|
174
172
|
# An array of the standalone sample configuration hashes.
|
175
173
|
def standalone_test_samples
|
176
174
|
@standalone_test_samples ||= begin
|
177
|
-
samples.select { |sample| sample["type"] == "test/samples" }
|
178
|
-
|
179
|
-
|
180
|
-
|
175
|
+
test_samples = samples.select { |sample| sample["type"] == "test/samples" }
|
176
|
+
test_samples.select { |sample| sample["schema_version"] == "1" || sample["schema_version"] == 1 }
|
177
|
+
.map { |sample| sample["samples"] }
|
178
|
+
.flatten.compact
|
181
179
|
end
|
182
180
|
end
|
183
181
|
|
@@ -231,6 +229,24 @@ module Gapic
|
|
231
229
|
configuration[:generate_path_helpers_output] ||= false
|
232
230
|
end
|
233
231
|
|
232
|
+
# Whether to generate REST clients
|
233
|
+
def generate_rest_clients?
|
234
|
+
return false if configuration[:transports].nil?
|
235
|
+
configuration[:transports].include? "rest"
|
236
|
+
end
|
237
|
+
|
238
|
+
# Whether to generate GRPC clients
|
239
|
+
def generate_grpc_clients?
|
240
|
+
return true if configuration[:transports].nil?
|
241
|
+
configuration[:transports].include? "grpc"
|
242
|
+
end
|
243
|
+
|
244
|
+
# Whether to generate gapic metadata (drift manifest) file
|
245
|
+
# @return [Boolean]
|
246
|
+
def generate_metadata
|
247
|
+
configuration[:generate_metadata] ||= false
|
248
|
+
end
|
249
|
+
|
234
250
|
# Whether the override_proto_namespaces parameter was given in the configuration
|
235
251
|
def override_proto_namespaces_defined?
|
236
252
|
configuration.key? :override_proto_namespaces
|
@@ -260,9 +276,7 @@ module Gapic
|
|
260
276
|
|
261
277
|
# Parsed grpc service config
|
262
278
|
def grpc_service_config
|
263
|
-
@grpc_service_config ||=
|
264
|
-
Gapic::GrpcServiceConfig::Parser.parse grpc_service_config_raw
|
265
|
-
end
|
279
|
+
@grpc_service_config ||= Gapic::GrpcServiceConfig::Parser.parse grpc_service_config_raw
|
266
280
|
end
|
267
281
|
|
268
282
|
# Get a resource given its type string
|
@@ -272,10 +286,8 @@ module Gapic
|
|
272
286
|
|
273
287
|
# Given a service, find all common services that use it as a delegate.
|
274
288
|
def common_services_for delegate
|
275
|
-
@delegate_to_common ||=
|
276
|
-
(
|
277
|
-
(mapping[d] ||= []) << c
|
278
|
-
end
|
289
|
+
@delegate_to_common ||= (configuration[:common_services] || {}).each_with_object({}) do |(c, d), mapping|
|
290
|
+
(mapping[d] ||= []) << c
|
279
291
|
end
|
280
292
|
all_services = services
|
281
293
|
@delegate_to_common.fetch(delegate.address.join("."), []).map do |addr|
|
@@ -292,6 +304,22 @@ module Gapic
|
|
292
304
|
services.find { |s| s.address == addr }
|
293
305
|
end
|
294
306
|
|
307
|
+
##
|
308
|
+
# Whether configuration has an override for the wrapper gem name
|
309
|
+
# @return [Boolean]
|
310
|
+
def wrapper_gem_name_override?
|
311
|
+
configuration.key?(:overrides) &&
|
312
|
+
configuration[:overrides].key?(:wrapper_gem_name)
|
313
|
+
end
|
314
|
+
|
315
|
+
##
|
316
|
+
# An override for the wrapper gem name in the configuration
|
317
|
+
# @return [String, Nil]
|
318
|
+
def wrapper_gem_name_override
|
319
|
+
return nil unless wrapper_gem_name_override?
|
320
|
+
configuration[:overrides][:wrapper_gem_name]
|
321
|
+
end
|
322
|
+
|
295
323
|
private
|
296
324
|
|
297
325
|
# Perform a variety of sanity checks on the data, and prints errors to
|
@@ -67,14 +67,13 @@ module Gapic
|
|
67
67
|
param_name_input = unescape param_name_input_esc
|
68
68
|
param_type, param_config_name = param_schema.schema_name_type_for param_name_input
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
param_value = parse_param_value param_type, value_str
|
70
|
+
param_value = parse_validate_param_value(
|
71
|
+
param_type,
|
72
|
+
param_name_input,
|
73
|
+
param_config_name,
|
74
|
+
value_str,
|
75
|
+
error_output
|
76
|
+
)
|
78
77
|
|
79
78
|
if param_value
|
80
79
|
RequestParameter.new param_val_input_str, param_name_input_esc, value_str, param_config_name, param_value
|
@@ -92,13 +91,48 @@ module Gapic
|
|
92
91
|
|
93
92
|
private
|
94
93
|
|
94
|
+
# Parses and validates param value depending on type and name
|
95
|
+
# @param param_type [Symbol] type of the parameter
|
96
|
+
# @param param_name_input [String] name of the parameter as given in the config
|
97
|
+
# @param param_config_name [String] canonical configuration name of the parameter
|
98
|
+
# @param value_str [String] string representation of parameter's value
|
99
|
+
# @param error_output [IO] Stream to write outputs to.
|
100
|
+
# @return [String,Array<String>,Hash{String => String}]
|
101
|
+
def parse_validate_param_value param_type, param_name_input, param_config_name, value_str, error_output
|
102
|
+
if param_type == :bool && !["true", "false"].include?(unescape(value_str))
|
103
|
+
error_str = "WARNING: parameter #{param_name_input} (recognised as bool " \
|
104
|
+
"#{param_config_name}) will be discarded because of " \
|
105
|
+
"invalid value. Value should be either 'true' or 'false'."
|
106
|
+
error_output&.puts error_str
|
107
|
+
end
|
108
|
+
|
109
|
+
param_value = parse_param_value param_type, value_str
|
110
|
+
|
111
|
+
if param_config_name == ":transports"
|
112
|
+
allowed_transports = ["grpc", "rest"]
|
113
|
+
noncompliant_values = param_value.reject { |pv| allowed_transports.include? pv }
|
114
|
+
if noncompliant_values.any?
|
115
|
+
noncompliant_values_list = noncompliant_values.join ", "
|
116
|
+
error_str = "WARNING: parameter #{param_name_input} (recognised as string array " \
|
117
|
+
"#{param_config_name}) will be discarded because "\
|
118
|
+
"it contains invalid values: #{noncompliant_values_list}. "\
|
119
|
+
"#{param_config_name} can only contain 'grpc' and/or 'rest' or be empty."
|
120
|
+
error_output&.puts error_str
|
121
|
+
param_value = nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
param_value
|
126
|
+
end
|
127
|
+
|
95
128
|
# Parses param value depending on type
|
96
|
-
# @param param_type [Symbol]
|
97
|
-
# @param value_str [String]
|
129
|
+
# @param param_type [Symbol] type of the parameter
|
130
|
+
# @param value_str [String] string representation of parameter's value
|
98
131
|
# @return [String,Array<String>,Hash{String => String}]
|
99
132
|
def parse_param_value param_type, value_str
|
100
133
|
case param_type
|
101
134
|
when :array
|
135
|
+
return [] if value_str.empty?
|
102
136
|
# elements in the arrays are concatenated by `;`
|
103
137
|
# e.g. foo;bar;baz
|
104
138
|
array_value_strings = split_by_unescaped value_str, ";"
|
@@ -6,13 +6,23 @@ require "<%= service.service_require %>"
|
|
6
6
|
require "<%= package.gem.version_require %>"
|
7
7
|
<% end %>
|
8
8
|
<%- unless package.empty? -%>
|
9
|
+
<%- if package.services.first.generate_grpc_clients? -%>
|
9
10
|
##
|
10
|
-
# To load this package, including all its services, and instantiate a
|
11
|
+
# To load this package, including all its services, and instantiate a <%= package.grpc_client_designation %>:
|
11
12
|
#
|
12
13
|
# require "<%= package.package_require %>"
|
13
14
|
# client = <%= package.services.first.create_client_call %>
|
14
15
|
#
|
15
16
|
<%- end -%>
|
17
|
+
<%- if package.services.first.generate_rest_clients? -%>
|
18
|
+
##
|
19
|
+
# To load this package, including all its services, and instantiate a REST client:
|
20
|
+
#
|
21
|
+
# require "<%= package.package_require %>"
|
22
|
+
# client = <%= package.services.first.rest.create_client_call %>
|
23
|
+
#
|
24
|
+
<%- end -%>
|
25
|
+
<%- end -%>
|
16
26
|
module <%= package.module_name %>
|
17
27
|
end
|
18
28
|
<% @footer = capture do %>
|