gapic-generator 0.4.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/lib/gapic/file_formatter.rb +0 -1
  4. data/lib/gapic/formatting_utils.rb +6 -6
  5. data/lib/gapic/generator/version.rb +1 -1
  6. data/lib/gapic/generators/default_generator.rb +16 -14
  7. data/lib/gapic/helpers/filepath_helper.rb +1 -0
  8. data/lib/gapic/helpers/namespace_helper.rb +8 -1
  9. data/lib/gapic/{path_template.rb → path_pattern.rb} +9 -8
  10. data/lib/gapic/path_pattern/parser.rb +146 -0
  11. data/lib/gapic/path_pattern/pattern.rb +80 -0
  12. data/lib/gapic/path_pattern/segment.rb +276 -0
  13. data/lib/gapic/presenters/field_presenter.rb +9 -9
  14. data/lib/gapic/presenters/file_presenter.rb +1 -1
  15. data/lib/gapic/presenters/gem_presenter.rb +39 -3
  16. data/lib/gapic/presenters/method_presenter.rb +19 -19
  17. data/lib/gapic/presenters/package_presenter.rb +4 -3
  18. data/lib/gapic/presenters/resource_presenter.rb +48 -36
  19. data/lib/gapic/presenters/service_presenter.rb +20 -14
  20. data/lib/gapic/schema/api.rb +7 -0
  21. data/lib/gapic/schema/wrappers.rb +13 -19
  22. data/lib/gapic/uri_template.rb +36 -0
  23. data/lib/gapic/uri_template/parser.rb +50 -0
  24. data/templates/default/gem/gemfile.erb +3 -0
  25. data/templates/default/gem/gemspec.erb +7 -6
  26. data/templates/default/gem/rakefile.erb +1 -0
  27. data/templates/default/gem/test_helper.erb +8 -0
  28. data/templates/default/layouts/_ruby.erb +5 -4
  29. data/templates/default/lib/_service.erb +2 -0
  30. data/templates/default/proto_docs/_message.erb +2 -2
  31. data/templates/default/service/client/_client.erb +7 -4
  32. data/templates/default/service/client/_config.erb +33 -29
  33. data/templates/default/service/client/_credentials.erb +1 -1
  34. data/templates/default/service/client/_operations.erb +3 -1
  35. data/templates/default/service/client/method/def/_options_defaults.erb +2 -2
  36. data/templates/default/service/client/method/def/_request_normal.erb +2 -2
  37. data/templates/default/service/client/method/def/_request_streaming.erb +3 -3
  38. data/templates/default/service/client/method/def/_response_normal.erb +1 -1
  39. data/templates/default/service/client/method/def/_response_paged.erb +2 -2
  40. data/templates/default/service/client/method/docs/_error.erb +1 -1
  41. data/templates/default/service/client/method/docs/_request_normal.erb +2 -2
  42. data/templates/default/service/client/method/docs/_request_streaming.erb +2 -2
  43. data/templates/default/service/client/method/docs/_response.erb +1 -1
  44. data/templates/default/service/client/resource/_def.erb +1 -1
  45. data/templates/default/service/client/resource/_doc.erb +1 -1
  46. data/templates/default/service/client/resource/_multi.erb +4 -7
  47. data/templates/default/service/client/resource/_single.erb +2 -3
  48. data/templates/default/service/test/_resource.erb +16 -0
  49. data/templates/default/service/test/client.erb +2 -5
  50. data/templates/default/service/test/client_operations.erb +2 -5
  51. data/templates/default/service/test/client_paths.erb +15 -0
  52. metadata +12 -6
  53. data/lib/gapic/path_template/parser.rb +0 -83
  54. data/lib/gapic/path_template/segment.rb +0 -67
@@ -95,21 +95,21 @@ 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
102
102
  else
103
103
  case field.type
104
- when 1, 2 then "Float"
105
- when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "Integer"
106
- when 9, 12 then "String"
107
- when 8 then "Boolean"
104
+ when 1, 2 then "::Float"
105
+ when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "::Integer"
106
+ when 9, 12 then "::String"
107
+ when 8 then "::Boolean"
108
108
  else
109
- "Object"
109
+ "::Object"
110
110
  end
111
111
  end
112
- field.repeated? ? "Array<#{base_type}>" : base_type
112
+ field.repeated? ? "::Array<#{base_type}>" : base_type
113
113
  end
114
114
 
115
115
  def field_map_type entry_message, output
@@ -118,7 +118,7 @@ module Gapic
118
118
  key_field = field if field.name == "key"
119
119
  value_field = field if field.name == "value"
120
120
  end
121
- class_name = output ? "Google::Protobuf::Map" : "Hash"
121
+ class_name = output ? "::Google::Protobuf::Map" : "::Hash"
122
122
  if key_field && value_field
123
123
  key_type = field_doc_types key_field, output
124
124
  value_type = field_doc_types value_field, output
@@ -141,7 +141,7 @@ module Gapic
141
141
  when 9, 12 then "\"hello world\""
142
142
  when 8 then "true"
143
143
  else
144
- "Object"
144
+ "::Object"
145
145
  end
146
146
  end
147
147
  end
@@ -39,7 +39,7 @@ module Gapic
39
39
  end
40
40
 
41
41
  def namespace
42
- return @file.ruby_package if @file.ruby_package.present?
42
+ return ensure_absolute_namespace @file.ruby_package if @file.ruby_package.present?
43
43
  ruby_namespace_for_address address
44
44
  end
45
45
 
@@ -33,7 +33,7 @@ module Gapic
33
33
  def packages
34
34
  @packages ||= begin
35
35
  packages = @api.generate_files.map(&:package).uniq.sort
36
- packages.map { |p| PackagePresenter.new @api, p }.delete_if(&:empty?)
36
+ packages.map { |p| PackagePresenter.new self, @api, p }.delete_if(&:empty?)
37
37
  end
38
38
  end
39
39
 
@@ -44,7 +44,7 @@ module Gapic
44
44
  def services
45
45
  @services ||= begin
46
46
  files = @api.generate_files
47
- files.map(&:services).flatten.map { |s| ServicePresenter.new @api, s }
47
+ files.map(&:services).flatten.map { |s| ServicePresenter.new self, @api, s }
48
48
  end
49
49
  end
50
50
 
@@ -134,7 +134,17 @@ module Gapic
134
134
  end
135
135
 
136
136
  def api_id
137
- gem_config :api_id
137
+ raw_id = gem_config :api_id
138
+ return nil unless raw_id
139
+ raw_id.include?(".") ? raw_id : "#{raw_id}.googleapis.com"
140
+ end
141
+
142
+ def api_shortname
143
+ gem_config :api_shortname
144
+ end
145
+
146
+ def issue_tracker_url
147
+ gem_config :issue_tracker_url
138
148
  end
139
149
 
140
150
  def free_tier?
@@ -147,10 +157,36 @@ module Gapic
147
157
  gem_config(:yard_strict) != "false"
148
158
  end
149
159
 
160
+ def generic_endpoint?
161
+ gem_config(:generic_endpoint) == "true"
162
+ end
163
+
150
164
  def entrypoint_require
151
165
  packages.first.package_require
152
166
  end
153
167
 
168
+ def license_name
169
+ "MIT"
170
+ end
171
+
172
+ def extra_files
173
+ ["README.md", "LICENSE.md", ".yardopts"]
174
+ end
175
+
176
+ def dependencies
177
+ deps = { "gapic-common" => "~> 0.2" }
178
+ deps["grpc-google-iam-v1"] = [">= 0.6.10", "< 2.0"] if iam_dependency?
179
+ extra_deps = gem_config :extra_dependencies
180
+ deps.merge! extra_deps if extra_deps
181
+ deps
182
+ end
183
+
184
+ def dependency_list
185
+ dependencies.to_a
186
+ .map { |name, requirements| [name, Array(requirements)] }
187
+ .sort_by { |name, _requirements| name }
188
+ end
189
+
154
190
  private
155
191
 
156
192
  def gem_config key
@@ -15,7 +15,7 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "active_support/inflector"
18
- require "gapic/path_template"
18
+ require "gapic/uri_template"
19
19
  require "gapic/ruby_info"
20
20
  require "gapic/helpers/namespace_helper"
21
21
 
@@ -27,13 +27,14 @@ module Gapic
27
27
  class MethodPresenter
28
28
  include Gapic::Helpers::NamespaceHelper
29
29
 
30
- def initialize api, method
30
+ def initialize service_presenter, api, method
31
+ @service_presenter = service_presenter
31
32
  @api = api
32
33
  @method = method
33
34
  end
34
35
 
35
36
  def service
36
- ServicePresenter.new @api, @method.parent
37
+ @service_presenter
37
38
  end
38
39
 
39
40
  def name
@@ -64,13 +65,13 @@ module Gapic
64
65
 
65
66
  def doc_response_type
66
67
  ret = return_type
67
- ret = "Gapic::Operation" if lro?
68
+ ret = "::Gapic::Operation" if lro?
68
69
  if server_streaming?
69
- ret = "Enumerable<#{ret}>"
70
+ ret = "::Enumerable<#{ret}>"
70
71
  elsif paged?
71
72
  paged_type = paged_response_type
72
- paged_type = "Gapic::Operation" if paged_type == "Google::Longrunning::Operation"
73
- ret = "Gapic::PagedEnumerable<#{paged_type}>"
73
+ paged_type = "::Gapic::Operation" if paged_type == "::Google::Longrunning::Operation"
74
+ ret = "::Gapic::PagedEnumerable<#{paged_type}>"
74
75
  end
75
76
  ret
76
77
  end
@@ -123,7 +124,7 @@ module Gapic
123
124
  return [
124
125
  OpenStruct.new(
125
126
  name: "operation",
126
- doc_types: "Gapic::Operation"
127
+ doc_types: "::Gapic::Operation"
127
128
  )
128
129
  ]
129
130
  end
@@ -134,7 +135,7 @@ module Gapic
134
135
  ),
135
136
  OpenStruct.new(
136
137
  name: "operation",
137
- doc_types: "GRPC::ActiveCall::Operation"
138
+ doc_types: "::GRPC::ActiveCall::Operation"
138
139
  )
139
140
  ]
140
141
  end
@@ -150,9 +151,9 @@ module Gapic
150
151
  end
151
152
 
152
153
  def lro?
153
- return paged_response_type == "Google::Longrunning::Operation" if paged?
154
+ return paged_response_type == "::Google::Longrunning::Operation" if paged?
154
155
 
155
- message_ruby_type(@method.output) == "Google::Longrunning::Operation"
156
+ message_ruby_type(@method.output) == "::Google::Longrunning::Operation"
156
157
  end
157
158
 
158
159
  def client_streaming?
@@ -193,8 +194,7 @@ module Gapic
193
194
  # @return [Array<String>] The segment key names.
194
195
  #
195
196
  def routing_params
196
- segments = Gapic::PathTemplate.parse method_path
197
- segments.select { |s| s.is_a? Gapic::PathTemplate::Segment }.map(&:name)
197
+ Gapic::UriTemplate.parse_arguments method_path
198
198
  end
199
199
 
200
200
  def routing_params?
@@ -226,12 +226,12 @@ module Gapic
226
226
  message_ruby_type arg.enum
227
227
  else
228
228
  case arg.type
229
- when 1, 2 then "Float"
230
- when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "Integer"
231
- when 9, 12 then "String"
232
- when 8 then "Boolean"
229
+ when 1, 2 then "::Float"
230
+ when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "::Integer"
231
+ when 9, 12 then "::String"
232
+ when 8 then "::Boolean"
233
233
  else
234
- "Object"
234
+ "::Object"
235
235
  end
236
236
  end
237
237
  end
@@ -256,7 +256,7 @@ module Gapic
256
256
  when 9, 12 then "\"hello world\""
257
257
  when 8 then "true"
258
258
  else
259
- "Object"
259
+ "::Object"
260
260
  end
261
261
  end
262
262
  end
@@ -27,13 +27,14 @@ module Gapic
27
27
  include Gapic::Helpers::FilepathHelper
28
28
  include Gapic::Helpers::NamespaceHelper
29
29
 
30
- def initialize api, package
30
+ def initialize gem_presenter, api, package
31
+ @gem_presenter = gem_presenter
31
32
  @api = api
32
33
  @package = package
33
34
  end
34
35
 
35
36
  def gem
36
- GemPresenter.new @api
37
+ @gem_presenter
37
38
  end
38
39
 
39
40
  def name
@@ -63,7 +64,7 @@ module Gapic
63
64
  normal_services = services.select { |s| @api.delegate_service_for(s).nil? }
64
65
  # But include common services that delegate to normal services in this package.
65
66
  common_services = normal_services.flat_map { |s| @api.common_services_for s }
66
- (normal_services + common_services).map { |s| ServicePresenter.new @api, s }
67
+ (normal_services + common_services).map { |s| ServicePresenter.new @gem_presenter, @api, s }
67
68
  end
68
69
  end
69
70
 
@@ -14,8 +14,7 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- require "gapic/path_template"
18
- require "ostruct"
17
+ require "gapic/path_pattern"
19
18
  require "active_support/inflector"
20
19
 
21
20
  module Gapic
@@ -28,20 +27,10 @@ module Gapic
28
27
  def initialize resource
29
28
  @resource = resource
30
29
 
31
- @patterns = resource.pattern.map do |template|
32
- segments = Gapic::PathTemplate.parse template
33
- OpenStruct.new(
34
- template: template,
35
- segments: segments,
36
- arguments: arguments_for(segments),
37
- path_string: path_string_for(segments)
38
- )
39
- end
30
+ @patterns = resource.pattern.map { |pattern| PatternPresenter.new pattern }
40
31
 
41
32
  # 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)
44
- end
33
+ @patterns.filter!(&:useful_for_helpers?)
45
34
  end
46
35
 
47
36
  def name
@@ -60,33 +49,56 @@ module Gapic
60
49
  "#{ActiveSupport::Inflector.underscore name}_path"
61
50
  end
62
51
 
63
- private
52
+ ##
53
+ # A presenter for a particular pattern
54
+ #
55
+ class PatternPresenter
56
+ def initialize pattern_string
57
+ @pattern = pattern_string
58
+ @parsed_pattern = Gapic::PathPattern.parse pattern_string
59
+ @path_string = build_path_string
60
+ end
64
61
 
65
- def arguments_for segments
66
- arg_segments(segments).map(&:name)
67
- end
62
+ attr_reader :pattern, :path_string
68
63
 
69
- def arg_segments segments
70
- segments.select { |segment| segment.is_a? Gapic::PathTemplate::Segment }
71
- end
64
+ def useful_for_helpers?
65
+ !@parsed_pattern.positional_segments? && !@parsed_pattern.nontrivial_pattern_segments?
66
+ end
72
67
 
73
- def path_string_for segments
74
- segments.map do |segment|
75
- if segment.is_a? Gapic::PathTemplate::Segment
76
- "\#{#{segment.name}}"
77
- else
78
- # Should be a String
79
- segment
80
- end
81
- end.join
82
- end
68
+ def arguments
69
+ @parsed_pattern.arguments
70
+ end
83
71
 
84
- def positional_args? segments
85
- arg_segments(segments).any?(&:positional?)
86
- end
72
+ def formal_arguments
73
+ @parsed_pattern.arguments.map { |name| "#{name}:" }.join ", "
74
+ end
75
+
76
+ def arguments_key
77
+ @parsed_pattern.arguments.sort.join ":"
78
+ end
79
+
80
+ def arguments_with_dummy_values
81
+ @parsed_pattern.arguments.each_with_index.map { |name, index| "#{name}: \"value#{index}\"" }.join ", "
82
+ end
87
83
 
88
- def named_arg_patterns? segments
89
- arg_segments(segments).any?(&:pattern)
84
+ def expected_path_for_dummy_values
85
+ index = 0
86
+ @parsed_pattern.segments.map do |segment|
87
+ if segment.provides_arguments?
88
+ segment_dummy_path = segment.expected_path_for_dummy_values index
89
+ index += segment.arguments.length
90
+ segment_dummy_path
91
+ else
92
+ segment.pattern
93
+ end
94
+ end.join "/"
95
+ end
96
+
97
+ private
98
+
99
+ def build_path_string
100
+ @parsed_pattern.segments.map(&:path_string).join "/"
101
+ end
90
102
  end
91
103
  end
92
104
  end
@@ -27,14 +27,15 @@ module Gapic
27
27
  include Gapic::Helpers::FilepathHelper
28
28
  include Gapic::Helpers::NamespaceHelper
29
29
 
30
- def initialize api, service, parent_service: nil
30
+ def initialize gem_presenter, api, service, parent_service: nil
31
+ @gem_presenter = gem_presenter
31
32
  @api = api
32
33
  @service = service
33
34
  @parent_service = parent_service
34
35
  end
35
36
 
36
37
  def gem
37
- GemPresenter.new @api
38
+ @gem_presenter
38
39
  end
39
40
 
40
41
  def file
@@ -42,12 +43,12 @@ module Gapic
42
43
  end
43
44
 
44
45
  def package
45
- PackagePresenter.new @api, @service.parent.package
46
+ PackagePresenter.new @gem_presenter, @api, @service.parent.package
46
47
  end
47
48
 
48
49
  def methods
49
50
  @methods ||= begin
50
- @service.methods.map { |m| MethodPresenter.new @api, m }
51
+ @service.methods.map { |m| MethodPresenter.new self, @api, m }
51
52
  end
52
53
  end
53
54
 
@@ -60,7 +61,7 @@ module Gapic
60
61
  def common_service_delegate
61
62
  unless defined? @common_service_delegate
62
63
  delegate = @api.delegate_service_for @service
63
- @common_service_delegate = delegate ? ServicePresenter.new(@api, delegate) : nil
64
+ @common_service_delegate = delegate ? ServicePresenter.new(@gem_presenter, @api, delegate) : nil
64
65
  end
65
66
  @common_service_delegate
66
67
  end
@@ -74,7 +75,7 @@ module Gapic
74
75
  # into the KMS namespace.
75
76
  return common_service_delegate.namespace if common_service_delegate
76
77
 
77
- return @service.ruby_package if @service.ruby_package.present?
78
+ return ensure_absolute_namespace @service.ruby_package if @service.ruby_package.present?
78
79
 
79
80
  namespace = ruby_namespace_for_address @service.address[0...-1]
80
81
  fix_namespace @api, namespace
@@ -89,20 +90,20 @@ module Gapic
89
90
  end
90
91
 
91
92
  def name
92
- @service.name
93
+ @api.fix_service_name @service.name
93
94
  end
94
95
 
95
96
  # The namespace of the protos. This may be different from the client
96
97
  # namespace for a common service.
97
98
  def proto_namespace
98
- return @service.ruby_package if @service.ruby_package.present?
99
+ return ensure_absolute_namespace @service.ruby_package if @service.ruby_package.present?
99
100
 
100
101
  namespace = ruby_namespace_for_address @service.address[0...-1]
101
102
  @api.override_proto_namespaces? ? fix_namespace(@api, namespace) : namespace
102
103
  end
103
104
 
104
105
  def proto_service_name_full
105
- name_full = "#{proto_namespace}::#{name}"
106
+ name_full = "#{proto_namespace}::#{@service.name}"
106
107
  @api.override_proto_namespaces? ? fix_namespace(@api, name_full) : name_full
107
108
  end
108
109
 
@@ -187,6 +188,7 @@ module Gapic
187
188
  end
188
189
 
189
190
  def client_endpoint
191
+ return nil if generic_endpoint?
190
192
  @parent_service&.client_endpoint ||
191
193
  common_service_delegate&.client_endpoint ||
192
194
  @service.host ||
@@ -194,16 +196,16 @@ module Gapic
194
196
  "localhost"
195
197
  end
196
198
 
199
+ def generic_endpoint?
200
+ gem.generic_endpoint?
201
+ end
202
+
197
203
  def client_scopes
198
204
  common_service_delegate&.client_scopes ||
199
205
  @service.scopes ||
200
206
  default_config(:oauth_scopes)
201
207
  end
202
208
 
203
- def client_proto_name
204
- @service.address.join "."
205
- end
206
-
207
209
  def credentials_name
208
210
  "Credentials"
209
211
  end
@@ -272,6 +274,10 @@ module Gapic
272
274
  service_file_path.sub ".rb", "_test.rb"
273
275
  end
274
276
 
277
+ def test_paths_file_path
278
+ service_file_path.sub ".rb", "_paths_test.rb"
279
+ end
280
+
275
281
  def test_client_operations_file_path
276
282
  service_file_path.sub ".rb", "_operations_test.rb"
277
283
  end
@@ -314,7 +320,7 @@ module Gapic
314
320
 
315
321
  def lro_service
316
322
  lro = @service.parent.parent.files.find { |file| file.name == "google/longrunning/operations.proto" }
317
- return ServicePresenter.new @api, lro.services.first, parent_service: self unless lro.nil?
323
+ return ServicePresenter.new @gem_presenter, @api, lro.services.first, parent_service: self unless lro.nil?
318
324
  end
319
325
 
320
326
  def config_channel_args