gapic-generator 0.3.3 → 0.6.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/lib/gapic/formatting_utils.rb +7 -7
  4. data/lib/gapic/generator/version.rb +1 -1
  5. data/lib/gapic/generators/default_generator.rb +16 -14
  6. data/lib/gapic/helpers/filepath_helper.rb +1 -0
  7. data/lib/gapic/helpers/namespace_helper.rb +8 -1
  8. data/lib/gapic/path_template/segment.rb +7 -0
  9. data/lib/gapic/presenters/field_presenter.rb +9 -9
  10. data/lib/gapic/presenters/file_presenter.rb +1 -1
  11. data/lib/gapic/presenters/gem_presenter.rb +28 -2
  12. data/lib/gapic/presenters/method_presenter.rb +23 -17
  13. data/lib/gapic/presenters/package_presenter.rb +11 -3
  14. data/lib/gapic/presenters/resource_presenter.rb +55 -35
  15. data/lib/gapic/presenters/service_presenter.rb +66 -23
  16. data/lib/gapic/ruby_info.rb +93 -0
  17. data/lib/gapic/schema/api.rb +63 -1
  18. data/templates/default/gem/gemfile.erb +3 -0
  19. data/templates/default/gem/gemspec.erb +7 -6
  20. data/templates/default/gem/rakefile.erb +1 -0
  21. data/templates/default/gem/test_helper.erb +8 -0
  22. data/templates/default/layouts/_ruby.erb +5 -4
  23. data/templates/default/lib/_service.erb +2 -0
  24. data/templates/default/proto_docs/_message.erb +2 -2
  25. data/templates/default/service/client.erb +1 -1
  26. data/templates/default/service/client/_client.erb +17 -4
  27. data/templates/default/service/client/_config.erb +33 -29
  28. data/templates/default/service/client/_credentials.erb +1 -1
  29. data/templates/default/service/client/_operations.erb +3 -1
  30. data/templates/default/service/client/method/def/_options_defaults.erb +2 -2
  31. data/templates/default/service/client/method/def/_request_normal.erb +2 -2
  32. data/templates/default/service/client/method/def/_request_streaming.erb +3 -3
  33. data/templates/default/service/client/method/def/_response_normal.erb +1 -1
  34. data/templates/default/service/client/method/def/_response_paged.erb +2 -2
  35. data/templates/default/service/client/method/docs/_error.erb +1 -1
  36. data/templates/default/service/client/method/docs/_request_normal.erb +2 -2
  37. data/templates/default/service/client/method/docs/_request_streaming.erb +2 -2
  38. data/templates/default/service/client/method/docs/_response.erb +1 -1
  39. data/templates/default/service/client/resource/_def.erb +1 -1
  40. data/templates/default/service/client/resource/_multi.erb +4 -7
  41. data/templates/default/service/client/resource/_single.erb +2 -3
  42. data/templates/default/service/credentials.erb +1 -1
  43. data/templates/default/service/operations.erb +1 -1
  44. data/templates/default/service/paths.erb +1 -1
  45. data/templates/default/service/test/_resource.erb +16 -0
  46. data/templates/default/service/test/client.erb +17 -4
  47. data/templates/default/service/test/client_operations.erb +3 -4
  48. data/templates/default/service/test/client_paths.erb +17 -0
  49. data/templates/default/service/test/method/_configure.erb +19 -0
  50. metadata +8 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 141fbba25c93dca9ccac5c4a380f7a0f8c1c1643ef2e9517fbb158ba92db822c
4
- data.tar.gz: c61466f199a4d34b6c1fefea9aa8773abc7d9514dfb232385a1e6806e49140f2
3
+ metadata.gz: 19f79c05f4e657a010e8f9663f1eefeadabd18ef4b456c137a8278bf8bb13a9e
4
+ data.tar.gz: ebe4c8c756ebd1e18424eccffc986f92bcda6f694a50842ed394c7d62d91f252
5
5
  SHA512:
6
- metadata.gz: 1cefa5cb936a4d9f211c0af9f03a9bcbd4ba76f35417cc3a1723164c949dc93b0f9f8be3602ac882d19c2a1109eed7b47150f4be4587ab5d5a368d7942df14f5
7
- data.tar.gz: eab763dd18a81db68af29cc55e54b69f7f8fe504bca56aa93925a66e0c8f548335a4700c0cb89cb13aef65f5de7d640dc8dc0a704190e6a06f7ecdaeb294b065
6
+ metadata.gz: 4a6689a12fcd02390d416ab8ada828f79e182e87a3230361fe32e3a8eea42d7555039b61c699903d25a5fb244c9db1857bbad1d816ea04e4de329d67c4359c74
7
+ data.tar.gz: fac5801f38bb3fd92b871c2c5ab9b2d7ee7138d0947ffb0c9695bd21ea0561762fee5dc462de884b5182cbf4627c5c9148783474584b6cb4c9dc7727313f7f1c
@@ -1,5 +1,39 @@
1
1
  # Release History for gapic-generator
2
2
 
3
+ ### 0.6.0 / 2020-06-02
4
+
5
+ * Support for clients with generic endpoint and credentials.
6
+ * Support for adding extra dependencies.
7
+ * Fixed a Ruby warning when looking up RPC-scoped configs with no parent.
8
+ * Internal: Presenters reference their parent rather than creating new objects.
9
+
10
+ ### 0.5.1 / 2020-05-21
11
+
12
+ * Support a configuration for overriding service module names.
13
+ * Operations client honors the quota_project setting.
14
+
15
+ ### 0.5.0 / 2020-05-19
16
+
17
+ * Add quota_project to the generated configs.
18
+ * Allow resource patterns with a star as a segment template.
19
+ * Generate tests for resource path helpers.
20
+ * Pin protobuf dependency for Ruby < 2.5.
21
+ * Create a test helper in for generated tests.
22
+
23
+ ### 0.4.2 / 2020-04-28
24
+
25
+ * Prepend double-colon to absolute/global namespaces to prevent conflicts.
26
+ * Fix documentation/examples of timeouts to clarify they are in seconds.
27
+
28
+ ### 0.4.0 / 2020-04-20
29
+
30
+ * Support generating clients of "common" interfaces by delegating to another service config.
31
+ * Added an accessor for the long-running-operation client from the main client.
32
+ * Generate tests for the configure method and operations client accessor.
33
+ * Prevent generation of RPC or factory methods with reserved names.
34
+ * Fixed: LRO clients weren't inheriting custom endpoints from the main client.
35
+ * Fixed: Cross-references weren't interpreted if the text included backticks, spaces, or hyphens.
36
+
3
37
  ### 0.3.3 / 2020-04-13
4
38
 
5
39
  * Fix cross-reference links to multi-word enum values.
@@ -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
@@ -137,15 +137,15 @@ module Gapic
137
137
 
138
138
  case entity
139
139
  when Gapic::Schema::Service
140
- "{#{convert_address_to_ruby entity}::Client #{text}}"
140
+ "{::#{convert_address_to_ruby entity}::Client #{text}}"
141
141
  when Gapic::Schema::Method
142
- "{#{convert_address_to_ruby entity.parent}::Client##{entity.name.underscore} #{text}}"
142
+ "{::#{convert_address_to_ruby entity.parent}::Client##{entity.name.underscore} #{text}}"
143
143
  when Gapic::Schema::Message, Gapic::Schema::Enum
144
- "{#{convert_address_to_ruby entity} #{text}}"
144
+ "{::#{convert_address_to_ruby entity} #{text}}"
145
145
  when Gapic::Schema::EnumValue
146
- "{#{convert_address_to_ruby entity.parent}::#{entity.name} #{text}}"
146
+ "{::#{convert_address_to_ruby entity.parent}::#{entity.name} #{text}}"
147
147
  when Gapic::Schema::Field
148
- "{#{convert_address_to_ruby entity.parent}##{entity.name} #{text}}"
148
+ "{::#{convert_address_to_ruby entity.parent}##{entity.name} #{text}}"
149
149
  end
150
150
  end
151
151
 
@@ -155,7 +155,7 @@ module Gapic
155
155
  address = entity.address
156
156
  address = address.join "." if address.is_a? Array
157
157
  address = address.sub file.package, file.ruby_package if file.ruby_package&.present?
158
- address.split(".").reject(&:empty?).map(&:camelize).map { |node| api.fix_namespace node }.join("::")
158
+ address.split(/\.|::/).reject(&:empty?).map(&:camelize).map { |node| api.fix_namespace node }.join("::")
159
159
  end
160
160
  end
161
161
  end
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Gapic
18
18
  module Generator
19
- VERSION = "0.3.3"
19
+ VERSION = "0.6.0"
20
20
  end
21
21
  end
@@ -41,10 +41,10 @@ module Gapic
41
41
  # @return [Array<
42
42
  # Google::Protobuf::Compiler::CodeGeneratorResponse::File>]
43
43
  # The files that were generated for the API.
44
- def generate
44
+ def generate gem_presenter: nil
45
45
  files = []
46
46
 
47
- gem = Gapic::Presenters.gem_presenter @api
47
+ gem = gem_presenter || Gapic::Presenters.gem_presenter(@api)
48
48
 
49
49
  gem.packages.each do |package|
50
50
  # Package level files
@@ -54,26 +54,28 @@ module Gapic
54
54
  # Service level files
55
55
  files << g("service.erb", "lib/#{service.service_file_path}", service: service)
56
56
  files << g("service/client.erb", "lib/#{service.client_file_path}", service: service)
57
- files << g("service/credentials.erb", "lib/#{service.credentials_file_path}", service: service)
57
+ files << g("service/credentials.erb", "lib/#{service.credentials_file_path}", service: service) unless gem.generic_endpoint?
58
58
  files << g("service/paths.erb", "lib/#{service.paths_file_path}", service: service) if service.paths?
59
59
  files << g("service/operations.erb", "lib/#{service.operations_file_path}", service: service) if service.lro?
60
60
  files << g("service/test/client.erb", "test/#{service.test_client_file_path}", service: service)
61
+ files << g("service/test/client_paths.erb", "test/#{service.test_paths_file_path}", service: service) if service.paths?
61
62
  files << g("service/test/client_operations.erb", "test/#{service.test_client_operations_file_path}", service: service) if service.lro?
62
63
  end
63
64
  end
64
65
 
65
66
  # 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)
76
- files << g("gem/entrypoint.erb", "lib/#{gem.name}.rb", gem: gem)
67
+ files << g("gem/gitignore.erb", ".gitignore", gem: gem)
68
+ files << g("gem/version.erb", "lib/#{gem.version_file_path}", gem: gem)
69
+ files << g("gem/test_helper.erb", "test/helper.rb", gem: gem)
70
+ files << g("gem/gemspec.erb", "#{gem.name}.gemspec", gem: gem)
71
+ files << g("gem/gemfile.erb", "Gemfile", gem: gem)
72
+ files << g("gem/rakefile.erb", "Rakefile", gem: gem)
73
+ files << g("gem/readme.erb", "README.md", gem: gem)
74
+ files << g("gem/changelog.erb", "CHANGELOG.md", gem: gem)
75
+ files << g("gem/rubocop.erb", ".rubocop.yml", gem: gem)
76
+ files << g("gem/yardopts.erb", ".yardopts", gem: gem)
77
+ files << g("gem/license.erb", "LICENSE.md", gem: gem)
78
+ files << g("gem/entrypoint.erb", "lib/#{gem.name}.rb", gem: gem)
77
79
 
78
80
  gem.proto_files.each do |proto_file|
79
81
  files << g("proto_docs/proto_file.erb", "proto_docs/#{proto_file.docs_file_path}", file: proto_file)
@@ -25,6 +25,7 @@ module Gapic
25
25
  ##
26
26
  # Converts a ruby namespace string to a file path string.
27
27
  def ruby_file_path api, namespace
28
+ namespace = namespace.sub(/^::/, "")
28
29
  file_path = ruby_file_path_for_namespace namespace
29
30
  fix_file_path api, file_path
30
31
  end
@@ -38,7 +38,14 @@ module Gapic
38
38
  # Ruby double-semicolon separators.
39
39
  def ruby_namespace_for_address address
40
40
  address = address.split "." if address.is_a? String
41
- address.reject(&:empty?).map(&:camelize).join "::"
41
+ ensure_absolute_namespace address.reject(&:empty?).map(&:camelize).join("::")
42
+ end
43
+
44
+ ##
45
+ # Returns the given namespace, ensuring double colons are prepended
46
+ #
47
+ def ensure_absolute_namespace namespace
48
+ namespace.start_with?("::") ? namespace : "::#{namespace}"
42
49
  end
43
50
 
44
51
  ##
@@ -56,6 +56,13 @@ module Gapic
56
56
  !@pattern.nil?
57
57
  end
58
58
 
59
+ # Determines if the segment has a nontrivial pattern (i.e. not `*` or `**`).
60
+ #
61
+ # @return [Boolean]
62
+ def nontrivial_pattern?
63
+ @pattern && @pattern != "*" && @pattern != "**"
64
+ end
65
+
59
66
  # @private
60
67
  def == other
61
68
  return false unless other.is_a? self.class
@@ -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
 
@@ -147,10 +147,36 @@ module Gapic
147
147
  gem_config(:yard_strict) != "false"
148
148
  end
149
149
 
150
+ def generic_endpoint?
151
+ gem_config(:generic_endpoint) == "true"
152
+ end
153
+
150
154
  def entrypoint_require
151
155
  packages.first.package_require
152
156
  end
153
157
 
158
+ def license_name
159
+ "MIT"
160
+ end
161
+
162
+ def extra_files
163
+ ["README.md", "LICENSE.md", ".yardopts"]
164
+ end
165
+
166
+ def dependencies
167
+ deps = { "gapic-common" => "~> 0.2" }
168
+ deps["grpc-google-iam-v1"] = [">= 0.6.10", "< 2.0"] if iam_dependency?
169
+ extra_deps = gem_config :extra_dependencies
170
+ deps.merge! extra_deps if extra_deps
171
+ deps
172
+ end
173
+
174
+ def dependency_list
175
+ dependencies.to_a
176
+ .map { |name, requirements| [name, Array(requirements)] }
177
+ .sort_by { |name, _requirements| name }
178
+ end
179
+
154
180
  private
155
181
 
156
182
  def gem_config key
@@ -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
@@ -26,17 +27,22 @@ module Gapic
26
27
  class MethodPresenter
27
28
  include Gapic::Helpers::NamespaceHelper
28
29
 
29
- def initialize api, method
30
+ def initialize service_presenter, api, method
31
+ @service_presenter = service_presenter
30
32
  @api = api
31
33
  @method = method
32
34
  end
33
35
 
34
36
  def service
35
- ServicePresenter.new @api, @method.parent
37
+ @service_presenter
36
38
  end
37
39
 
38
40
  def name
39
- ActiveSupport::Inflector.underscore @method.name
41
+ @name ||= begin
42
+ candidate = ActiveSupport::Inflector.underscore @method.name
43
+ candidate = "call_#{candidate}" if Gapic::RubyInfo.excluded_method_names.include? candidate
44
+ candidate
45
+ end
40
46
  end
41
47
 
42
48
  def kind
@@ -59,13 +65,13 @@ module Gapic
59
65
 
60
66
  def doc_response_type
61
67
  ret = return_type
62
- ret = "Gapic::Operation" if lro?
68
+ ret = "::Gapic::Operation" if lro?
63
69
  if server_streaming?
64
- ret = "Enumerable<#{ret}>"
70
+ ret = "::Enumerable<#{ret}>"
65
71
  elsif paged?
66
72
  paged_type = paged_response_type
67
- paged_type = "Gapic::Operation" if paged_type == "Google::Longrunning::Operation"
68
- ret = "Gapic::PagedEnumerable<#{paged_type}>"
73
+ paged_type = "::Gapic::Operation" if paged_type == "::Google::Longrunning::Operation"
74
+ ret = "::Gapic::PagedEnumerable<#{paged_type}>"
69
75
  end
70
76
  ret
71
77
  end
@@ -118,7 +124,7 @@ module Gapic
118
124
  return [
119
125
  OpenStruct.new(
120
126
  name: "operation",
121
- doc_types: "Gapic::Operation"
127
+ doc_types: "::Gapic::Operation"
122
128
  )
123
129
  ]
124
130
  end
@@ -129,7 +135,7 @@ module Gapic
129
135
  ),
130
136
  OpenStruct.new(
131
137
  name: "operation",
132
- doc_types: "GRPC::ActiveCall::Operation"
138
+ doc_types: "::GRPC::ActiveCall::Operation"
133
139
  )
134
140
  ]
135
141
  end
@@ -145,9 +151,9 @@ module Gapic
145
151
  end
146
152
 
147
153
  def lro?
148
- return paged_response_type == "Google::Longrunning::Operation" if paged?
154
+ return paged_response_type == "::Google::Longrunning::Operation" if paged?
149
155
 
150
- message_ruby_type(@method.output) == "Google::Longrunning::Operation"
156
+ message_ruby_type(@method.output) == "::Google::Longrunning::Operation"
151
157
  end
152
158
 
153
159
  def client_streaming?
@@ -221,12 +227,12 @@ module Gapic
221
227
  message_ruby_type arg.enum
222
228
  else
223
229
  case arg.type
224
- when 1, 2 then "Float"
225
- when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "Integer"
226
- when 9, 12 then "String"
227
- when 8 then "Boolean"
230
+ when 1, 2 then "::Float"
231
+ when 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "::Integer"
232
+ when 9, 12 then "::String"
233
+ when 8 then "::Boolean"
228
234
  else
229
- "Object"
235
+ "::Object"
230
236
  end
231
237
  end
232
238
  end
@@ -251,7 +257,7 @@ module Gapic
251
257
  when 9, 12 then "\"hello world\""
252
258
  when 8 then "true"
253
259
  else
254
- "Object"
260
+ "::Object"
255
261
  end
256
262
  end
257
263
  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
@@ -53,10 +54,17 @@ module Gapic
53
54
  namespace.split("::").last
54
55
  end
55
56
 
57
+ # Services whose clients should be generated in this package namespace.
56
58
  def services
57
59
  @services ||= begin
58
60
  files = @api.generate_files.select { |f| f.package == @package }
59
- files.map(&:services).flatten.map { |s| ServicePresenter.new @api, s }
61
+ services = files.map(&:services).flatten
62
+ # Omit common services in this package. Common service clients do not
63
+ # go into their own package.
64
+ normal_services = services.select { |s| @api.delegate_service_for(s).nil? }
65
+ # But include common services that delegate to normal services in this package.
66
+ common_services = normal_services.flat_map { |s| @api.common_services_for s }
67
+ (normal_services + common_services).map { |s| ServicePresenter.new @gem_presenter, @api, s }
60
68
  end
61
69
  end
62
70
 
@@ -15,7 +15,6 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "gapic/path_template"
18
- require "ostruct"
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 { |template| PatternPresenter.new template }
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,64 @@ 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 template
57
+ @template = template
58
+ @segments = Gapic::PathTemplate.parse template
59
+ @arguments = arg_segments.map(&:name)
60
+ @path_string = build_path_string
61
+ end
64
62
 
65
- def arguments_for segments
66
- arg_segments(segments).map(&:name)
67
- end
63
+ attr_reader :template, :segments, :arguments, :path_string
68
64
 
69
- def arg_segments segments
70
- segments.select { |segment| segment.is_a? Gapic::PathTemplate::Segment }
71
- end
65
+ def useful_for_helpers?
66
+ arg_segments.none?(&:nontrivial_pattern?) && arg_segments.none?(&:positional?)
67
+ end
72
68
 
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
69
+ def formal_arguments
70
+ arguments.map { |arg| "#{arg}:" }.join ", "
71
+ end
83
72
 
84
- def positional_args? segments
85
- arg_segments(segments).any?(&:positional?)
86
- end
73
+ def arguments_key
74
+ arguments.sort.join ":"
75
+ end
76
+
77
+ def arguments_with_dummy_values
78
+ arguments.each_with_index.map { |arg, index| "#{arg}: \"value#{index}\"" }.join ", "
79
+ end
80
+
81
+ def expected_path_for_dummy_values
82
+ index = -1
83
+ segments.map do |segment|
84
+ if segment.is_a? Gapic::PathTemplate::Segment
85
+ index += 1
86
+ "value#{index}"
87
+ else
88
+ # Should be a String
89
+ segment
90
+ end
91
+ end.join
92
+ end
87
93
 
88
- def named_arg_patterns? segments
89
- arg_segments(segments).any?(&:pattern)
94
+ private
95
+
96
+ def arg_segments
97
+ segments.select { |segment| segment.is_a? Gapic::PathTemplate::Segment }
98
+ end
99
+
100
+ def build_path_string
101
+ segments.map do |segment|
102
+ if segment.is_a? Gapic::PathTemplate::Segment
103
+ "\#{#{segment.name}}"
104
+ else
105
+ # Should be a String
106
+ segment
107
+ end
108
+ end.join
109
+ end
90
110
  end
91
111
  end
92
112
  end