gapic-generator 0.2.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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.