gapic-generator 0.2.2 → 0.4.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -0
  3. data/lib/gapic/formatting_utils.rb +4 -2
  4. data/lib/gapic/generator/version.rb +1 -1
  5. data/lib/gapic/generators/default_generator.rb +11 -10
  6. data/lib/gapic/presenters/field_presenter.rb +1 -1
  7. data/lib/gapic/presenters/gem_presenter.rb +8 -2
  8. data/lib/gapic/presenters/method_presenter.rb +17 -2
  9. data/lib/gapic/presenters/package_presenter.rb +16 -1
  10. data/lib/gapic/presenters/resource_presenter.rb +3 -9
  11. data/lib/gapic/presenters/service_presenter.rb +57 -12
  12. data/lib/gapic/resource_lookup.rb +23 -45
  13. data/lib/gapic/ruby_info.rb +93 -0
  14. data/lib/gapic/schema/api.rb +102 -1
  15. data/lib/gapic/schema/loader.rb +9 -2
  16. data/lib/gapic/schema/wrappers.rb +109 -22
  17. data/templates/default/gem/entrypoint.erb +8 -0
  18. data/templates/default/gem/gemspec.erb +1 -1
  19. data/templates/default/gem/readme.erb +15 -1
  20. data/templates/default/gem/rubocop.erb +13 -41
  21. data/templates/default/lib/_package.erb +17 -0
  22. data/templates/default/lib/_service.erb +32 -0
  23. data/templates/default/package.erb +5 -5
  24. data/templates/default/service.erb +5 -7
  25. data/templates/default/service/_helpers.erb +3 -0
  26. data/templates/default/service/client.erb +1 -1
  27. data/templates/default/service/client/_client.erb +10 -16
  28. data/templates/default/service/client/_operations.erb +0 -4
  29. data/templates/default/service/client/_resource.erb +1 -1
  30. data/templates/default/service/client/method/docs/_request_normal.erb +10 -5
  31. data/templates/default/service/client/method/docs/_request_streaming.erb +1 -1
  32. data/templates/default/service/credentials.erb +1 -1
  33. data/templates/default/service/operations.erb +1 -1
  34. data/templates/default/service/paths.erb +1 -1
  35. data/templates/default/service/test/client.erb +16 -2
  36. data/templates/default/service/test/client_operations.erb +2 -2
  37. data/templates/default/service/test/method/_configure.erb +19 -0
  38. metadata +8 -3
  39. data/templates/default/service/client/_helpers.erb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c88e9ae5990030e6fd090eaebcc037a128121621b2be5442e12353985530f90
4
- data.tar.gz: 3dd8af72aecf6cb4b2b2fedf692e987bf8aa74c7484e40ee1de677020a141e0b
3
+ metadata.gz: 6eb09d3958e2bf3212a940df300ab29228dabdb7dabc31b1d9755eddee129c5b
4
+ data.tar.gz: e9431a7bc6f8680553e0bd682d68cdf6ec5fc61a6c564fec5c074f4884d362c9
5
5
  SHA512:
6
- metadata.gz: 0f508a5ab35d5a342c9f6a208bd888277cf82e3ba15215120b2bbdd71a01dff675fe54758e78e5f0a3240dfe3528aefcb120f7cb8b1caa9477f3f6dd5e6a9e5b
7
- data.tar.gz: c1188319beee864fa260f0c6ef5f2b9e34ec0b3778de3901cf544e8ab151075dfb450c45159cff4ae1c666c838f7b2ce105f5cb29c07cbe6f2ff9ff5f815f9ef
6
+ metadata.gz: 554bdbb8d1b6ca6dbfb646656cb91dc5f1080d60e8e7103771ca8e3352f09e33a0b9ef3edd86547c173cfc98e18d45da1be8b9648aef40525b1bfb13c5579d62
7
+ data.tar.gz: c998693373a980357d17d540fdbaa891959666bfb2b2dd12b2843eb9b8df0bca1808259305c25614a3951f695b004fa28b862888e1e9e4fa706ce6cfcd2b4f5f
@@ -1,5 +1,42 @@
1
1
  # Release History for gapic-generator
2
2
 
3
+ ### 0.4.0 / 2020-04-20
4
+
5
+ * Support generating clients of "common" interfaces by delegating to another service config.
6
+ * Added an accessor for the long-running-operation client from the main client.
7
+ * Generate tests for the configure method and operations client accessor.
8
+ * Prevent generation of RPC or factory methods with reserved names.
9
+ * Fixed: LRO clients weren't inheriting custom endpoints from the main client.
10
+ * Fixed: Cross-references weren't interpreted if the text included backticks, spaces, or hyphens.
11
+
12
+ ### 0.3.3 / 2020-04-13
13
+
14
+ * Fix cross-reference links to multi-word enum values.
15
+
16
+ ### 0.3.2 / 2020-04-12
17
+
18
+ * Fix the talent.v4beta1 hack.
19
+
20
+ ### 0.3.1 / 2020-04-11
21
+
22
+ * Disable ModuleLength metric for generated code.
23
+ * Omit nonconforming resource patterns instead of crashing.
24
+
25
+ ### 0.3.0 / 2020-04-10
26
+
27
+ * Detect when a resource is referenced implicitly via child_type, and generate path helpers.
28
+ * Update grpc-google-iam-v1 dependency to require the latest version.
29
+ * Generated require graph is more sane and does not include cycles.
30
+ * The bundler entrypoint now loads the entire gem for wrapper gems.
31
+ * Generated readmes are more useful and include a quickstart.
32
+ * Package and service modules now have basic documentation.
33
+ * Overloads for methods now have basic explanatory documentation, including how to pass an empty request.
34
+ * Request object documentation no longer duplicates the method documentation.
35
+
36
+ ### 0.2.3 / 2020-04-06
37
+
38
+ * No changes
39
+
3
40
  ### 0.2.2 / 2020-03-31
4
41
 
5
42
  * Updates to common protos, especially core types which were more than a year old.
@@ -22,7 +22,7 @@ module Gapic
22
22
  #
23
23
  module FormattingUtils
24
24
  @brace_detector = /\A(?<pre>[^`]*(`[^`]*`[^`]*)*[^`\\])?\{(?<inside>[^\s][^}]*)\}(?<post>.*)\z/m
25
- @xref_detector = /\A(?<pre>[^`]*(`[^`]*`[^`]*)*)?\[(?<text>[\w\.]+)\]\[(?<addr>[\w\.]+)\](?<post>.*)\z/m
25
+ @xref_detector = /\A(?<pre>[^`]*(`[^`]*`[^`]*)*)?\[(?<text>[\w\. `-]+)\]\[(?<addr>[\w\.]+)\](?<post>.*)\z/m
26
26
  @list_element_detector = /\A\s*(\*|\+|-|[0-9a-zA-Z]+\.)\s/
27
27
 
28
28
  class << self
@@ -140,8 +140,10 @@ module Gapic
140
140
  "{#{convert_address_to_ruby entity}::Client #{text}}"
141
141
  when Gapic::Schema::Method
142
142
  "{#{convert_address_to_ruby entity.parent}::Client##{entity.name.underscore} #{text}}"
143
- when Gapic::Schema::Message, Gapic::Schema::Enum, Gapic::Schema::EnumValue
143
+ when Gapic::Schema::Message, Gapic::Schema::Enum
144
144
  "{#{convert_address_to_ruby entity} #{text}}"
145
+ when Gapic::Schema::EnumValue
146
+ "{#{convert_address_to_ruby entity.parent}::#{entity.name} #{text}}"
145
147
  when Gapic::Schema::Field
146
148
  "{#{convert_address_to_ruby entity.parent}##{entity.name} #{text}}"
147
149
  end
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Gapic
18
18
  module Generator
19
- VERSION = "0.2.2"
19
+ VERSION = "0.4.0"
20
20
  end
21
21
  end
@@ -63,16 +63,17 @@ module Gapic
63
63
  end
64
64
 
65
65
  # Gem level files
66
- files << g("gem/gitignore.erb", ".gitignore", gem: gem)
67
- files << g("gem/version.erb", "lib/#{gem.version_file_path}", gem: gem)
68
- files << g("gem/gemspec.erb", "#{gem.name}.gemspec", gem: gem)
69
- files << g("gem/gemfile.erb", "Gemfile", gem: gem)
70
- files << g("gem/rakefile.erb", "Rakefile", gem: gem)
71
- files << g("gem/readme.erb", "README.md", gem: gem)
72
- files << g("gem/changelog.erb", "CHANGELOG.md", gem: gem)
73
- files << g("gem/rubocop.erb", ".rubocop.yml", gem: gem)
74
- files << g("gem/yardopts.erb", ".yardopts", gem: gem)
75
- files << g("gem/license.erb", "LICENSE.md", gem: gem)
66
+ files << g("gem/gitignore.erb", ".gitignore", gem: gem)
67
+ files << g("gem/version.erb", "lib/#{gem.version_file_path}", gem: gem)
68
+ files << g("gem/gemspec.erb", "#{gem.name}.gemspec", gem: gem)
69
+ files << g("gem/gemfile.erb", "Gemfile", gem: gem)
70
+ files << g("gem/rakefile.erb", "Rakefile", gem: gem)
71
+ files << g("gem/readme.erb", "README.md", gem: gem)
72
+ files << g("gem/changelog.erb", "CHANGELOG.md", gem: gem)
73
+ files << g("gem/rubocop.erb", ".rubocop.yml", gem: gem)
74
+ files << g("gem/yardopts.erb", ".yardopts", gem: gem)
75
+ files << g("gem/license.erb", "LICENSE.md", gem: gem)
76
+ files << g("gem/entrypoint.erb", "lib/#{gem.name}.rb", gem: gem)
76
77
 
77
78
  gem.proto_files.each do |proto_file|
78
79
  files << g("proto_docs/proto_file.erb", "proto_docs/#{proto_file.docs_file_path}", file: proto_file)
@@ -95,7 +95,7 @@ module Gapic
95
95
  base_type =
96
96
  if field.message?
97
97
  type = message_ruby_type field.message
98
- output ? type : "#{type} | Hash"
98
+ output ? type : "#{type}, Hash"
99
99
  elsif field.enum?
100
100
  # TODO: handle when arg message is nil and enum is the type
101
101
  message_ruby_type field.enum
@@ -37,6 +37,10 @@ module Gapic
37
37
  end
38
38
  end
39
39
 
40
+ def packages?
41
+ !packages.empty?
42
+ end
43
+
40
44
  def services
41
45
  @services ||= begin
42
46
  files = @api.generate_files
@@ -134,11 +138,13 @@ module Gapic
134
138
  end
135
139
 
136
140
  def free_tier?
137
- gem_config(:free_tier) ? true : false
141
+ # Default to false unless the config is explicitly set to "true"
142
+ gem_config(:free_tier) == "true"
138
143
  end
139
144
 
140
145
  def yard_strict?
141
- gem_config(:yard_strict) ? true : false
146
+ # Default to true unless the config is explicitly set to "false"
147
+ gem_config(:yard_strict) != "false"
142
148
  end
143
149
 
144
150
  def entrypoint_require
@@ -16,6 +16,7 @@
16
16
 
17
17
  require "active_support/inflector"
18
18
  require "gapic/path_template"
19
+ require "gapic/ruby_info"
19
20
  require "gapic/helpers/namespace_helper"
20
21
 
21
22
  module Gapic
@@ -36,7 +37,11 @@ module Gapic
36
37
  end
37
38
 
38
39
  def name
39
- ActiveSupport::Inflector.underscore @method.name
40
+ @name ||= begin
41
+ candidate = ActiveSupport::Inflector.underscore @method.name
42
+ candidate = "call_#{candidate}" if Gapic::RubyInfo.excluded_method_names.include? candidate
43
+ candidate
44
+ end
40
45
  end
41
46
 
42
47
  def kind
@@ -160,6 +165,16 @@ module Gapic
160
165
 
161
166
  def paged?
162
167
  return false if server_streaming? # Cannot page a streaming response
168
+
169
+ # HACK(dazuma, 2020-04-06): Two specific RPCs should not be paged.
170
+ # This is an intentionally hard-coded exception (and a temporary one,
171
+ # to be removed when these methods no longer conform to AIP-4233.) For
172
+ # detailed information, see internal link go/actools-talent-pagination.
173
+ address = @method.address.join "."
174
+ return false if address == "google.cloud.talent.v4beta1.ProfileService.SearchProfiles"
175
+ return false if address == "google.cloud.talent.v4beta1.JobService.SearchJobs"
176
+ return false if address == "google.cloud.talent.v4beta1.JobService.SearchJobsForAlert"
177
+
163
178
  paged_request?(@method.input) && paged_response?(@method.output)
164
179
  end
165
180
 
@@ -205,7 +220,7 @@ module Gapic
205
220
 
206
221
  def doc_types_for arg
207
222
  if arg.message?
208
- "#{message_ruby_type arg.message} | Hash"
223
+ "#{message_ruby_type arg.message}, Hash"
209
224
  elsif arg.enum?
210
225
  # TODO: handle when arg message is nil and enum is the type
211
226
  message_ruby_type arg.enum
@@ -45,10 +45,25 @@ module Gapic
45
45
  ruby_namespace_for_address address
46
46
  end
47
47
 
48
+ def parent_namespace
49
+ namespace.split("::")[0...-1].join("::")
50
+ end
51
+
52
+ def module_name
53
+ namespace.split("::").last
54
+ end
55
+
56
+ # Services whose clients should be generated in this package namespace.
48
57
  def services
49
58
  @services ||= begin
50
59
  files = @api.generate_files.select { |f| f.package == @package }
51
- files.map(&:services).flatten.map { |s| ServicePresenter.new @api, s }
60
+ services = files.map(&:services).flatten
61
+ # Omit common services in this package. Common service clients do not
62
+ # go into their own package.
63
+ normal_services = services.select { |s| @api.delegate_service_for(s).nil? }
64
+ # But include common services that delegate to normal services in this package.
65
+ common_services = normal_services.flat_map { |s| @api.common_services_for s }
66
+ (normal_services + common_services).map { |s| ServicePresenter.new @api, s }
52
67
  end
53
68
  end
54
69
 
@@ -38,15 +38,9 @@ module Gapic
38
38
  )
39
39
  end
40
40
 
41
- @patterns.each do |pattern|
42
- # URI path template verification for expected proto resource usage
43
- if named_arg_patterns? pattern.segments
44
- raise ArgumentError, "only resources without named patterns are supported, " \
45
- " not #{pattern.template}"
46
- elsif positional_args? pattern.segments
47
- raise ArgumentError, "only resources with named segments are supported, " \
48
- " not #{pattern.template}"
49
- end
41
+ # Keep only patterns that can be used to create path helpers
42
+ @patterns.reject! do |pattern|
43
+ named_arg_patterns?(pattern.segments) || positional_args?(pattern.segments)
50
44
  end
51
45
  end
52
46
 
@@ -55,7 +55,25 @@ module Gapic
55
55
  @service.address
56
56
  end
57
57
 
58
+ # Returns a presenter for this service's delegate (if it is a common service)
59
+ # otherwise returns `nil`.
60
+ def common_service_delegate
61
+ unless defined? @common_service_delegate
62
+ delegate = @api.delegate_service_for @service
63
+ @common_service_delegate = delegate ? ServicePresenter.new(@api, delegate) : nil
64
+ end
65
+ @common_service_delegate
66
+ end
67
+
68
+ # The namespace of the client. Normally this is the version module. This
69
+ # may be different from the proto namespace for a common service.
58
70
  def namespace
71
+ # If this service is a common service, its client should go into its
72
+ # delegate's namespace rather than its own. For example, KMS includes
73
+ # the common IAMPolicy service, but that service's client should go
74
+ # into the KMS namespace.
75
+ return common_service_delegate.namespace if common_service_delegate
76
+
59
77
  return @service.ruby_package if @service.ruby_package.present?
60
78
 
61
79
  namespace = ruby_namespace_for_address @service.address[0...-1]
@@ -74,8 +92,22 @@ module Gapic
74
92
  @service.name
75
93
  end
76
94
 
95
+ # The namespace of the protos. This may be different from the client
96
+ # namespace for a common service.
97
+ def proto_namespace
98
+ return @service.ruby_package if @service.ruby_package.present?
99
+
100
+ namespace = ruby_namespace_for_address @service.address[0...-1]
101
+ @api.override_proto_namespaces? ? fix_namespace(@api, namespace) : namespace
102
+ end
103
+
77
104
  def proto_service_name_full
78
- fix_namespace @api, "#{namespace}::#{name}"
105
+ name_full = "#{proto_namespace}::#{name}"
106
+ @api.override_proto_namespaces? ? fix_namespace(@api, name_full) : name_full
107
+ end
108
+
109
+ def module_name
110
+ service_name_full.split("::").last
79
111
  end
80
112
 
81
113
  def proto_service_file_path
@@ -106,6 +138,10 @@ module Gapic
106
138
  "#{proto_service_name_full}::Stub"
107
139
  end
108
140
 
141
+ def service_name_full
142
+ fix_namespace @api, "#{namespace}::#{name}"
143
+ end
144
+
109
145
  def service_file_path
110
146
  service_require + ".rb"
111
147
  end
@@ -114,8 +150,12 @@ module Gapic
114
150
  service_file_path.split("/").last
115
151
  end
116
152
 
153
+ def service_directory_name
154
+ service_require.split("/").last
155
+ end
156
+
117
157
  def service_require
118
- ruby_file_path @api, proto_service_name_full
158
+ ruby_file_path @api, service_name_full
119
159
  end
120
160
 
121
161
  def client_name
@@ -123,7 +163,7 @@ module Gapic
123
163
  end
124
164
 
125
165
  def client_name_full
126
- fix_namespace @api, "#{proto_service_name_full}::#{client_name}"
166
+ fix_namespace @api, "#{service_name_full}::#{client_name}"
127
167
  end
128
168
 
129
169
  def create_client_call
@@ -147,12 +187,17 @@ module Gapic
147
187
  end
148
188
 
149
189
  def client_endpoint
150
- return @parent_service.client_endpoint if @parent_service
151
- @service.host || default_config(:default_host) || "localhost"
190
+ @parent_service&.client_endpoint ||
191
+ common_service_delegate&.client_endpoint ||
192
+ @service.host ||
193
+ default_config(:default_host) ||
194
+ "localhost"
152
195
  end
153
196
 
154
197
  def client_scopes
155
- @service.scopes || default_config(:oauth_scopes)
198
+ common_service_delegate&.client_scopes ||
199
+ @service.scopes ||
200
+ default_config(:oauth_scopes)
156
201
  end
157
202
 
158
203
  def client_proto_name
@@ -164,7 +209,7 @@ module Gapic
164
209
  end
165
210
 
166
211
  def credentials_name_full
167
- fix_namespace @api, "#{proto_service_name_full}::#{credentials_name}"
212
+ fix_namespace @api, "#{service_name_full}::#{credentials_name}"
168
213
  end
169
214
 
170
215
  def credentials_class_xref
@@ -192,7 +237,7 @@ module Gapic
192
237
  end
193
238
 
194
239
  def helpers_require
195
- ruby_file_path @api, "#{proto_service_name_full}::Helpers"
240
+ ruby_file_path @api, "#{service_name_full}::Helpers"
196
241
  end
197
242
 
198
243
  def references
@@ -208,7 +253,7 @@ module Gapic
208
253
  end
209
254
 
210
255
  def paths_name_full
211
- fix_namespace @api, "#{proto_service_name_full}::#{paths_name}"
256
+ fix_namespace @api, "#{service_name_full}::#{paths_name}"
212
257
  end
213
258
 
214
259
  def paths_file_path
@@ -220,7 +265,7 @@ module Gapic
220
265
  end
221
266
 
222
267
  def paths_require
223
- ruby_file_path @api, "#{proto_service_name_full}::#{paths_name}"
268
+ ruby_file_path @api, "#{service_name_full}::#{paths_name}"
224
269
  end
225
270
 
226
271
  def test_client_file_path
@@ -252,7 +297,7 @@ module Gapic
252
297
  end
253
298
 
254
299
  def operations_name_full
255
- fix_namespace @api, "#{proto_service_name_full}::#{operations_name}"
300
+ fix_namespace @api, "#{service_name_full}::#{operations_name}"
256
301
  end
257
302
 
258
303
  def operations_file_path
@@ -264,7 +309,7 @@ module Gapic
264
309
  end
265
310
 
266
311
  def operations_require
267
- ruby_file_path @api, "#{proto_service_name_full}::#{operations_name}"
312
+ ruby_file_path @api, "#{service_name_full}::#{operations_name}"
268
313
  end
269
314
 
270
315
  def lro_service
@@ -26,64 +26,42 @@ module Gapic
26
26
 
27
27
  # @private
28
28
  def lookup!
29
- resources = @api.files.flat_map { |file| lookup_file_resource_descriptors file }
30
- resources.compact.uniq
31
- end
32
-
33
- # @private
34
- def lookup_file_resource_descriptors file
35
29
  resources = []
36
- resources += file.resources.select { |resource| service_resource_types.include? resource.type }
37
- resources += file.messages.flat_map { |message| lookup_message_resources_descriptors message }
38
- resources
39
- end
40
-
41
- # @private
42
- def service_resource_types
43
- @service_resource_types ||= begin
44
- @service.methods.flat_map do |method|
45
- input_resource_types = message_resource_types method.input
46
-
47
- if @api.generate_path_helpers_output?
48
- output_resource_types = message_resource_types method.output
49
- input_resource_types + output_resource_types
50
- else
51
- input_resource_types
52
- end
53
- end.uniq
30
+ @service.methods.each do |method|
31
+ resources.concat resources_for_message(method.input)
32
+ resources.concat resources_for_message(method.output) if @api.generate_path_helpers_output?
54
33
  end
34
+ resources.uniq
55
35
  end
56
36
 
57
37
  # @private
58
- def message_resource_types message, seen_messages = []
59
- return [] if seen_messages.include? message
38
+ def resources_for_message message, seen_messages = []
39
+ resources = []
40
+ return resources if seen_messages.include? message
60
41
  seen_messages << message
61
- resource_types = []
62
- resource_types << message.resource.type if message.resource
63
- resource_types += message.nested_messages.map do |nested_message|
64
- message_resource_types nested_message, seen_messages
42
+ resources << message.resource if message.resource
43
+ message.nested_messages.each do |nested_message|
44
+ resources.concat resources_for_message(nested_message, seen_messages)
65
45
  end
66
46
  message.fields.each do |field|
67
- resource_types << field.resource_reference.type if field.resource_reference
68
- resource_types += message_resource_types field.message, seen_messages if field.message?
47
+ resources.concat resources_for_reference(field.resource_reference) if field.resource_reference
48
+ resources.concat resources_for_message(field.message, seen_messages) if field.message?
69
49
  end
70
- resource_types.flatten
50
+ resources
71
51
  end
72
52
 
73
53
  # @private
74
- def lookup_message_resources_descriptors message
75
- resources = []
76
-
77
- # We don't expect service_resource_types to iclude nil, so we can use message.resource&.type
78
- resources << message.resource if service_resource_types.include? message.resource&.type
79
-
80
- if message.nested_messages
81
- resources += message.nested_messages.flat_map do |nested_message|
82
- lookup_message_resources_descriptors nested_message
83
- end
54
+ # Given a reference (either a type or child type), return the corresponding
55
+ # resources.
56
+ def resources_for_reference reference
57
+ if (type = reference.type) && !type.empty?
58
+ Array(@api.lookup_resource_type(type))
59
+ elsif (child_type = reference.child_type) && !child_type.empty?
60
+ child_resource = @api.lookup_resource_type child_type
61
+ child_resource ? child_resource.parent_resources : []
62
+ else
63
+ []
84
64
  end
85
-
86
- resources
87
65
  end
88
66
 
89
67
  # Lookup all resources for a given service.