gapic-generator 0.7.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -0
  3. data/lib/gapic/generator/version.rb +1 -1
  4. data/lib/gapic/generators/default_generator.rb +18 -5
  5. data/lib/gapic/generators/default_generator_parameters.rb +8 -4
  6. data/lib/gapic/presenters.rb +4 -0
  7. data/lib/gapic/presenters/field_presenter.rb +44 -0
  8. data/lib/gapic/presenters/gem_presenter.rb +55 -10
  9. data/lib/gapic/presenters/method_presenter.rb +40 -16
  10. data/lib/gapic/presenters/method_rest_presenter.rb +194 -0
  11. data/lib/gapic/presenters/package_presenter.rb +18 -0
  12. data/lib/gapic/presenters/service_config_presenter.rb +48 -0
  13. data/lib/gapic/presenters/service_presenter.rb +60 -4
  14. data/lib/gapic/presenters/service_rest_presenter.rb +139 -0
  15. data/lib/gapic/presenters/snippet_presenter.rb +103 -0
  16. data/lib/gapic/runner.rb +2 -1
  17. data/lib/gapic/schema/api.rb +58 -16
  18. data/lib/gapic/schema/request_param_parser.rb +46 -12
  19. data/lib/google/protobuf/any.pb.rb +1 -1
  20. data/lib/google/protobuf/compiler/plugin.pb.rb +9 -6
  21. data/lib/google/protobuf/descriptor.pb.rb +2 -2
  22. data/lib/google/protobuf/empty.pb.rb +1 -1
  23. data/templates/default/gem/readme.erb +3 -3
  24. data/templates/default/lib/_package.erb +11 -1
  25. data/templates/default/lib/_service.erb +31 -1
  26. data/templates/default/lib/rest/_rest.erb +11 -0
  27. data/templates/default/service/client/_client.erb +1 -1
  28. data/templates/default/service/client/_credentials.erb +2 -0
  29. data/templates/default/service/client/_operations.erb +1 -1
  30. data/templates/default/service/client/_self_configure_defaults.erb +2 -2
  31. data/templates/default/service/rest.erb +6 -0
  32. data/templates/default/service/rest/client.erb +6 -0
  33. data/templates/default/service/rest/client/_client.erb +115 -0
  34. data/templates/default/service/rest/client/_config.erb +74 -0
  35. data/templates/default/service/rest/client/_requires.erb +1 -0
  36. data/templates/default/service/rest/client/method/_def.erb +18 -0
  37. data/templates/default/service/rest/client/method/def/_options_defaults.erb +15 -0
  38. data/templates/default/service/rest/client/method/def/_rescue.erb +3 -0
  39. data/templates/default/service/rest/client/method/def/_response_normal.erb +17 -0
  40. data/templates/default/service/rest/client/method/docs/_error.erb +2 -0
  41. data/templates/default/service/rest/client/method/docs/_request.erb +27 -0
  42. data/templates/default/service/rest/client/method/docs/_result.erb +6 -0
  43. data/templates/default/service/rest/grpc_transcoding.erb +6 -0
  44. data/templates/default/service/rest/grpc_transcoding/_grpc_transcoding.erb +9 -0
  45. data/templates/default/service/rest/grpc_transcoding/method/_def.erb +21 -0
  46. data/templates/default/service/rest/grpc_transcoding/method/def/_query_string_param.erb +8 -0
  47. data/templates/default/service/rest/test/client.erb +18 -0
  48. data/templates/default/service/rest/test/method/_assert_response.erb +2 -0
  49. data/templates/default/service/rest/test/method/_configure.erb +19 -0
  50. data/templates/default/service/rest/test/method/_normal.erb +71 -0
  51. data/templates/default/service/rest/test/method/_setup.erb +38 -0
  52. data/templates/default/snippets/gemfile.erb +17 -0
  53. data/templates/default/snippets/snippet/_structure.erb +71 -0
  54. data/templates/default/snippets/standalone.erb +6 -0
  55. metadata +32 -4
  56. data/templates/default/service/client/_self_configure_retry_policy.erb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a5cfd7100b78e532d61c6cbb0e1fdc26e4e52235d0838c887a3ee951f642513
4
- data.tar.gz: 42ca94ca019ed994efc8beb90bbb3e88921b2b128b346551f1ae7acc8999b5e8
3
+ metadata.gz: ab653b4ab114926d58b96c5326de2a8ece5ad19d2780cb8ec5886ee83a3cb053
4
+ data.tar.gz: 733ccb95f513617b9fc653ac8bbc8f02a37fa8be1a8b81c5cec051299d5f7468
5
5
  SHA512:
6
- metadata.gz: 963c359acc6f8d5ebba562d8e151394e95db7db61cc203a05a14b7e941ef22849a3d9bf7ca1d517548ec7aaaa817339557dfa90592dfc54c9628c193d49ab928
7
- data.tar.gz: 0a955e4cfcd87eb3c112d8acb3bf58b1db10f224f22bbf0422af76876e58d01f1b3a5d65543c8909e005787e7ded93554bcc62887fc3e60625091bc254cf1d81
6
+ metadata.gz: 5ceea190fdf3424e89df06130809a21f6cc43b61255e1a9fa143413e4ca197a7f52962dcd060693091317226063ae373cb2c6cfdb55bf516ae06c4d9099d43b4
7
+ data.tar.gz: 7558dd6358c2a19e2e9d471270acb9ce12a94696b67980193e4d6dcafb168f79342a408b68d89408606ff208fec5f5ae5bbad35110f81e9398d2eb5a124c5f43
data/CHANGELOG.md CHANGED
@@ -1,5 +1,52 @@
1
1
  # Release History for gapic-generator
2
2
 
3
+ ### 0.9.0 / 2021-06-29
4
+
5
+ * Support for configuring the service/method used for the quickstart example
6
+ * Allow generation of libraries with no custom env prefix
7
+ * Add service override setting to the repo metadata
8
+ * Wrapper gem dependencies on pre-GA versioned gems now allow both 0.x and 1.x versions
9
+ * Scoped some String and Hash references to the global scope to avoid name collisions
10
+ * Reformat some config code to avoid rubocop indentation churn
11
+ * Bazel: Replace monolith deps with rules_gapic
12
+
13
+ ### 0.8.0 / 2021-06-16
14
+
15
+ * Initial implementation of standalone snippet generation.
16
+ * Updated gapic-common dependencies to require at least 0.5 and to support future 1.x versions.
17
+ * Generated unit tests for REST clients.
18
+ * Generated proper x-goog-api-client headers for REST clients.
19
+ * Added generation arguments to generated repo metadata.
20
+ * Allow multiple versions in the extra-dependency command line argument.
21
+ * Fixed treatment of boolean-valued command line arguments to the generator.
22
+ * Fixed behavior of wrapper-gem-override if given an empty value.
23
+ * Fixed default env_prefix computation to avoid the version part of the proto namespace.
24
+ * Fixed Bazel front-end to preserve file permissions.
25
+
26
+ ### 0.7.5 / 2021-05-18
27
+
28
+ * Bazel jobs now provide a prebuilt ruby binary.
29
+ * Fixed generated indentation for a few cases, by updating to Rubocop 1.15.
30
+ * Added library_type to generated repo metadata files.
31
+
32
+ ### 0.7.4 / 2021-05-07
33
+
34
+ * Fixed the broken link in the generated libraries' README.md
35
+ * Generated libraries with REST transport now use presense testing instead of rejecting defaults to determine which fields to transcode into the query string parameters
36
+
37
+ ### 0.7.3 / 2021-03-24
38
+
39
+ * Fixed gapic metadata (drift manifest) generation
40
+ * Gapic metadata generation is disabled by default in gapic-generator
41
+ (enabled by default in gapic-generator-cloud)
42
+ * Can now generate libraries with REST transport in addition to GRPC
43
+ * gapic-common 0.4 is the default version for the generated libraries now (was 0.3)
44
+ (required for the generated libraries with the REST transport)
45
+
46
+ ### 0.7.2 / 2021-03-05
47
+
48
+ * No changes.
49
+
3
50
  ### 0.7.1 / 2021-02-27
4
51
 
5
52
  * Update generated readmes to reflect that Ruby 2.5 or later is now required.
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Gapic
18
18
  module Generator
19
- VERSION = "0.7.1"
19
+ VERSION = "0.9.0"
20
20
  end
21
21
  end
@@ -54,13 +54,24 @@ module Gapic
54
54
  package.services.each do |service|
55
55
  # Service level files
56
56
  files << g("service.erb", "lib/#{service.service_file_path}", service: service)
57
- files << g("service/client.erb", "lib/#{service.client_file_path}", service: service)
57
+ files << g("service/rest.erb", "lib/#{service.rest.service_rest_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
58
+ files << g("service/client.erb", "lib/#{service.client_file_path}", service: service) unless @api.generate_rest_clients?
58
59
  files << g("service/credentials.erb", "lib/#{service.credentials_file_path}", service: service) unless gem.generic_endpoint?
59
60
  files << g("service/paths.erb", "lib/#{service.paths_file_path}", service: service) if service.paths?
60
- files << g("service/operations.erb", "lib/#{service.operations_file_path}", service: service) if service.lro?
61
- files << g("service/test/client.erb", "test/#{service.test_client_file_path}", service: service)
61
+ files << g("service/operations.erb", "lib/#{service.operations_file_path}", service: service) if service.lro? && !@api.generate_rest_clients?
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?
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
+ files << g("service/test/client.erb", "test/#{service.test_client_file_path}", service: service) unless @api.generate_rest_clients?
62
66
  files << g("service/test/client_paths.erb", "test/#{service.test_paths_file_path}", service: service) if service.paths?
63
- files << g("service/test/client_operations.erb", "test/#{service.test_client_operations_file_path}", service: service) if service.lro?
67
+ files << g("service/test/client_operations.erb", "test/#{service.test_client_operations_file_path}", service: service) if service.lro? && !@api.generate_rest_clients?
68
+
69
+ if @api.generate_standalone_snippets?
70
+ service.methods.each do |method|
71
+ snippet = method.snippet
72
+ files << g("snippets/standalone.erb", "snippets/#{snippet.snippet_file_path}", snippet: snippet)
73
+ end
74
+ end
64
75
  end
65
76
  end
66
77
 
@@ -77,7 +88,9 @@ module Gapic
77
88
  files << g("gem/yardopts.erb", ".yardopts", gem: gem)
78
89
  files << g("gem/license.erb", "LICENSE.md", gem: gem)
79
90
  files << g("gem/entrypoint.erb", "lib/#{gem.name}.rb", gem: gem)
80
- files << g("gem/gapic_metadata_json.erb", "gapic_metadata.json", gem: gem)
91
+ files << g("gem/gapic_metadata_json.erb", "gapic_metadata.json", gem: gem) if @api.generate_metadata
92
+
93
+ files << g("snippets/gemfile.erb", "snippets/Gemfile", gem: gem) if @api.generate_standalone_snippets?
81
94
 
82
95
  gem.proto_files.each do |proto_file|
83
96
  files << g("proto_docs/proto_file.erb", "proto_docs/#{proto_file.docs_file_path}", file: proto_file)
@@ -23,7 +23,8 @@ module Gapic
23
23
  BOOL_PARAMETERS = [
24
24
  ":gem.:free_tier",
25
25
  ":gem.:yard_strict",
26
- ":gem.:generic_endpoint"
26
+ ":gem.:generic_endpoint",
27
+ ":generate_metadata"
27
28
  ].freeze
28
29
 
29
30
  STRING_PARAMETERS = [
@@ -42,11 +43,13 @@ module Gapic
42
43
  ":gem.:api_shortname",
43
44
  ":gem.:factory_method_suffix",
44
45
  ":defaults.:service.:default_host",
45
- "grpc_service_config"
46
+ "grpc_service_config",
47
+ ":overrides.:wrapper_gem_name"
46
48
  ].freeze
47
49
 
48
50
  ARRAY_PARAMETERS = [
49
- ":defaults.:service.:oauth_scopes"
51
+ ":defaults.:service.:oauth_scopes",
52
+ ":transports"
50
53
  ].freeze
51
54
 
52
55
  MAP_PARAMETERS = [
@@ -83,7 +86,8 @@ module Gapic
83
86
  }.freeze
84
87
 
85
88
  ARRAY_PARAMETERS_ALIASES = {
86
- "default-oauth-scopes" => ":defaults.:service.:oauth_scopes"
89
+ "default-oauth-scopes" => ":defaults.:service.:oauth_scopes",
90
+ "transports" => ":transports"
87
91
  }.freeze
88
92
 
89
93
  MAP_PARAMETERS_ALIASES = {
@@ -21,10 +21,14 @@ require "gapic/presenters/file_presenter"
21
21
  require "gapic/presenters/gem_presenter"
22
22
  require "gapic/presenters/message_presenter"
23
23
  require "gapic/presenters/method_presenter"
24
+ require "gapic/presenters/method_rest_presenter"
24
25
  require "gapic/presenters/package_presenter"
25
26
  require "gapic/presenters/resource_presenter"
26
27
  require "gapic/presenters/sample_presenter"
27
28
  require "gapic/presenters/service_presenter"
29
+ require "gapic/presenters/service_config_presenter"
30
+ require "gapic/presenters/service_rest_presenter"
31
+ require "gapic/presenters/snippet_presenter"
28
32
 
29
33
  module Gapic
30
34
  ##
@@ -88,6 +88,10 @@ module Gapic
88
88
  @field.repeated?
89
89
  end
90
90
 
91
+ def required?
92
+ @field.required?
93
+ end
94
+
91
95
  def map?
92
96
  @field.map?
93
97
  end
@@ -100,6 +104,34 @@ module Gapic
100
104
  @message.oneof_decl[@field.oneof_index].name
101
105
  end
102
106
 
107
+ ##
108
+ # Returns a stringified default value for the protobuf types
109
+ # that are possible to fit into the query string parameter
110
+ # and nil for the other types (e.g. Messages)
111
+ #
112
+ # @return [String, nil]
113
+ #
114
+ def default_value_for_type
115
+ if @field.message?
116
+ nil
117
+ elsif @field.enum?
118
+ ":#{@field.enum.values.first.name}"
119
+ else
120
+ case @field.type
121
+ when 1, 2, 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "0" # floating point or integer
122
+ when 9, 12 then "\"\""
123
+ when 8 then "false"
124
+ end
125
+ end
126
+ end
127
+
128
+ ##
129
+ # Name of this field, camel-cased
130
+ # @return [String]
131
+ def camel_name
132
+ camel_name_for name
133
+ end
134
+
103
135
  protected
104
136
 
105
137
  def field_doc_types field, output
@@ -161,6 +193,18 @@ module Gapic
161
193
  def message_ruby_type message
162
194
  ruby_namespace @api, message.address.join(".")
163
195
  end
196
+
197
+ ##
198
+ # Converts a snake_case parameter name into camelCase for query string parameters
199
+ # @param attr_name [String]
200
+ # @return [String] camel-cased parameter name
201
+ def camel_name_for attr_name
202
+ parts = attr_name.split "_"
203
+ first_part = parts[0]
204
+ other_parts = parts[1..-1]
205
+ other_parts_pascal = other_parts.map(&:capitalize).join
206
+ "#{first_part}#{other_parts_pascal}"
207
+ end
164
208
  end
165
209
  end
166
210
  end
@@ -32,6 +32,9 @@ module Gapic
32
32
  @api = api
33
33
  end
34
34
 
35
+ ##
36
+ # @return [Enumerable<Gapic::Presenters::PackagePresenter>]
37
+ #
35
38
  def packages
36
39
  @packages ||= begin
37
40
  packages = @api.generate_files.map(&:package).uniq.sort
@@ -124,7 +127,7 @@ module Gapic
124
127
  end
125
128
 
126
129
  def env_prefix
127
- (gem_config(:env_prefix) || name.split("-").last).upcase
130
+ gem_config(:env_prefix)&.upcase
128
131
  end
129
132
 
130
133
  def iam_dependency?
@@ -153,18 +156,26 @@ module Gapic
153
156
  gem_config :issue_tracker_url
154
157
  end
155
158
 
159
+ ##
160
+ # @return [Boolean]
161
+ #
156
162
  def free_tier?
157
- # Default to false unless the config is explicitly set to "true"
158
- gem_config(:free_tier) == "true"
163
+ gem_config(:free_tier) || false
159
164
  end
160
165
 
166
+ ##
167
+ # @return [Boolean]
168
+ #
161
169
  def yard_strict?
162
170
  # Default to true unless the config is explicitly set to "false"
163
- gem_config(:yard_strict) != "false"
171
+ gem_config(:yard_strict).nil? || gem_config(:yard_strict)
164
172
  end
165
173
 
174
+ ##
175
+ # @return [Boolean]
176
+ #
166
177
  def generic_endpoint?
167
- gem_config(:generic_endpoint) == "true"
178
+ gem_config(:generic_endpoint) || false
168
179
  end
169
180
 
170
181
  def entrypoint_require
@@ -180,11 +191,13 @@ module Gapic
180
191
  end
181
192
 
182
193
  def dependencies
183
- deps = { "gapic-common" => "~> 0.3" }
184
- deps["grpc-google-iam-v1"] = [">= 0.6.10", "< 2.0"] if iam_dependency?
185
- extra_deps = gem_config :extra_dependencies
186
- deps.merge! extra_deps if extra_deps
187
- deps
194
+ @dependencies ||= begin
195
+ deps = { "gapic-common" => [">= 0.5", "< 2.a"] }
196
+ deps["grpc-google-iam-v1"] = [">= 0.6.10", "< 2.a"] if iam_dependency?
197
+ extra_deps = gem_config_dependencies
198
+ deps.merge! extra_deps if extra_deps
199
+ deps
200
+ end
188
201
  end
189
202
 
190
203
  def dependency_list
@@ -214,6 +227,18 @@ module Gapic
214
227
  JSON.pretty_generate first_package_drift_manifest
215
228
  end
216
229
 
230
+ ##
231
+ # The service to use for quick start samples. Normally this is simply the
232
+ # {#first_non_common_service}, but it can be overridden via a gem config.
233
+ #
234
+ # @return [Gapic::Presenters::ServicePresenter]
235
+ #
236
+ def quick_start_service
237
+ preferred_service = gem_config :quick_start_service
238
+ result = services.find { |svc| svc.name == preferred_service } if preferred_service
239
+ result || first_non_common_service
240
+ end
241
+
217
242
  private
218
243
 
219
244
  def gem_config key
@@ -222,6 +247,26 @@ module Gapic
222
247
  @api.configuration[:gem][key]
223
248
  end
224
249
 
250
+ ##
251
+ # There is a special case (from PoV of generator parameters)
252
+ # in gem dependencies where a dependency needs to be an array of strings
253
+ # e.g. ">= 1.6", "< 2.a"
254
+ # Rather than creating a special generator param case for this I will special-case it here.
255
+ # '|' is the separator.
256
+ # The above would be represented as ">= 1.6|< 2.a"
257
+ #
258
+ # @return [Hash<String, String>, Hash{String=>Array<String>}, nil]
259
+ def gem_config_dependencies
260
+ return unless gem_config :extra_dependencies
261
+ gem_config(:extra_dependencies).map do |dep_name, dep_versions|
262
+ if dep_versions.include? "|"
263
+ [dep_name, dep_versions.split("|")]
264
+ else
265
+ [dep_name, dep_versions]
266
+ end
267
+ end.to_h
268
+ end
269
+
225
270
  def blacklist_protos
226
271
  blacklist = gem_config :blacklist
227
272
 
@@ -15,7 +15,6 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "active_support/inflector"
18
- require "gapic/uri_template"
19
18
  require "gapic/ruby_info"
20
19
  require "gapic/helpers/namespace_helper"
21
20
 
@@ -27,16 +26,34 @@ module Gapic
27
26
  class MethodPresenter
28
27
  include Gapic::Helpers::NamespaceHelper
29
28
 
29
+ # @return [Gapic::Schema::Method]
30
+ attr_accessor :method
31
+
32
+ # @return [Gapic::Presenters::MethodRestPresenter]
33
+ attr_accessor :rest
34
+
35
+ ##
36
+ # @param service_presenter [Gapic::Presenters::ServicePresenter]
37
+ # @param api [Gapic::Schema::Api]
38
+ # @param method [Gapic::Schema::Method]
30
39
  def initialize service_presenter, api, method
31
40
  @service_presenter = service_presenter
32
41
  @api = api
33
42
  @method = method
43
+ @rest = MethodRestPresenter.new self
34
44
  end
35
45
 
46
+ ##
47
+ # @return [Gapic::Presenters::ServicePresenter]
48
+ #
36
49
  def service
37
50
  @service_presenter
38
51
  end
39
52
 
53
+ def snippet
54
+ SnippetPresenter.new self, @api
55
+ end
56
+
40
57
  def name
41
58
  @name ||= begin
42
59
  candidate = ActiveSupport::Inflector.underscore @method.name
@@ -195,15 +212,17 @@ module Gapic
195
212
  end
196
213
 
197
214
  ##
198
- #
199
215
  # @return [Array<String>] The segment key names.
200
216
  #
201
217
  def routing_params
202
- Gapic::UriTemplate.parse_arguments method_path
218
+ rest.routing_params
203
219
  end
204
220
 
221
+ ##
222
+ # @return [Boolean] Whether any routing params are present
223
+ #
205
224
  def routing_params?
206
- routing_params.any?
225
+ rest.routing_params?
207
226
  end
208
227
 
209
228
  def grpc_service_config
@@ -213,10 +232,27 @@ module Gapic
213
232
  end
214
233
  end
215
234
 
235
+ def service_config_presenter
236
+ ServiceConfigPresenter.new grpc_service_config
237
+ end
238
+
216
239
  def grpc_method_name
217
240
  @method.name
218
241
  end
219
242
 
243
+ ##
244
+ # Returns a hash with a drift_manifest of this rpc method
245
+ # describing correspondence between the proto description
246
+ # of the rpc with the generated code for the method.
247
+ # For ruby currently [03/2021] only one method is generated per RPC,
248
+ # so the correspondence is very basic.
249
+ # See https://github.com/googleapis/googleapis/blob/master/gapic/metadata/gapic_metadata.proto
250
+ #
251
+ # @return [Hash]
252
+ def drift_manifest
253
+ { methods: [name] }
254
+ end
255
+
220
256
  protected
221
257
 
222
258
  def message_ruby_type message
@@ -266,18 +302,6 @@ module Gapic
266
302
  end
267
303
  end
268
304
 
269
- def method_path
270
- return "" if @method.http.nil?
271
-
272
- method = [
273
- @method.http.get, @method.http.post, @method.http.put,
274
- @method.http.patch, @method.http.delete
275
- ].find { |x| !x.empty? }
276
- return method unless method.nil?
277
-
278
- return @method.http.custom.path unless @method.http.custom.nil?
279
- end
280
-
281
305
  def paged_request? request
282
306
  page_token = request.fields.find do |f|
283
307
  f.name == "page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING