gapic-generator 0.6.5 → 0.6.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27e2894595efed8561aa48e9059465257267e7f29310a806251bcc6d4d85c63f
4
- data.tar.gz: af47f16264074317a8d02e73539208a4b43f565ae346aef480619bc73a6b1203
3
+ metadata.gz: 4fd38043485e7ffbb2e8edf375019429972c5ac01b8be85803c5f6f9518b06c5
4
+ data.tar.gz: 23312fda7203a549f3e2f714df2ef73a0d71aea1aae369104de8ba079d4746c1
5
5
  SHA512:
6
- metadata.gz: eacd1840fadb1236cb5ed7efe7ba254a977529435ee7ddff1fcee7bb900fa847ccc0a3b861098f1292a63f72e82f6065146f1f0a0260b0624dc9a184de3d3389
7
- data.tar.gz: 8a93aaef7317b85fc048604b626af4cef13cf90ea2dd785a12180d94d71dbf0bc4ea24a34c828a04825adcfd4ae2b88e4cc3934d41de7de01b3be27f6302aaba
6
+ metadata.gz: cef8f93df7ca8b3207815a9c8239eeea6fb783265943d6ec22b246945582df439ddad1419a1783df8c0c1a3e432194a8ddb204c08856ac67dce5abb030ede394
7
+ data.tar.gz: 82df4fc573990154f629711aa9829d0c8aa6aacb2df34bcff9cff140dd5049de1f135325c5df089ca9b6b9188fae415e1bad351df8e6904bc1e071c0ae3ee63b
@@ -1,5 +1,29 @@
1
1
  # Release History for gapic-generator
2
2
 
3
+ ### 0.6.10 / 2021-01-13
4
+
5
+ * 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`.
6
+ * 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.
7
+
8
+ ### 0.6.9 / 2020-12-07
9
+
10
+ * Load package-level handwritten helpers.
11
+ * Disable Names/PredicateName rubocop rule.
12
+ * Fix generated client tests when a request field name collides with a Ruby superclass method.
13
+
14
+ ### 0.6.8 / 2020-09-16
15
+
16
+ * Add samples tasks to generated gapic rakefiles.
17
+ * Disable Style/AsciiComments rule.
18
+
19
+ ### 0.6.7 / 2020-08-07
20
+
21
+ * Generated credentials config allows symbols.
22
+
23
+ ### 0.6.6 / 2020-08-05
24
+
25
+ * Use numeric error codes rather than strings in generated retry configs.
26
+
3
27
  ### 0.6.5 / 2020-07-16
4
28
 
5
29
  * Examples in auth, rakefile, and readme should pick a non-common service.
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Gapic
18
18
  module Generator
19
- VERSION = "0.6.5"
19
+ VERSION = "0.6.10"
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
@@ -89,6 +90,12 @@ module Gapic
89
90
 
90
91
  # rubocop:enable all
91
92
 
93
+ # Schema of the parameters that the generator accepts
94
+ # @return [Gapic::Schema::ParameterSchema]
95
+ def self.parameter_schema
96
+ DefaultGeneratorParameters.default_schema
97
+ end
98
+
92
99
  private
93
100
 
94
101
  ##
@@ -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
@@ -40,6 +40,31 @@ module Gapic
40
40
  MULTIPLIER_JSON_KEY = "backoffMultiplier"
41
41
  STATUS_CODES_JSON_KEY = "retryableStatusCodes"
42
42
 
43
+ # See https://grpc.github.io/grpc/core/md_doc_statuscodes.html for a
44
+ # list of error codes.
45
+ ERROR_CODE_MAPPING = [
46
+ "OK",
47
+ "CANCELLED",
48
+ "UNKNOWN",
49
+ "INVALID_ARGUMENT",
50
+ "DEADLINE_EXCEEDED",
51
+ "NOT_FOUND",
52
+ "ALREADY_EXISTS",
53
+ "PERMISSION_DENIED",
54
+ "RESOURCE_EXHAUSTED",
55
+ "FAILED_PRECONDITION",
56
+ "ABORTED",
57
+ "OUT_OF_RANGE",
58
+ "UNIMPLEMENTED",
59
+ "INTERNAL",
60
+ "UNAVAILABLE",
61
+ "DATA_LOSS",
62
+ "UNAUTHENTICATED"
63
+ ].freeze
64
+
65
+ ERROR_STRING_MAPPING = ERROR_CODE_MAPPING.each_with_index.each_with_object({}) do |(str, num), hash|
66
+ hash[str] = num
67
+ end.freeze
43
68
 
44
69
  ##
45
70
  # Parses ServiceConfig from a json of a GRPC service config
@@ -146,11 +171,26 @@ module Gapic
146
171
  initial_delay_seconds = parse_interval_seconds get(retry_policy_json, INITIAL_DELAY_JSON_KEY)
147
172
  max_delay_seconds = parse_interval_seconds get(retry_policy_json, MAX_DELAY_JSON_KEY)
148
173
  multiplier = get retry_policy_json, MULTIPLIER_JSON_KEY
149
- status_codes = get retry_policy_json, STATUS_CODES_JSON_KEY
174
+ status_codes = convert_codes get retry_policy_json, STATUS_CODES_JSON_KEY
150
175
 
151
176
  RetryPolicy.new initial_delay_seconds, max_delay_seconds, multiplier, status_codes
152
177
  end
153
178
 
179
+ ##
180
+ # Interpret input status codes. Convert strings to their associated integer codes.
181
+ #
182
+ def self.convert_codes input_codes
183
+ return nil if input_codes.nil?
184
+ Array(input_codes).map do |obj|
185
+ case obj
186
+ when String
187
+ ERROR_STRING_MAPPING[obj]
188
+ when Integer
189
+ obj
190
+ end
191
+ end.compact
192
+ end
193
+
154
194
  ##
155
195
  # Parses time expressed in secondds from the GRPC service config json
156
196
  # The time is encoded is a string as float or integer with a letter 's' afterwards
@@ -212,7 +252,7 @@ module Gapic
212
252
  end
213
253
 
214
254
  private_class_method :parse_service_names, :filter_service_method_names, :parse_config,
215
- :parse_retry_policy, :parse_interval_seconds, :valid_float?
255
+ :parse_retry_policy, :parse_interval_seconds, :valid_float?, :convert_codes
216
256
  end
217
257
  end
218
258
  end
@@ -80,9 +80,25 @@ 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
86
102
  end
87
103
  end
88
104
  end
@@ -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
@@ -25,6 +25,10 @@ Metrics/PerceivedComplexity:
25
25
  Naming/FileName:
26
26
  Exclude:
27
27
  - "lib/<%= gem.name %>.rb"
28
+ Naming/PredicateName:
29
+ Enabled: false
30
+ Style/AsciiComments:
31
+ Enabled: false
28
32
  Style/CaseEquality:
29
33
  Enabled: false
30
34
  Style/IfUnlessModifier:
@@ -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
@@ -87,7 +87,7 @@ class Configuration
87
87
 
88
88
  config_attr :endpoint, <%= service.client_endpoint.inspect %>, ::String
89
89
  config_attr :credentials, nil do |value|
90
- allowed = [::String, ::Hash, ::Proc, ::Google::Auth::Credentials, ::Signet::OAuth2::Client, nil]
90
+ allowed = [::String, ::Hash, ::Proc, ::Symbol, ::Google::Auth::Credentials, ::Signet::OAuth2::Client, nil]
91
91
  allowed += [::GRPC::Core::Channel, ::GRPC::Core::ChannelCredentials] if defined? ::GRPC
92
92
  allowed.any? { |klass| klass === value }
93
93
  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.5
4
+ version: 0.6.10
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-07-20 00:00:00.000000000 Z
13
+ date: 2021-01-14 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
@@ -343,7 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
343
347
  - !ruby/object:Gem::Version
344
348
  version: '0'
345
349
  requirements: []
346
- rubygems_version: 3.0.3
350
+ rubygems_version: 3.1.2
347
351
  signing_key:
348
352
  specification_version: 4
349
353
  summary: An API Client Generator for Ruby in Ruby!