gapic-generator 0.6.8 → 0.6.13

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cb3044a15ef0354c0aa76903f7bf51e1218b96b0ba7b5923c1b996119dcc5c5
4
- data.tar.gz: 4a6b8fa141b8474ed05188f097febfe550901d00b832b153b9fcd3710f01c7a1
3
+ metadata.gz: c9f0e5ee2a9fd5c53dd43b0cc3d04c0c6c590ce06782dcb0a5eb9a346369d241
4
+ data.tar.gz: 7a4787ff915d5a8355677377f60481fa5f714923ccf4d1f65e02f5ef8754dd4d
5
5
  SHA512:
6
- metadata.gz: d8680d28265909b97ca6071a0a28165368d68f861ec4d13615abdf9931b063dfa336e5e8c382a12be24daa4f34b247e1b3da3c28a8550ff27366493ae4a9d113
7
- data.tar.gz: 95057a02f066f096c326020e4fbd83bf9ca24f279722812072eefd34df8e2184fe6b72c8d785c37596f0a626279d73fea810fd5c793e96b49c8cbfeb0148ac2e
6
+ metadata.gz: c01dd5965a8a54e79e802135eb6df543200b338252e7f129a6adddc53e1c9d92ae91043ebe3ad30846ae496b868d489a1190b477b72448f8ecc022abcd1eb6bb
7
+ data.tar.gz: df3aed51dc4573c7bde9370f77920434a58bb12b13e4a3388fe741deabee9d0ecefa60f50b165c7ab6856a9ea5c0149d789ab825059bf93d1749de66358298ad
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Release History for gapic-generator
2
2
 
3
+ ### 0.6.13 / 2021-02-22
4
+
5
+ * Remove InputOnly and OutputOnly proto tags from docs to avoid confusing YARD.
6
+ * Generate drift manifest.
7
+ * Executable entrypoints set the default external locale to utf-8.
8
+
9
+ ### 0.6.12 / 2021-02-01
10
+
11
+ * No changes.
12
+
13
+ ### 0.6.11 / 2021-02-01
14
+
15
+ * Generated clients determine whether to use self-signed JWT credentials.
16
+
17
+ ### 0.6.10 / 2021-01-13
18
+
19
+ * A set of human-readable command-line parameters can now be specified for the gapic-generator, e.g. `gem-name`. These parameters strictly duplicate the existing behaviour of old command-line parameters, e.g. `:gem.:name`.
20
+ * Documentation for the `timeout` parameter in some templates has been fixed to correctly specify 'seconds' where previously it incorrectly sais 'milliseconds'. This is a purely documentation update, no functionality changes.
21
+
22
+ ### 0.6.9 / 2020-12-07
23
+
24
+ * Load package-level handwritten helpers.
25
+ * Disable Names/PredicateName rubocop rule.
26
+ * Fix generated client tests when a request field name collides with a Ruby superclass method.
27
+
3
28
  ### 0.6.8 / 2020-09-16
4
29
 
5
30
  * Add samples tasks to generated gapic rakefiles.
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env -S ruby -E UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright 2018 Google LLC
@@ -24,6 +24,7 @@ module Gapic
24
24
  @brace_detector = /\A(?<pre>[^`]*(`[^`]*`[^`]*)*[^`\\])?\{(?<inside>[^\s][^}]*)\}(?<post>.*)\z/m
25
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
+ @omit_lines = ["@InputOnly\n", "@OutputOnly\n"]
27
28
 
28
29
  class << self
29
30
  ##
@@ -49,7 +50,7 @@ module Gapic
49
50
  # preformatted.
50
51
  in_block = nil
51
52
  base_indent = 0
52
- lines.map do |line|
53
+ (lines - @omit_lines).map do |line|
53
54
  indent = line_indent line
54
55
  if indent.nil?
55
56
  in_block = nil
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Gapic
18
18
  module Generator
19
- VERSION = "0.6.8"
19
+ VERSION = "0.6.13"
20
20
  end
21
21
  end
@@ -15,6 +15,7 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "gapic/generators/base_generator"
18
+ require "gapic/generators/default_generator_parameters"
18
19
  require "gapic/presenters"
19
20
 
20
21
  module Gapic
@@ -64,18 +65,19 @@ module Gapic
64
65
  end
65
66
 
66
67
  # Gem level files
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)
68
+ files << g("gem/gitignore.erb", ".gitignore", gem: gem)
69
+ files << g("gem/version.erb", "lib/#{gem.version_file_path}", gem: gem)
70
+ files << g("gem/test_helper.erb", "test/helper.rb", gem: gem)
71
+ files << g("gem/gemspec.erb", "#{gem.name}.gemspec", gem: gem)
72
+ files << g("gem/gemfile.erb", "Gemfile", gem: gem)
73
+ files << g("gem/rakefile.erb", "Rakefile", gem: gem)
74
+ files << g("gem/readme.erb", "README.md", gem: gem)
75
+ files << g("gem/changelog.erb", "CHANGELOG.md", gem: gem)
76
+ files << g("gem/rubocop.erb", ".rubocop.yml", gem: gem)
77
+ files << g("gem/yardopts.erb", ".yardopts", gem: gem)
78
+ files << g("gem/license.erb", "LICENSE.md", gem: gem)
79
+ files << g("gem/entrypoint.erb", "lib/#{gem.name}.rb", gem: gem)
80
+ files << g("gem/gapic_metadata_json.erb", "gapic_metadata.json", gem: gem)
79
81
 
80
82
  gem.proto_files.each do |proto_file|
81
83
  files << g("proto_docs/proto_file.erb", "proto_docs/#{proto_file.docs_file_path}", file: proto_file)
@@ -89,6 +91,12 @@ module Gapic
89
91
 
90
92
  # rubocop:enable all
91
93
 
94
+ # Schema of the parameters that the generator accepts
95
+ # @return [Gapic::Schema::ParameterSchema]
96
+ def self.parameter_schema
97
+ DefaultGeneratorParameters.default_schema
98
+ end
99
+
92
100
  private
93
101
 
94
102
  ##
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 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 "gapic/schema/parameter_schema"
18
+
19
+ module Gapic
20
+ module Generators
21
+ # Contains the default generator's parameters
22
+ module DefaultGeneratorParameters
23
+ BOOL_PARAMETERS = [
24
+ ":gem.:free_tier",
25
+ ":gem.:yard_strict",
26
+ ":gem.:generic_endpoint"
27
+ ].freeze
28
+
29
+ STRING_PARAMETERS = [
30
+ ":gem.:name",
31
+ ":gem.:namespace",
32
+ ":gem.:title",
33
+ ":gem.:description",
34
+ ":gem.:summary",
35
+ ":gem.:homepage",
36
+ ":gem.:env_prefix",
37
+ ":gem.:version_dependencies",
38
+ ":gem.:migration_version",
39
+ ":gem.:product_documentation_url",
40
+ ":gem.:issue_tracker_url",
41
+ ":gem.:api_id",
42
+ ":gem.:api_shortname",
43
+ ":gem.:factory_method_suffix",
44
+ ":defaults.:service.:default_host",
45
+ "grpc_service_config"
46
+ ].freeze
47
+
48
+ ARRAY_PARAMETERS = [
49
+ ":defaults.:service.:oauth_scopes"
50
+ ].freeze
51
+
52
+ MAP_PARAMETERS = [
53
+ ":common_services",
54
+ ":overrides.:file_path",
55
+ ":overrides.:namespace",
56
+ ":overrides.:service",
57
+ ":gem.:extra_dependencies"
58
+ ].freeze
59
+
60
+ BOOL_PARAMETERS_ALIASES = {
61
+ "gem-free-tier" => ":gem.:free_tier",
62
+ "gem-yard-strict" => ":gem.:yard_strict",
63
+ "gem-generic-endpoint" => ":gem.:generic_endpoint"
64
+ }.freeze
65
+
66
+ STRING_PARAMETERS_ALIASES = {
67
+ "gem-name" => ":gem.:name",
68
+ "gem-namespace" => ":gem.:namespace",
69
+ "gem-title" => ":gem.:title",
70
+ "gem-description" => ":gem.:description",
71
+ "gem-summary" => ":gem.:summary",
72
+ "gem-homepage" => ":gem.:homepage",
73
+ "gem-env-prefix" => ":gem.:env_prefix",
74
+ "gem-wrapper-of" => ":gem.:version_dependencies",
75
+ "gem-migration-version" => ":gem.:migration_version",
76
+ "gem-product-url" => ":gem.:product_documentation_url",
77
+ "gem-issues-url" => ":gem.:issue_tracker_url",
78
+ "gem-api-id" => ":gem.:api_id",
79
+ "gem-api-shortname" => ":gem.:api_shortname",
80
+ "gem-factory-method-suffix" => ":gem.:factory_method_suffix",
81
+ "default-service-host" => ":defaults.:service.:default_host",
82
+ "grpc-service-config" => "grpc_service_config"
83
+ }.freeze
84
+
85
+ ARRAY_PARAMETERS_ALIASES = {
86
+ "default-oauth-scopes" => ":defaults.:service.:oauth_scopes"
87
+ }.freeze
88
+
89
+ MAP_PARAMETERS_ALIASES = {
90
+ "common-services" => ":common_services",
91
+ "file-path-override" => ":overrides.:file_path",
92
+ "namespace-override" => ":overrides.:namespace",
93
+ "service-override" => ":overrides.:service",
94
+ "gem-extra-dependencies" => ":gem.:extra_dependencies"
95
+ }.freeze
96
+
97
+ def self.default_schema
98
+ base_schema = Gapic::Schema::ParameterSchema.create(
99
+ bool_params_list: BOOL_PARAMETERS,
100
+ string_params_list: STRING_PARAMETERS,
101
+ array_params_list: ARRAY_PARAMETERS,
102
+ map_params_list: MAP_PARAMETERS
103
+ )
104
+
105
+ base_schema.extend_with_aliases(
106
+ bool_aliases: BOOL_PARAMETERS_ALIASES,
107
+ string_aliases: STRING_PARAMETERS_ALIASES,
108
+ array_aliases: ARRAY_PARAMETERS_ALIASES,
109
+ map_aliases: MAP_PARAMETERS_ALIASES
110
+ )
111
+ end
112
+ end
113
+ end
114
+ end
@@ -17,6 +17,8 @@
17
17
  require "gapic/helpers/filepath_helper"
18
18
  require "gapic/helpers/namespace_helper"
19
19
 
20
+ require "json"
21
+
20
22
  module Gapic
21
23
  module Presenters
22
24
  ##
@@ -191,6 +193,27 @@ module Gapic
191
193
  .sort_by { |name, _requirements| name }
192
194
  end
193
195
 
196
+ ##
197
+ # Returns a hash with a drift_manifest of
198
+ # a first package in this gem
199
+ # (while the behaviour in case of multiple packages is clarified).
200
+ # See https://github.com/googleapis/googleapis/blob/master/gapic/metadata/gapic_metadata.proto
201
+ #
202
+ # @return [Hash]
203
+ def first_package_drift_manifest
204
+ return {} unless packages?
205
+ packages[0].drift_manifest
206
+ end
207
+
208
+ ##
209
+ # Returns a drift manifest of the first package in
210
+ # a pretty JSON string form
211
+ #
212
+ # @return [String]
213
+ def first_package_drift_json
214
+ JSON.pretty_generate first_package_drift_manifest
215
+ end
216
+
194
217
  private
195
218
 
196
219
  def gem_config key
@@ -80,9 +80,43 @@ module Gapic
80
80
  package_require + ".rb"
81
81
  end
82
82
 
83
+ def package_directory_name
84
+ package_require.split("/").last
85
+ end
86
+
83
87
  def empty?
84
88
  services.empty?
85
89
  end
90
+
91
+ def helpers_file_path
92
+ helpers_require + ".rb"
93
+ end
94
+
95
+ def helpers_file_name
96
+ "_helpers.rb"
97
+ end
98
+
99
+ def helpers_require
100
+ package_require + "/_helpers"
101
+ end
102
+
103
+ ##
104
+ # Returns a hash with a drift_manifest of this package
105
+ # describing correspondence between the proto description
106
+ # of the package with the generated code for the package.
107
+ # See https://github.com/googleapis/googleapis/blob/master/gapic/metadata/gapic_metadata.proto
108
+ #
109
+ # @return [Hash]
110
+ def drift_manifest
111
+ {
112
+ schema: "1.0",
113
+ comment: "This file maps proto services/RPCs to the corresponding library clients/methods",
114
+ language: "ruby",
115
+ protoPackage: name,
116
+ libraryPackage: namespace,
117
+ services: services.map { |s| [s.grpc_service_name, s.drift_manifest] }.to_h
118
+ }
119
+ end
86
120
  end
87
121
  end
88
122
  end
@@ -333,10 +333,40 @@ module Gapic
333
333
  @api.grpc_service_config.service_level_configs[grpc_full_name]
334
334
  end
335
335
 
336
+ ##
337
+ # The short proto name for this service
338
+ #
339
+ # @return [String]
340
+ def grpc_service_name
341
+ @service.name
342
+ end
343
+
336
344
  def grpc_full_name
337
345
  @service.address.join "."
338
346
  end
339
347
 
348
+ ##
349
+ # Returns a hash with a drift_manifest of this service,
350
+ # describing correspondence between the proto description
351
+ # of the service with the generated code for the service.
352
+ # See https://github.com/googleapis/googleapis/blob/master/gapic/metadata/gapic_metadata.proto
353
+ #
354
+ # @return [Hash]
355
+ def drift_manifest
356
+ {
357
+ clients: {
358
+ grpc: {
359
+ libraryClient: client_name_full,
360
+ # The methods should grouped by grpc_method_name and then
361
+ # their names are returned together in an array.
362
+ # For Ruby currently we have 1:1 proto to code
363
+ # correspondence for methods, so our generation is easier
364
+ methods: methods.map { |m| [m.grpc_method_name, [m.name]] }.to_h
365
+ }
366
+ }
367
+ }
368
+ end
369
+
340
370
  private
341
371
 
342
372
  def default_config key
data/lib/gapic/runner.rb CHANGED
@@ -16,6 +16,7 @@
16
16
 
17
17
  require "gapic/generator"
18
18
  require "gapic/schema"
19
+ require "gapic/schema/request_param_parser"
19
20
  require "google/protobuf/compiler/plugin.pb"
20
21
 
21
22
  module Gapic
@@ -27,6 +28,20 @@ module Gapic
27
28
  # Initializes the runner.
28
29
  # @param [Google::Protobuf::Compiler::CodeGeneratorRequest] request
29
30
  def initialize request
31
+ # parse the parameters that apply to runner and not to the api and exclude them from the request
32
+ runner_param_names = ["binary_output", "generator"]
33
+ runner_schema = Gapic::Schema::ParameterSchema.create(
34
+ string_params_list: runner_param_names
35
+ )
36
+
37
+ params = Gapic::Schema::RequestParamParser.parse_parameters_string request.parameter, param_schema: runner_schema
38
+ @binary_output_path = params.filter { |p| p.config_name == "binary_output" }.first&.config_value
39
+ @generator_type = params.filter { |p| p.config_name == "generator" }.first&.config_value
40
+
41
+ gapic_params = params.filter { |p| !runner_param_names.include? p.config_name }
42
+ # reconstruct the request parameter string without the runner parameters
43
+ request.parameter = Gapic::Schema::RequestParamParser.reconstruct_parameters_string gapic_params
44
+
30
45
  @request = request
31
46
  end
32
47
 
@@ -34,22 +49,22 @@ module Gapic
34
49
  # @param [String] generator_type
35
50
  # @return [Google::Protobuf::Compiler::CodeGeneratorResponse]
36
51
  def run generator_type: nil
37
- # Create an API Schema from the FileDescriptorProtos
38
- api = Gapic::Schema::Api.new request
39
-
40
- write_binary_file! api
52
+ # save the binary file if needed
53
+ write_binary_file
41
54
 
42
55
  # Retrieve generator type from protoc_options if not already provided.
43
- generator_type ||= api.protoc_options["generator"]
56
+ generator_type ||= @generator_type
44
57
  # Find the generator for the generator type.
45
58
  generator = Gapic::Generator.find generator_type
46
59
 
60
+ # Create an API Schema from the FileDescriptorProtos
61
+ api = Gapic::Schema::Api.new request, parameter_schema: generator.parameter_schema
62
+
47
63
  # Create and run the generator from the API.
48
64
  output_files = generator.new(api).generate
49
65
 
50
66
  # Create and write the response
51
- response = Google::Protobuf::Compiler::CodeGeneratorResponse.new \
52
- file: output_files
67
+ response = Google::Protobuf::Compiler::CodeGeneratorResponse.new file: output_files
53
68
  response.supported_features = Google::Protobuf::Compiler::CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL
54
69
  response
55
70
  end
@@ -64,15 +79,13 @@ module Gapic
64
79
 
65
80
  private
66
81
 
67
- def write_binary_file! api
68
- return unless api.protoc_options["binary_output"]
69
-
70
- # First, strip the binary_output parameter out so it doesn't get saved
71
- binary_file = api.protoc_options.delete "binary_output"
72
- request.parameter = api.protoc_parameter
82
+ # Save binary file with the request
83
+ # if the binary_output_path parameter is set
84
+ def write_binary_file
85
+ return unless @binary_output_path
73
86
 
74
87
  # Write binary file if the binary_output option is set
75
- File.binwrite binary_file, request.to_proto
88
+ File.binwrite @binary_output_path, request.to_proto
76
89
  end
77
90
  end
78
91
  end
@@ -16,7 +16,9 @@
16
16
 
17
17
  require "yaml"
18
18
  require "json"
19
+ require "gapic/generators/default_generator_parameters"
19
20
  require "gapic/schema/loader"
21
+ require "gapic/schema/request_param_parser"
20
22
  require "gapic/grpc_service_config/parser"
21
23
 
22
24
  module Gapic
@@ -44,9 +46,11 @@ module Gapic
44
46
  #
45
47
  # @param request [Google::Protobuf::Compiler::CodeGeneratorRequest]
46
48
  # The request object.
49
+ # @param parameter_schema [Gapic::Schema::ParameterSchema]
50
+ # The request parameters schema to use
47
51
  # @param error_output [IO] An IO to write any errors/warnings to.
48
52
  # @param configuration [Hash] Optional override of configuration.
49
- def initialize request, error_output: STDERR, configuration: nil
53
+ def initialize request, parameter_schema: nil, error_output: STDERR, configuration: nil
50
54
  @request = request
51
55
  loader = Loader.new
52
56
  @files = request.proto_file.map do |fd|
@@ -55,6 +59,9 @@ module Gapic
55
59
  @files.each { |f| f.parent = self }
56
60
  @configuration = configuration
57
61
  @resource_types = analyze_resources
62
+
63
+ parameter_schema ||= Gapic::Generators::DefaultGeneratorParameters.default_schema
64
+ @protoc_parameters = parse_parameter request.parameter, parameter_schema, error_output
58
65
  sanity_checks error_output
59
66
  end
60
67
 
@@ -116,33 +123,20 @@ module Gapic
116
123
 
117
124
  # Structured Hash representation of the parameter values.
118
125
  # @return [Hash]
119
- # A Hash of the request parameters.
120
126
  def protoc_options
121
127
  @protoc_options ||= begin
122
128
  result = {}
123
- parameters = parse_parameter request.parameter
124
- parameters.each do |param_array|
125
- key = param_array.first
126
- next if key.empty?
127
- value = param_array[1..-1]
128
- value = value.first if value.size == 1
129
- value = nil if value.empty?
130
- result[str_to_key(key)] = value
129
+ @protoc_parameters.each do |parameter|
130
+ result[str_to_key(parameter.config_name)] = parameter.config_value
131
131
  end
132
132
  result
133
133
  end
134
134
  end
135
135
 
136
- # Reconstructed string representation of the protoc options
136
+ # Reconstructed string representation of the protoc parameters
137
137
  # @return [String]
138
138
  def protoc_parameter
139
- protoc_options.map do |k, v|
140
- v = Array(v).map do |s|
141
- s.gsub("\\", "\\\\\\\\").gsub(",", "\\\\,").gsub("=", "\\\\=")
142
- end.join("=")
143
- k = key_to_str k
144
- "#{k}=#{v}"
145
- end.join ","
139
+ Gapic::Schema::RequestParamParser.reconstruct_parameters_string @protoc_parameters
146
140
  end
147
141
 
148
142
  # Structured representation of the samples configuration files.
@@ -353,20 +347,13 @@ module Gapic
353
347
 
354
348
  # Parse a comma-delimited list of equals-delimited lists of strings, while
355
349
  # mapping backslash-escaped commas and equal signs to literal characters.
356
- def parse_parameter str
357
- str.scan(/\\.|,|=|[^\\,=]+/)
358
- .each_with_object([[String.new]]) do |tok, arr|
359
- if tok == ","
360
- arr.append [String.new]
361
- elsif tok == "="
362
- arr.last.append String.new
363
- elsif tok.start_with? "\\"
364
- arr.last.last << tok[1]
365
- else
366
- arr.last.last << tok
367
- end
368
- arr
369
- end
350
+ # @param str [String]
351
+ # @param error_output [IO] Stream to write outputs to.
352
+ # @return [Array<Gapic::Schema::RequestParameter>]
353
+ def parse_parameter str, parameter_schema, error_output
354
+ Gapic::Schema::RequestParamParser.parse_parameters_string str,
355
+ param_schema: parameter_schema,
356
+ error_output: error_output
370
357
  end
371
358
 
372
359
  # split the string on periods, but map backslash-escaped periods to
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 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
+ module Gapic
18
+ module Schema
19
+ # Contains information about known parameter names
20
+ # and the types expected to be parsed from the request options string
21
+ class ParameterSchema
22
+ attr_accessor :bool_params, :string_params, :array_params, :map_params
23
+
24
+ # Creates a schema with given alias-parameter maps
25
+ # @param bool_params [Hash{String => String}]
26
+ # @param string_params [Hash{String => String}]
27
+ # @param array_params [Hash{String => String}]
28
+ # @param map_params [Hash{String => String}]
29
+ def initialize bool_params = {}, string_params = {}, array_params = {}, map_params = {}
30
+ @bool_params = bool_params
31
+ @string_params = string_params
32
+ @array_params = array_params
33
+ @map_params = map_params
34
+ end
35
+
36
+ # Creates a schema from given parameter lists
37
+ # @param bool_params_list [Array<String>]
38
+ # @param string_params_list [Array<String>]
39
+ # @param array_params_list [Array<String>]
40
+ # @param map_params_list [Array<String>]
41
+ # @return Gapic::Schema::ParameterSchema
42
+ def self.create bool_params_list: [], string_params_list: [], array_params_list: [], map_params_list: []
43
+ bool_params = bool_params_list.map { |val| [val, val] }.to_h
44
+ string_params = string_params_list.map { |val| [val, val] }.to_h
45
+ array_params = array_params_list.map { |val| [val, val] }.to_h
46
+ map_params = map_params_list.map { |val| [val, val] }.to_h
47
+
48
+ ParameterSchema.new bool_params, string_params, array_params, map_params
49
+ end
50
+
51
+ # Creates a new schema from this by adding aliases to existing parameters
52
+ # @param bool_aliases [Hash{String => String}]
53
+ # @param string_aliases [Hash{String => String}]
54
+ # @param array_aliases [Hash{String => String}]
55
+ # @param map_aliases [Hash{String => String}]
56
+ # @return Gapic::Schema::ParameterSchema
57
+ def extend_with_aliases bool_aliases: {}, string_aliases: {}, array_aliases: {}, map_aliases: {}
58
+ bool_params = @bool_params
59
+ bool_aliases.each { |param_alias, param| bool_params[param_alias] = param if bool_params.key? param }
60
+
61
+ string_params = @string_params
62
+ string_aliases.each { |param_alias, param| string_params[param_alias] = param if string_params.key? param }
63
+
64
+ array_params = @array_params
65
+ array_aliases.each { |param_alias, param| array_params[param_alias] = param if array_params.key? param }
66
+
67
+ map_params = @map_params
68
+ map_aliases.each { |param_alias, param| map_params[param_alias] = param if map_params.key? param }
69
+
70
+ ParameterSchema.new bool_params, string_params, array_params, map_params
71
+ end
72
+
73
+ # Looks up a parameter by name (including aliases)
74
+ # and return a type label (or :unknown) and a configuration name
75
+ # @param param_name [String] Input parameter name
76
+ # @return [Array<Symbol, String>] An array of [:detected_type, config_parameter_name]
77
+ def schema_name_type_for param_name
78
+ if @bool_params.key? param_name
79
+ [:bool, @bool_params[param_name]]
80
+ elsif @string_params.key? param_name
81
+ [:string, @string_params[param_name]]
82
+ elsif @array_params.key? param_name
83
+ [:array, @array_params[param_name]]
84
+ elsif @map_params.key? param_name
85
+ [:map, @map_params[param_name]]
86
+ else
87
+ [:unknown, param_name]
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 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 "gapic/schema/request_parameter"
18
+ require "gapic/schema/parameter_schema"
19
+
20
+ module Gapic
21
+ module Schema
22
+ # Contains logic for parsing protoc request parameters
23
+ # from the plugin_opt command line
24
+ module RequestParamParser
25
+ class << self
26
+ # Unescapes a symbol from the string
27
+ # e.g. `'a\.b', '.' => 'a.b'`
28
+ # @param string [String] String to unescape
29
+ # @return [String] Unescaped string
30
+ def unescape string
31
+ string.gsub(/\\./) { |escaped| escaped[1] }
32
+ end
33
+
34
+ # Splits a string by an unescaped symbol
35
+ # e.g. `'a\.b.c.d\.e', '.' => ['a\.b', 'c', 'd\.e']`
36
+ # @param string [String] String to split
37
+ # @param symbol [String] Symbol to split by
38
+ # @param max_splits [Integer] Maximum amount of splits to perform; -1 for no limit
39
+ # @return [Array<String>] List of split string parts
40
+ def split_by_unescaped string, symbol, max_splits = -1
41
+ splits = 0
42
+ escaped_symbol = Regexp.escape symbol
43
+ string.scan(/\\.|#{escaped_symbol}|[^#{escaped_symbol}\\]+/).each_with_object([String.new]) do |tok, arr|
44
+ if tok == symbol && (max_splits.negative? || splits < max_splits)
45
+ arr.append String.new
46
+ splits += 1
47
+ else
48
+ arr.last << tok
49
+ end
50
+ arr
51
+ end
52
+ end
53
+
54
+ # Parse a comma-delimited list of equals-delimited lists of strings, while
55
+ # mapping backslash-escaped commas and equal signs to literal characters.
56
+ # @param str [String] String to parse
57
+ # @param param_schema [ParameterSchema] Parameter schema to use
58
+ # @param error_output [IO] Stream to write outputs to.
59
+ # @return [Array<RequestParameter>] List of parameters parsed
60
+ def parse_parameters_string str, param_schema: nil, error_output: nil
61
+ return [] if str.empty?
62
+ param_schema ||= Gapic::Generators::DefaultGeneratorParameters.default_schema
63
+
64
+ param_val_input_strings = split_by_unescaped str, ","
65
+ param_val_input_strings.map do |param_val_input_str|
66
+ param_name_input_esc, value_str = split_by_unescaped param_val_input_str, "=", 1
67
+ param_name_input = unescape param_name_input_esc
68
+ param_type, param_config_name = param_schema.schema_name_type_for param_name_input
69
+
70
+ if param_type == :bool && !["true", "false"].include?(unescape(value_str))
71
+ error_str = "WARNING: parameter #{param_name_input} (recognised as bool " \
72
+ "#{param_config_name}) will be discarded because of " \
73
+ "invalid value. Value should be either 'true' or 'false'."
74
+ error_output&.puts error_str
75
+ end
76
+
77
+ param_value = parse_param_value param_type, value_str
78
+
79
+ if param_value
80
+ RequestParameter.new param_val_input_str, param_name_input_esc, value_str, param_config_name, param_value
81
+ end
82
+ end.compact # known bool parameters with invalid values will not be added so we have to compact
83
+ end
84
+
85
+ # Take a list of parameters and re-create an input string
86
+ # that can be parsed into these parameters
87
+ # @param parameters [Array<RequestParameter>] List of gapic-generator parameters
88
+ # @return [String] an input string with parameters
89
+ def reconstruct_parameters_string parameters
90
+ parameters.map(&:input_str).join ","
91
+ end
92
+
93
+ private
94
+
95
+ # Parses param value depending on type
96
+ # @param param_type [Symbol]
97
+ # @param value_str [String]
98
+ # @return [String,Array<String>,Hash{String => String}]
99
+ def parse_param_value param_type, value_str
100
+ case param_type
101
+ when :array
102
+ # elements in the arrays are concatenated by `;`
103
+ # e.g. foo;bar;baz
104
+ array_value_strings = split_by_unescaped value_str, ";"
105
+ array_value_strings.map { |s| unescape s }
106
+ when :map
107
+ # elements in the maps are `=` - separated key-value pairs, concatenated by ';'
108
+ # e.g. foo=hoge;bar=piyo
109
+ keyvaluepair_strings = split_by_unescaped value_str, ";"
110
+ new_hash = keyvaluepair_strings.map do |kvp_str|
111
+ split_by_unescaped(kvp_str, "=", 1).map { |s| unescape s }
112
+ end
113
+ new_hash.to_h
114
+ when :bool
115
+ # bools should be either `true` or `false`
116
+ unesc_val = unescape value_str
117
+ unesc_val if ["true", "false"].include? unesc_val
118
+ else
119
+ # if it's an unknown type, just escape it without attempting to parse anything
120
+ unescape value_str
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 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
+ module Gapic
18
+ module Schema
19
+ # Encapsulates information that is parsed from a single command line parameter
20
+ # from the plugin_opt command line
21
+ class RequestParameter
22
+ attr_reader :input_str, :input_name, :input_value, :config_name, :config_value
23
+
24
+ # @param input_str [String] the input string containing parameter and value
25
+ # that the parameter and value were parsed from
26
+ # @param input_name [String] the name of the parameter as found in the input
27
+ # can be an alias to a known config parameter name
28
+ # @param input_value [String] the unescaped input value of the parameter as found in the input
29
+ # @param config_name [String] the known config parameter name as matched during parsing
30
+ # @param config_value [String,Array,Hash] the parsed and deserialized config value
31
+ def initialize input_str, input_name, input_value, config_name, config_value
32
+ @input_str = input_str
33
+ @input_name = input_name
34
+ @input_value = input_value
35
+ @config_name = config_name
36
+ @config_value = config_value
37
+ end
38
+
39
+ # The hash of input name-value
40
+ # @return [Hash {String => String}]
41
+ def to_input_h
42
+ { input_name => input_value }
43
+ end
44
+
45
+ # The hash of config name-value
46
+ # @return [Hash {String => String, Array, Hash}]
47
+ def to_config_h
48
+ { config_name => config_value }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,2 @@
1
+ <%- assert_locals gem -%>
2
+ <%= gem.first_package_drift_json %>
@@ -25,6 +25,8 @@ Metrics/PerceivedComplexity:
25
25
  Naming/FileName:
26
26
  Exclude:
27
27
  - "lib/<%= gem.name %>.rb"
28
+ Naming/PredicateName:
29
+ Enabled: false
28
30
  Style/AsciiComments:
29
31
  Enabled: false
30
32
  Style/CaseEquality:
@@ -15,3 +15,7 @@ require "<%= package.gem.version_require %>"
15
15
  <%- end -%>
16
16
  module <%= package.module_name %>
17
17
  end
18
+ <% @footer = capture do %>
19
+ helper_path = ::File.join __dir__, "<%= package.package_directory_name %>", "<%= package.helpers_file_name %>"
20
+ require "<%= package.helpers_require %>" if ::File.file? helper_path
21
+ <% end %>
@@ -1,3 +1,3 @@
1
1
  <%- assert_locals service -%>
2
- helper_path = ::File.join __dir__, "<%= service.service_directory_name%>", "helpers.rb"
2
+ helper_path = ::File.join __dir__, "<%= service.service_directory_name %>", "<%= service.helpers_file_name %>"
3
3
  require "<%= service.helpers_require %>" if ::File.file? helper_path
@@ -97,7 +97,13 @@ class <%= service.client_name %>
97
97
  # Create credentials
98
98
  credentials = @config.credentials
99
99
  <%- unless service.generic_endpoint? -%>
100
- credentials ||= Credentials.default scope: @config.scope
100
+ # Use self-signed JWT if the scope and endpoint are unchanged from default,
101
+ # 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 &&
104
+ !@config.endpoint.split(".").first.include?("-")
105
+ credentials ||= Credentials.default scope: @config.scope,
106
+ enable_self_signed_jwt: enable_self_signed_jwt
101
107
  if credentials.is_a?(String) || credentials.is_a?(Hash)
102
108
  credentials = Credentials.new credentials, scope: @config.scope
103
109
  end
@@ -127,7 +127,7 @@ class Configuration
127
127
  # Each configuration object is of type `Gapic::Config::Method` and includes
128
128
  # the following configuration fields:
129
129
  #
130
- # * `timeout` (*type:* `Numeric`) - The call timeout in milliseconds
130
+ # * `timeout` (*type:* `Numeric`) - The call timeout in seconds
131
131
  # * `metadata` (*type:* `Hash{Symbol=>String}`) - Additional gRPC headers
132
132
  # * `retry_policy (*type:* `Hash`) - The retry policy. The policy fields
133
133
  # include the following keys:
@@ -87,13 +87,13 @@ def test_<%= method.name %>
87
87
  assert_kind_of <%= method.request_type %>, r
88
88
  <%- fields.each do |field| -%>
89
89
  <%- if field.message? && field.repeated? && !field.map? -%>
90
- assert_kind_of <%= field.type_name_full %>, r.<%= field.name %>.first
90
+ assert_kind_of <%= field.type_name_full %>, r["<%= field.name %>"].first
91
91
  <%- elsif field.map? -%>
92
- assert_equal(<%= field.default_value %>, r.<%= field.name %>.to_h)
92
+ assert_equal(<%= field.default_value %>, r["<%= field.name %>"].to_h)
93
93
  <%- elsif field.message? -%>
94
- assert_equal Gapic::Protobuf.coerce(<%= field.default_value %>, to: <%= field.type_name_full %>), r.<%= field.name %>
94
+ assert_equal Gapic::Protobuf.coerce(<%= field.default_value %>, to: <%= field.type_name_full %>), r["<%= field.name %>"]
95
95
  <%- else -%>
96
- assert_equal <%= field.default_value %>, r.<%= field.name %>
96
+ assert_equal <%= field.default_value %>, r["<%= field.name %>"]
97
97
  <%- end -%>
98
98
  <%- if field.oneof? && !field.proto3_optional? -%>
99
99
  assert_equal :<%= field.name %>, r.<%= field.oneof_name %>
@@ -71,13 +71,13 @@ def test_<%= method.name %>
71
71
  assert_kind_of <%= method.request_type %>, r
72
72
  <%- fields.each do |field| -%>
73
73
  <%- if field.message? && field.repeated? && !field.map? -%>
74
- assert_kind_of <%= field.type_name_full %>, r.<%= field.name %>.first
74
+ assert_kind_of <%= field.type_name_full %>, r["<%= field.name %>"].first
75
75
  <%- elsif field.map? -%>
76
- assert_equal(<%= field.default_value %>, r.<%= field.name %>.to_h)
76
+ assert_equal(<%= field.default_value %>, r["<%= field.name %>"].to_h)
77
77
  <%- elsif field.message? -%>
78
- assert_equal Gapic::Protobuf.coerce(<%= field.default_value %>, to: <%= field.type_name_full %>), r.<%= field.name %>
78
+ assert_equal Gapic::Protobuf.coerce(<%= field.default_value %>, to: <%= field.type_name_full %>), r["<%= field.name %>"]
79
79
  <%- else -%>
80
- assert_equal <%= field.default_value %>, r.<%= field.name %>
80
+ assert_equal <%= field.default_value %>, r["<%= field.name %>"]
81
81
  <%- end -%>
82
82
  <%- if field.oneof? && !field.proto3_optional? -%>
83
83
  assert_equal :<%= field.name %>, r.<%= field.oneof_name %>
@@ -18,13 +18,13 @@ def test_<%= method.name %>
18
18
  assert_kind_of <%= method.request_type %>, request
19
19
  <%- fields.each do |field| -%>
20
20
  <%- if field.message? && field.repeated? && !field.map? -%>
21
- assert_kind_of <%= field.type_name_full %>, request.<%= field.name %>.first
21
+ assert_kind_of <%= field.type_name_full %>, request["<%= field.name %>"].first
22
22
  <%- elsif field.map? -%>
23
- assert_equal(<%= field.default_value %>, request.<%= field.name %>.to_h)
23
+ assert_equal(<%= field.default_value %>, request["<%= field.name %>"].to_h)
24
24
  <%- elsif field.message? -%>
25
- assert_equal Gapic::Protobuf.coerce(<%= field.default_value %>, to: <%= field.type_name_full %>), request.<%= field.name %>
25
+ assert_equal Gapic::Protobuf.coerce(<%= field.default_value %>, to: <%= field.type_name_full %>), request["<%= field.name %>"]
26
26
  <%- else -%>
27
- assert_equal <%= field.default_value %>, request.<%= field.name %>
27
+ assert_equal <%= field.default_value %>, request["<%= field.name %>"]
28
28
  <%- end -%>
29
29
  <%- if field.oneof? && !field.proto3_optional? -%>
30
30
  assert_equal :<%= field.name %>, request.<%= field.oneof_name %>
@@ -18,13 +18,13 @@ def test_<%= method.name %>
18
18
  assert_kind_of <%= method.request_type %>, request
19
19
  <%- fields.each do |field| -%>
20
20
  <%- if field.message? && field.repeated? && !field.map? -%>
21
- assert_kind_of <%= field.type_name_full %>, request.<%= field.name %>.first
21
+ assert_kind_of <%= field.type_name_full %>, request["<%= field.name %>"].first
22
22
  <%- elsif field.map? -%>
23
- assert_equal(<%= field.default_value %>, request.<%= field.name %>.to_h)
23
+ assert_equal(<%= field.default_value %>, request["<%= field.name %>"].to_h)
24
24
  <%- elsif field.message? -%>
25
- assert_equal Gapic::Protobuf.coerce(<%= field.default_value %>, to: <%= field.type_name_full %>), request.<%= field.name %>
25
+ assert_equal Gapic::Protobuf.coerce(<%= field.default_value %>, to: <%= field.type_name_full %>), request["<%= field.name %>"]
26
26
  <%- else -%>
27
- assert_equal <%= field.default_value %>, request.<%= field.name %>
27
+ assert_equal <%= field.default_value %>, request["<%= field.name %>"]
28
28
  <%- end -%>
29
29
  <%- if field.oneof? && !field.proto3_optional? -%>
30
30
  assert_equal :<%= field.name %>, request.<%= field.oneof_name %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gapic-generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.8
4
+ version: 0.6.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ernest Landrito
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-09-16 00:00:00.000000000 Z
13
+ date: 2021-02-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: actionpack
@@ -196,6 +196,7 @@ files:
196
196
  - lib/gapic/generator/version.rb
197
197
  - lib/gapic/generators/base_generator.rb
198
198
  - lib/gapic/generators/default_generator.rb
199
+ - lib/gapic/generators/default_generator_parameters.rb
199
200
  - lib/gapic/grpc_service_config/method_config.rb
200
201
  - lib/gapic/grpc_service_config/parser.rb
201
202
  - lib/gapic/grpc_service_config/parsing_error.rb
@@ -225,6 +226,9 @@ files:
225
226
  - lib/gapic/schema.rb
226
227
  - lib/gapic/schema/api.rb
227
228
  - lib/gapic/schema/loader.rb
229
+ - lib/gapic/schema/parameter_schema.rb
230
+ - lib/gapic/schema/request_param_parser.rb
231
+ - lib/gapic/schema/request_parameter.rb
228
232
  - lib/gapic/schema/wrappers.rb
229
233
  - lib/gapic/uri_template.rb
230
234
  - lib/gapic/uri_template/parser.rb
@@ -242,6 +246,7 @@ files:
242
246
  - templates/default/gem/_version.erb
243
247
  - templates/default/gem/changelog.erb
244
248
  - templates/default/gem/entrypoint.erb
249
+ - templates/default/gem/gapic_metadata_json.erb
245
250
  - templates/default/gem/gemfile.erb
246
251
  - templates/default/gem/gemspec.erb
247
252
  - templates/default/gem/gitignore.erb
@@ -343,7 +348,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
343
348
  - !ruby/object:Gem::Version
344
349
  version: '0'
345
350
  requirements: []
346
- rubygems_version: 3.0.3
351
+ rubygems_version: 3.1.4
347
352
  signing_key:
348
353
  specification_version: 4
349
354
  summary: An API Client Generator for Ruby in Ruby!