gapic-generator 0.7.5 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/lib/gapic/generator/version.rb +1 -1
  4. data/lib/gapic/generators/default_generator.rb +11 -1
  5. data/lib/gapic/generators/default_generator_parameters.rb +3 -1
  6. data/lib/gapic/presenters.rb +2 -0
  7. data/lib/gapic/presenters/gem_presenter.rb +63 -10
  8. data/lib/gapic/presenters/method/rest_pagination_info.rb +246 -0
  9. data/lib/gapic/presenters/method_presenter.rb +21 -2
  10. data/lib/gapic/presenters/method_rest_presenter.rb +70 -4
  11. data/lib/gapic/presenters/resource_presenter.rb +8 -0
  12. data/lib/gapic/presenters/service_config_presenter.rb +48 -0
  13. data/lib/gapic/presenters/service_presenter.rb +69 -0
  14. data/lib/gapic/presenters/service_rest_presenter.rb +36 -28
  15. data/lib/gapic/presenters/snippet_presenter.rb +103 -0
  16. data/lib/gapic/schema/api.rb +32 -8
  17. data/lib/gapic/schema/request_param_parser.rb +2 -2
  18. data/lib/gapic/schema/wrappers.rb +26 -0
  19. data/templates/default/gem/readme.erb +3 -3
  20. data/templates/default/lib/rest/_rest.erb +0 -2
  21. data/templates/default/service/client/_client.erb +18 -20
  22. data/templates/default/service/client/_config.erb +13 -14
  23. data/templates/default/service/client/_credentials.erb +2 -0
  24. data/templates/default/service/client/_operations.erb +1 -1
  25. data/templates/default/service/client/_paths.erb +1 -1
  26. data/templates/default/service/client/_self_configure_defaults.erb +2 -2
  27. data/templates/default/service/client/method/_def.erb +2 -0
  28. data/templates/default/service/client/method/def/_options_defaults.erb +3 -1
  29. data/templates/default/service/client/method/docs/_deprecated.erb +5 -0
  30. data/templates/default/service/client/method/docs/_snippets.erb +6 -0
  31. data/templates/default/service/rest/client/_client.erb +15 -24
  32. data/templates/default/service/rest/client/_config.erb +48 -0
  33. data/templates/default/service/rest/client/method/_def.erb +1 -1
  34. data/templates/default/service/rest/client/method/def/_options_defaults.erb +7 -3
  35. data/templates/default/service/rest/client/method/def/_response.erb +6 -0
  36. data/templates/default/service/rest/client/method/def/_response_normal.erb +4 -15
  37. data/templates/default/service/rest/client/method/def/_response_paged.erb +7 -0
  38. data/templates/default/service/rest/client/method/docs/_result.erb +3 -3
  39. data/templates/default/service/rest/service_stub.erb +6 -0
  40. data/templates/default/service/rest/service_stub/_service_stub.erb +25 -0
  41. data/templates/default/service/rest/{grpc_transcoding/method → service_stub/grpc_transcoding_method}/_def.erb +4 -1
  42. data/templates/default/service/rest/{grpc_transcoding/method → service_stub/grpc_transcoding_method}/def/_query_string_param.erb +0 -0
  43. data/templates/default/service/rest/service_stub/method/_def.erb +20 -0
  44. data/templates/default/service/rest/service_stub/method/def/_request.erb +2 -0
  45. data/templates/default/service/rest/service_stub/method/def/_response.erb +17 -0
  46. data/templates/default/service/rest/test/client.erb +18 -0
  47. data/templates/default/service/rest/test/method/_assert_response.erb +2 -0
  48. data/templates/default/service/rest/test/method/_configure.erb +19 -0
  49. data/templates/default/service/rest/test/method/_normal.erb +71 -0
  50. data/templates/default/service/rest/test/method/_setup.erb +38 -0
  51. data/templates/default/service/test/client_paths.erb +1 -1
  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 +29 -12
  56. data/templates/default/service/client/_self_configure_retry_policy.erb +0 -15
  57. data/templates/default/service/rest/client/_requires.erb +0 -1
  58. data/templates/default/service/rest/grpc_transcoding/_grpc_transcoding.erb +0 -9
@@ -0,0 +1,103 @@
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
+
19
+ module Gapic
20
+ module Presenters
21
+ ##
22
+ # A presenter for snippets.
23
+ #
24
+ class SnippetPresenter
25
+ def initialize method_presenter, api
26
+ @method_presenter = method_presenter
27
+ @api = api
28
+ end
29
+
30
+ def client_streaming?
31
+ @method_presenter.client_streaming?
32
+ end
33
+
34
+ def bidi_streaming?
35
+ @method_presenter.client_streaming? && @method_presenter.server_streaming?
36
+ end
37
+
38
+ def response_kind
39
+ if @method_presenter.server_streaming?
40
+ :streaming
41
+ elsif @method_presenter.paged?
42
+ :paged
43
+ elsif @method_presenter.lro?
44
+ :lro
45
+ else
46
+ :simple
47
+ end
48
+ end
49
+
50
+ def snippet_file_path
51
+ "#{@method_presenter.service.service_require.split('/').last}/#{@method_presenter.name}.rb"
52
+ end
53
+
54
+ def require_path
55
+ @method_presenter.service.package.package_require
56
+ end
57
+
58
+ def client_type
59
+ @method_presenter.service.client_name_full.sub(/^::/, "")
60
+ end
61
+
62
+ def request_type
63
+ @method_presenter.request_type.sub(/^::/, "")
64
+ end
65
+
66
+ def return_type
67
+ base_type = @method_presenter.return_type.sub(/^::/, "")
68
+ @method_presenter.server_streaming? ? "Enumerable<#{base_type}>" : base_type
69
+ end
70
+
71
+ def paged_response_type
72
+ @method_presenter.paged_response_type
73
+ end
74
+
75
+ def base_response_type
76
+ @method_presenter.return_type
77
+ end
78
+
79
+ # TODO: Determine type of LRO response
80
+
81
+ def method_name
82
+ @method_presenter.name
83
+ end
84
+
85
+ def region_tag
86
+ gem_presenter = @method_presenter.service.gem
87
+ api_id = gem_presenter.api_shortname || gem_presenter.api_id&.split(".")&.first
88
+ names = gem_presenter.name.split "-"
89
+ final_name = names.pop
90
+ if final_name =~ /^v\d/
91
+ api_version = final_name
92
+ api_id ||= names.last
93
+ else
94
+ api_id ||= final_name
95
+ api_version = "v0"
96
+ end
97
+ service_name = @method_presenter.service.module_name
98
+ method_name = @method_presenter.method.name
99
+ "#{api_id}_#{api_version}_generated_#{service_name}_#{method_name}_sync"
100
+ end
101
+ end
102
+ end
103
+ end
@@ -89,6 +89,10 @@ module Gapic
89
89
  matching_files.first
90
90
  end
91
91
 
92
+ def overrides_of key
93
+ configuration&.fetch(:overrides, nil)&.fetch(key, nil) || {}
94
+ end
95
+
92
96
  def fix_file_path str
93
97
  str = String str
94
98
  return str if configuration[:overrides].nil?
@@ -241,6 +245,16 @@ module Gapic
241
245
  configuration[:transports].include? "grpc"
242
246
  end
243
247
 
248
+ # Whether to generate standalone snippets
249
+ def generate_standalone_snippets?
250
+ configuration[:generate_standalone_snippets] ||= false
251
+ end
252
+
253
+ # Whether to generate inline documentation snippets
254
+ def generate_yardoc_snippets?
255
+ configuration[:generate_yardoc_snippets] ||= false
256
+ end
257
+
244
258
  # Whether to generate gapic metadata (drift manifest) file
245
259
  # @return [Boolean]
246
260
  def generate_metadata
@@ -314,10 +328,15 @@ module Gapic
314
328
 
315
329
  ##
316
330
  # An override for the wrapper gem name in the configuration
317
- # @return [String, Nil]
331
+ # @return [String, nil]
318
332
  def wrapper_gem_name_override
319
333
  return nil unless wrapper_gem_name_override?
320
- configuration[:overrides][:wrapper_gem_name]
334
+ return nil if configuration[:overrides][:wrapper_gem_name].nil?
335
+
336
+ wrapper_name_config = configuration[:overrides][:wrapper_gem_name].strip
337
+ return nil if wrapper_name_config.empty?
338
+
339
+ wrapper_name_config
321
340
  end
322
341
 
323
342
  private
@@ -340,9 +359,14 @@ module Gapic
340
359
  # * A mapping from resource type to resource wrapper is returned.
341
360
  def analyze_resources
342
361
  # In order to set parent_resources, we first populate a mapping from
343
- # parsed pattern to resource mapping (in the patterns variable). This
344
- # is done in one pass along with populating the resource type mapping.
345
- # Then, we go through all resources again, get its expected parent
362
+ # parsed pattern to resources that use it (in the patterns variable).
363
+ # Note that there may be multiple resources associated with a pattern.
364
+ # (This is uncommon, but one example is monitoring v3 which uses
365
+ # "projects/*" for its workspace type as well as inheriting the common
366
+ # project type. We thus map each pattern to an array of resources.)
367
+ # Constructing the patterns mapping is done in one pass along with
368
+ # populating the type mapping (which maps only to single resources.)
369
+ # Then, we go through all resources again, get each's expected parent
346
370
  # patterns, and anything that shows up in the patterns mapping is taken
347
371
  # to be a parent.
348
372
  types = {}
@@ -353,8 +377,8 @@ module Gapic
353
377
  end
354
378
  types.each do |_type, resource|
355
379
  parents = resource.parsed_parent_patterns
356
- .map { |pat| patterns[pat] }
357
- .compact.uniq
380
+ .flat_map { |pat| Array(patterns[pat]) }
381
+ .uniq
358
382
  resource.parent_resources.replace parents
359
383
  end
360
384
  types
@@ -363,7 +387,7 @@ module Gapic
363
387
  def populate_resource_lookups resource, types, patterns
364
388
  types[resource.type] = resource
365
389
  resource.parsed_patterns.each do |pat|
366
- patterns[pat] = resource
390
+ ((patterns[pat] ||= []) << resource).uniq!
367
391
  end
368
392
  end
369
393
 
@@ -75,7 +75,7 @@ module Gapic
75
75
  error_output
76
76
  )
77
77
 
78
- if param_value
78
+ unless param_value.nil?
79
79
  RequestParameter.new param_val_input_str, param_name_input_esc, value_str, param_config_name, param_value
80
80
  end
81
81
  end.compact # known bool parameters with invalid values will not be added so we have to compact
@@ -148,7 +148,7 @@ module Gapic
148
148
  when :bool
149
149
  # bools should be either `true` or `false`
150
150
  unesc_val = unescape value_str
151
- unesc_val if ["true", "false"].include? unesc_val
151
+ (unesc_val == "true") if ["true", "false"].include? unesc_val
152
152
  else
153
153
  # if it's an unknown type, just escape it without attempting to parse anything
154
154
  unescape value_str
@@ -268,6 +268,12 @@ module Gapic
268
268
  parent.ruby_package
269
269
  end
270
270
 
271
+ # @return [Boolean] True if this service is marked as deprecated, false
272
+ # otherwise.
273
+ def is_deprecated?
274
+ options[:deprecated] if options
275
+ end
276
+
271
277
  # @return [Array<Google::Api::ResourceDescriptor>] A representation of the resource.
272
278
  # This is generally intended to be attached to the "name" field.
273
279
  # See `google/api/resource.proto`.
@@ -336,6 +342,12 @@ module Gapic
336
342
  options[:".google.longrunning.operation_info"] if options
337
343
  end
338
344
 
345
+ # @return [Boolean] True if this method is marked as deprecated, false
346
+ # otherwise.
347
+ def is_deprecated?
348
+ options[:deprecated] if options
349
+ end
350
+
339
351
  # @return [Google::Api::HttpRule] The HTTP bindings for this method. See
340
352
  # `google/api/http.proto`.
341
353
  def http
@@ -641,6 +653,20 @@ module Gapic
641
653
  false
642
654
  end
643
655
 
656
+ # @return [Field, nil] a key field for this map
657
+ # or nil if this field is not a map
658
+ def map_key_field
659
+ return nil? unless map?
660
+ @message.fields.find { |f| f.name == "key" }
661
+ end
662
+
663
+ # @return [Field, nil] a value field for this map
664
+ # or nil if this field is not a map
665
+ def map_val_field
666
+ return nil? unless map?
667
+ @message.fields.find { |f| f.name == "value" }
668
+ end
669
+
644
670
  # @return [String] A reference to another resource message or resource
645
671
  # definition. See `google/api/resource.proto`.
646
672
  def resource_reference
@@ -16,12 +16,12 @@ $ gem install <%= gem.name %>
16
16
 
17
17
  ```ruby
18
18
  require "<%= gem.entrypoint_require %>"
19
- <%- service = gem.first_non_common_service -%>
20
- <%- method = service&.methods.first -%>
19
+ <%- service = gem.quick_start_service -%>
20
+ <%- method = service&.quick_start_method -%>
21
21
  <%- if service && method -%>
22
22
 
23
23
  client = <%= service.create_client_call %>
24
- request = my_create_request
24
+ request = <%= method.request_type %>.new # (request fields as keyword arguments...)
25
25
  response = client.<%= method.name %> request
26
26
  <%- end -%>
27
27
  ```
@@ -1,7 +1,5 @@
1
1
  <%- assert_locals service -%>
2
2
  <% @requires = capture do %>
3
- require "gapic/rest"
4
- require "<%= service.rest.transcoding_helper_require %>"
5
3
  require "<%= service.rest.client_require %>"
6
4
  <% end %>
7
5
  module <%= service.module_name %>
@@ -23,14 +23,17 @@ class <%= service.client_name %>
23
23
  #
24
24
  # See {<%= service.client_name_full %>::Configuration}
25
25
  # for a description of the configuration fields.
26
+ <%- if service.is_deprecated? -%>
26
27
  #
27
- # ## Example
28
+ # @deprecated This service is deprecated and may be removed in the next major version update.
29
+ <%- end -%>
28
30
  #
29
- # To modify the configuration for all <%= service.name %> clients:
31
+ # @example
30
32
  #
31
- # <%= service.client_name_full %>.configure do |config|
32
- # config.timeout = 10.0
33
- # end
33
+ # # Modify the configuration for all <%= service.name %> clients
34
+ # <%= service.client_name_full %>.configure do |config|
35
+ # config.timeout = 10.0
36
+ # end
34
37
  #
35
38
  # @yield [config] Configure the <%= service.client_name %> client.
36
39
  # @yieldparam config [<%= service.client_name %>::Configuration]
@@ -64,19 +67,15 @@ class <%= service.client_name %>
64
67
  ##
65
68
  # Create a new <%= service.name %> client object.
66
69
  #
67
- # ## Examples
68
- #
69
- # To create a new <%= service.name %> client with the default
70
- # configuration:
71
- #
72
- # client = <%= service.client_name_full %>.new
70
+ # @example
73
71
  #
74
- # To create a new <%= service.name %> client with a custom
75
- # configuration:
72
+ # # Create a client using the default configuration
73
+ # client = <%= service.client_name_full %>.new
76
74
  #
77
- # client = <%= service.client_name_full %>.new do |config|
78
- # config.timeout = 10.0
79
- # end
75
+ # # Create a client using a custom configuration
76
+ # client = <%= service.client_name_full %>.new do |config|
77
+ # config.timeout = 10.0
78
+ # end
80
79
  #
81
80
  # @yield [config] Configure the <%= service.name %> client.
82
81
  # @yieldparam config [<%= service.client_name %>::Configuration]
@@ -97,14 +96,13 @@ class <%= service.client_name %>
97
96
  # Create credentials
98
97
  credentials = @config.credentials
99
98
  <%- unless service.generic_endpoint? -%>
100
- # Use self-signed JWT if the scope and endpoint are unchanged from default,
99
+ # Use self-signed JWT if the endpoint is unchanged from default,
101
100
  # but only if the default endpoint does not have a region prefix.
102
- enable_self_signed_jwt = @config.scope == <%= service.client_name %>.configure.scope &&
103
- @config.endpoint == <%= service.client_name %>.configure.endpoint &&
101
+ enable_self_signed_jwt = @config.endpoint == <%= service.client_name %>.configure.endpoint &&
104
102
  !@config.endpoint.split(".").first.include?("-")
105
103
  credentials ||= Credentials.default scope: @config.scope,
106
104
  enable_self_signed_jwt: enable_self_signed_jwt
107
- if credentials.is_a?(String) || credentials.is_a?(Hash)
105
+ if credentials.is_a?(::String) || credentials.is_a?(::Hash)
108
106
  credentials = Credentials.new credentials, scope: @config.scope
109
107
  end
110
108
  <%- end -%>
@@ -14,22 +14,21 @@
14
14
  # on construction.
15
15
  #
16
16
  <%- unless method_service.methods.empty? -%>
17
- # # Examples
17
+ # @example
18
18
  #
19
- # To modify the global config, setting the timeout for <%= method_service.methods.first.name %>
20
- # to 20 seconds, and all remaining timeouts to 10 seconds:
19
+ # # Modify the global config, setting the timeout for
20
+ # # <%= method_service.methods.first.name %> to 20 seconds,
21
+ # # and all remaining timeouts to 10 seconds.
22
+ # <%= service.client_name_full %>.configure do |config|
23
+ # config.timeout = 10.0
24
+ # config.rpcs.<%= method_service.methods.first.name %>.timeout = 20.0
25
+ # end
21
26
  #
22
- # <%= service.client_name_full %>.configure do |config|
23
- # config.timeout = 10.0
24
- # config.rpcs.<%= method_service.methods.first.name %>.timeout = 20.0
25
- # end
26
- #
27
- # To apply the above configuration only to a new client:
28
- #
29
- # client = <%= service.client_name_full %>.new do |config|
30
- # config.timeout = 10.0
31
- # config.rpcs.<%= method_service.methods.first.name %>.timeout = 20.0
32
- # end
27
+ # # Apply the above configuration only to a new client.
28
+ # client = <%= service.client_name_full %>.new do |config|
29
+ # config.timeout = 10.0
30
+ # config.rpcs.<%= method_service.methods.first.name %>.timeout = 20.0
31
+ # end
33
32
  #
34
33
  <%- end -%>
35
34
  # @!attribute [rw] endpoint
@@ -12,10 +12,12 @@ class <%= service.credentials_name %> < ::Google::Auth::Credentials
12
12
  <%- end -%>
13
13
  ]
14
14
  <%- end -%>
15
+ <%- if service.gem.env_prefix -%>
15
16
  self.env_vars = [
16
17
  "<%= service.gem.env_prefix %>_CREDENTIALS",
17
18
  "<%= service.gem.env_prefix %>_KEYFILE",
18
19
  "<%= service.gem.env_prefix %>_CREDENTIALS_JSON",
19
20
  "<%= service.gem.env_prefix %>_KEYFILE_JSON"
20
21
  ]
22
+ <%- end -%>
21
23
  end
@@ -61,7 +61,7 @@ class <%= service.operations_name %>
61
61
  # Create credentials
62
62
  credentials = @config.credentials
63
63
  credentials ||= Credentials.default scope: @config.scope
64
- if credentials.is_a?(String) || credentials.is_a?(Hash)
64
+ if credentials.is_a?(::String) || credentials.is_a?(::Hash)
65
65
  credentials = Credentials.new credentials, scope: @config.scope
66
66
  end
67
67
  @quota_project_id = @config.quota_project
@@ -1,7 +1,7 @@
1
1
  <%- assert_locals service -%>
2
2
  # Path helper methods for the <%= service.name %> API.
3
3
  module Paths
4
- <%- service.references.each do |resource| -%>
4
+ <%- service.deduped_references.each do |resource| -%>
5
5
  <%= indent render(partial: "service/client/resource", locals: { resource: resource }), 2 %>
6
6
 
7
7
  <%- end %>
@@ -6,7 +6,7 @@
6
6
  default_config.timeout = <%= format_number service.grpc_service_config.timeout_seconds %>
7
7
  <%- end -%>
8
8
  <%- if service.grpc_service_config.retry_policy -%>
9
- default_config.retry_policy = <%= indent_tail render(partial: "service/client/self_configure_retry_policy", locals: { retry_policy: service.grpc_service_config.retry_policy }), 2 %>
9
+ default_config.retry_policy = <%= indent_tail service.service_config_presenter.retry_policy_fields, 2 %>
10
10
  <%- end -%>
11
11
  <%- end -%>
12
12
  <%- method_service.methods.each do |method| -%>
@@ -16,7 +16,7 @@
16
16
  default_config.rpcs.<%= method.name %>.timeout = <%= format_number method.grpc_service_config.timeout_seconds %>
17
17
  <%- end -%>
18
18
  <%- if method.grpc_service_config.retry_policy -%>
19
- default_config.rpcs.<%= method.name %>.retry_policy =<%= indent_tail render(partial: "service/client/self_configure_retry_policy", locals: { retry_policy: method.grpc_service_config.retry_policy }), 2 %>
19
+ default_config.rpcs.<%= method.name %>.retry_policy =<%= indent_tail method.service_config_presenter.retry_policy_fields, 2 %>
20
20
  <%- end -%>
21
21
  <%- end -%>
22
22
  <%- end -%>
@@ -4,12 +4,14 @@
4
4
  <%= indent method.doc_description, "# " %>
5
5
  #
6
6
  <%- end -%>
7
+ <%= render partial: "service/client/method/docs/deprecated", locals: { method: method } -%>
7
8
  <%= render partial: "service/client/method/docs/request", locals: { method: method } -%>
8
9
  #
9
10
  <%= render partial: "service/client/method/docs/response", locals: { method: method } -%>
10
11
  #
11
12
  <%= render partial: "service/client/method/docs/error", locals: { method: method } -%>
12
13
  #
14
+ <%= render partial: "service/client/method/docs/snippets", locals: { method: method } -%>
13
15
  <%= render partial: "service/client/method/docs/samples", locals: { method: method } -%>
14
16
  def <%= method.name %> request, options = nil
15
17
  <%= indent render(partial: "service/client/method/def/request", locals: { method: method }), 2 %>