grpc-rest 0.1.24 → 0.2.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/CI.yml +2 -41
  3. data/.rubocop.yml +3 -0
  4. data/CHANGELOG +6 -1
  5. data/Gemfile +3 -1
  6. data/Gemfile.lock +21 -10
  7. data/README.md +7 -8
  8. data/bin/protoc-gen-rails +6 -0
  9. data/grpc-rest.gemspec +4 -1
  10. data/lib/generator/controller.rb.erb +27 -0
  11. data/lib/generator/grpc.rb.erb +9 -0
  12. data/lib/generator/method.rb +96 -0
  13. data/lib/generator/output.rb +28 -0
  14. data/lib/generator/plugin_pb.rb +25 -0
  15. data/lib/generator/service.rb +36 -0
  16. data/lib/generator.rb +88 -0
  17. data/lib/grpc_rest/version.rb +3 -1
  18. data/lib/grpc_rest.rb +40 -38
  19. data/{protoc-gen-rails/testdata/base/app/controllers/my_service_controller.rb → spec/__snapshots__/service.snap} +33 -27
  20. data/spec/base_interceptor_spec.rb +6 -3
  21. data/spec/{protoc-gen-openapiv2 → gen/protoc-gen-openapiv2}/options/annotations_pb.rb +5 -4
  22. data/spec/{protoc-gen-openapiv2 → gen/protoc-gen-openapiv2}/options/openapiv2_pb.rb +30 -29
  23. data/spec/gen/test_pb.rb +15 -0
  24. data/spec/gen/test_service_pb.rb +23 -0
  25. data/spec/gen/test_service_services_pb.rb +26 -0
  26. data/spec/generator_spec.rb +49 -0
  27. data/spec/grpc_rest_spec.rb +71 -25
  28. data/spec/gruf_spec.rb +4 -3
  29. data/spec/spec_helper.rb +8 -6
  30. data/spec/test_service_pb.rb +1 -1
  31. data/spec/test_service_services_pb.rb +2 -1
  32. data/spec/testdata/base/app/controllers/my_service_controller.rb +65 -0
  33. data/spec/testdata/no_service/.keep +0 -0
  34. data/{protoc-gen-rails → spec}/testdata/test_service.proto +1 -0
  35. metadata +90 -26
  36. data/protoc-gen-rails/.goreleaser.yml +0 -27
  37. data/protoc-gen-rails/LICENSE +0 -21
  38. data/protoc-gen-rails/go.mod +0 -25
  39. data/protoc-gen-rails/go.sum +0 -49
  40. data/protoc-gen-rails/internal/output.go +0 -165
  41. data/protoc-gen-rails/internal/parse.go +0 -101
  42. data/protoc-gen-rails/internal/utils.go +0 -57
  43. data/protoc-gen-rails/main.go +0 -104
  44. data/protoc-gen-rails/main_test.go +0 -158
  45. /data/{protoc-gen-rails/testdata/no_service/.keep → spec/__snapshots__/no_service.snap} +0 -0
  46. /data/{protoc-gen-rails → spec}/google-deps/google/api/annotations.proto +0 -0
  47. /data/{protoc-gen-rails → spec}/google-deps/google/api/http.proto +0 -0
  48. /data/{protoc-gen-rails → spec}/google-deps/protoc-gen-openapiv2/options/annotations.proto +0 -0
  49. /data/{protoc-gen-rails → spec}/google-deps/protoc-gen-openapiv2/options/openapiv2.proto +0 -0
  50. /data/{protoc-gen-rails → spec}/testdata/base/config/routes/grpc.rb +0 -0
  51. /data/{protoc-gen-rails → spec}/testdata/test.proto +0 -0
data/lib/grpc_rest.rb CHANGED
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'google/protobuf/well_known_types'
2
4
  require 'grpc'
3
5
  require 'grpc/core/status_codes'
4
6
 
5
7
  module GrpcRest
6
8
  class << self
7
-
8
9
  def underscore(s)
9
10
  GRPC::GenericService.underscore(s)
10
11
  end
@@ -39,7 +40,7 @@ module GrpcRest
39
40
 
40
41
  # https://stackoverflow.com/a/2158473/5199431
41
42
  def longest_common_substring(arr)
42
- return "" if arr.empty?
43
+ return '' if arr.empty?
43
44
 
44
45
  result = 0
45
46
  first_val = arr[0]
@@ -48,6 +49,7 @@ module GrpcRest
48
49
  character = first_val[k]
49
50
  arr.each { |str| all_matched &= (character == str[k]) }
50
51
  break unless all_matched
52
+
51
53
  result += 1
52
54
  end
53
55
  first_val.slice(0, result)
@@ -64,14 +66,12 @@ module GrpcRest
64
66
  end
65
67
 
66
68
  def map_proto_type(descriptor, val)
67
- if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
68
- return handle_enum_values(descriptor, val)
69
- end
69
+ return handle_enum_values(descriptor, val) if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
70
70
 
71
71
  case descriptor.type
72
- when *%i(int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64)
72
+ when :int32, :int64, :uint32, :uint64, :sint32, :sint64, :fixed32, :fixed64, :sfixed32, :sfixed64
73
73
  return val.to_i
74
- when *%i(float double)
74
+ when :float, :double
75
75
  return val.to_f
76
76
  when :bool
77
77
  return !!val
@@ -79,19 +79,18 @@ module GrpcRest
79
79
 
80
80
  case descriptor.subtype&.name
81
81
  when 'google.protobuf.Struct'
82
- return Google::Protobuf::Struct.from_hash(val)
82
+ Google::Protobuf::Struct.from_hash(val)
83
83
  when 'google.protobuf.Timestamp'
84
- if val.is_a?(Numeric)
85
- return Google::Protobuf::Timestamp.from_time(Time.at(val))
86
- else
87
- return Google::Protobuf::Timestamp.from_time(Time.new(val))
88
- end
84
+ return Google::Protobuf::Timestamp.from_time(Time.at(val)) if val.is_a?(Numeric)
85
+
86
+ Google::Protobuf::Timestamp.from_time(Time.new(val))
87
+
89
88
  when 'google.protobuf.Value'
90
- return Google::Protobuf::Value.from_ruby(val)
89
+ Google::Protobuf::Value.from_ruby(val)
91
90
  when 'google.protobuf.ListValue'
92
- return Google::Protobuf::ListValue.from_a(val)
91
+ Google::Protobuf::ListValue.from_a(val)
93
92
  else
94
- return map_proto_record(descriptor.subtype, val)
93
+ map_proto_record(descriptor.subtype, val)
95
94
  end
96
95
  end
97
96
 
@@ -102,11 +101,16 @@ module GrpcRest
102
101
  next if val.nil?
103
102
 
104
103
  if descriptor.label == :repeated
105
- params[field] = val.map { |v| map_proto_type(descriptor, v) }
104
+ # leave map entries as key => value
105
+ unless descriptor.subtype&.options&.to_h&.dig(:map_entry)
106
+ params[field] = val.map { |v| map_proto_type(descriptor, v) }
107
+ end
106
108
  else
107
109
  params[field] = map_proto_type(descriptor, val)
108
110
  end
109
111
  end
112
+
113
+
110
114
  params
111
115
  end
112
116
 
@@ -132,10 +136,10 @@ module GrpcRest
132
136
  end
133
137
  assign_value(request, entry[:name], value_to_use)
134
138
  end
135
- if body_string.present? && body_string != '*'
136
- # we need to "splat" the body parameters into the given sub-record rather than into the top-level.
137
- sub_record = sub_field(request, body_string, parameters)
138
- end
139
+ return unless body_string.present? && body_string != '*'
140
+
141
+ # we need to "splat" the body parameters into the given sub-record rather than into the top-level.
142
+ sub_field(request, body_string, parameters)
139
143
  end
140
144
 
141
145
  # Ported from https://github.com/grpc-ecosystem/grpc-gateway/blob/main/runtime/errors.go#L36
@@ -171,25 +175,26 @@ module GrpcRest
171
175
  end
172
176
 
173
177
  def error_msg(error)
178
+ Rails.logger.error("#{error.message}, backtrace: #{error.backtrace.join("\n")}")
174
179
  if error.respond_to?(:code)
175
- {
180
+ {
176
181
  code: error.code,
177
182
  message: error.message,
178
183
  details: [
179
- {
180
- backtrace: error.backtrace
181
- }
184
+ {
185
+ backtrace: error.backtrace
186
+ }
182
187
  ]
183
- }
188
+ }
184
189
  else
185
190
  {
186
- code: 3,
187
- message: "InvalidArgument: #{error.message}",
188
- details: [
189
- {
190
- backtrace: error.backtrace
191
- }
192
- ]
191
+ code: 3,
192
+ message: "InvalidArgument: #{error.message}",
193
+ details: [
194
+ {
195
+ backtrace: error.backtrace
196
+ }
197
+ ]
193
198
  }
194
199
  end
195
200
  end
@@ -228,14 +233,12 @@ module GrpcRest
228
233
  klass = ::Gruf::Controllers::Base.subclasses.find do |k|
229
234
  k.bound_service == service_obj
230
235
  end
231
- if klass
232
- return send_gruf_request(klass, service_obj, method, request)
233
- end
236
+ return send_gruf_request(klass, service_obj, method, request) if klass
234
237
  end
235
238
  send_grpc_request(service, method, request)
236
239
  end
237
240
 
238
- def send_request(service, method, request, options={})
241
+ def send_request(service, method, request, options = {})
239
242
  response = get_response(service, method, request)
240
243
  if options[:emit_defaults]
241
244
  response.to_json(emit_defaults: true)
@@ -244,5 +247,4 @@ module GrpcRest
244
247
  end
245
248
  end
246
249
  end
247
-
248
250
  end
@@ -1,4 +1,4 @@
1
-
1
+ spec/app/app/controllers/my_service_controller.rb:
2
2
  ####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
3
3
 
4
4
  require 'grpc_rest'
@@ -14,54 +14,60 @@ class MyServiceController < ActionController::Base
14
14
  rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
15
15
  render json: GrpcRest.error_msg(e), status: :bad_request
16
16
  end
17
+ METHOD_PARAM_MAP = {"test"=>[{:name=>"foobar", :val=>"=blah/*", :split_name=>["foobar"]}],
18
+ "test2"=>[],
19
+ "test3"=>
20
+ [{:name=>"sub_record.sub_id",
21
+ :val=>"",
22
+ :split_name=>["sub_record", "sub_id"]}],
23
+ "test4"=>[]}
24
+ .freeze
17
25
 
18
- METHOD_PARAM_MAP = {
19
-
20
- "test" => [
21
- {name: "foobar", val: "blah/*", split_name:["foobar"]},
22
- ],
23
-
24
- "test_2" => [
25
- ],
26
-
27
- "test_3" => [
28
- {name: "sub_record.sub_id", val: nil, split_name:["sub_record","sub_id"]},
29
- ],
30
-
31
- "test_4" => [
32
- ],
33
- }.freeze
34
26
 
35
27
  def test
36
28
  fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
37
29
  parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
38
30
  grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters.slice(*fields))
39
31
  GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test"], "", request.parameters)
40
- render json: GrpcRest.send_request("Testdata::MyService", "test", grpc_request, {emit_defaults: true})
32
+ render json: GrpcRest.send_request("Testdata::MyService", "test", grpc_request, {:emit_defaults=>true})
41
33
  end
42
34
 
43
- def test_2
35
+ def test2
44
36
  fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
45
37
  parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
46
38
  grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters.slice(*fields))
47
- GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test_2"], "second_record", request.parameters)
48
- render json: GrpcRest.send_request("Testdata::MyService", "test_2", grpc_request, {})
39
+ GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test2"], "second_record", request.parameters)
40
+ render json: GrpcRest.send_request("Testdata::MyService", "test2", grpc_request, {})
49
41
  end
50
42
 
51
- def test_3
43
+ def test3
52
44
  fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
53
45
  parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
54
46
  grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters.slice(*fields))
55
- GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test_3"], "", request.parameters)
56
- render json: GrpcRest.send_request("Testdata::MyService", "test_3", grpc_request, {})
47
+ GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test3"], "", request.parameters)
48
+ render json: GrpcRest.send_request("Testdata::MyService", "test3", grpc_request, {})
57
49
  end
58
50
 
59
- def test_4
51
+ def test4
60
52
  fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
61
53
  parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
62
54
  grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters.slice(*fields))
63
- GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test_4"], "*", request.parameters)
64
- render json: GrpcRest.send_request("Testdata::MyService", "test_4", grpc_request, {})
55
+ GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test4"], "*", request.parameters)
56
+ render json: GrpcRest.send_request("Testdata::MyService", "test4", grpc_request, {})
65
57
  end
66
58
 
67
59
  end
60
+
61
+
62
+ spec/app/config/routes/grpc.rb:
63
+ # frozen_string_literal: true
64
+
65
+ ####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
66
+
67
+
68
+ get '/test/*foobar' => 'my_service#test'
69
+ post '/test2' => 'my_service#test2'
70
+ post '/test3/*sub_id' => 'my_service#test3'
71
+ post '/test4' => 'my_service#test4'
72
+
73
+
@@ -5,7 +5,7 @@ require 'src/proto/grpc/testing/test_services_pb'
5
5
 
6
6
  RSpec.describe GrpcRest::BaseInterceptor, type: :class do
7
7
  let(:rpc_service) { Grpc::Testing::TestService::Service.new }
8
- let(:rpc_desc) { Grpc::Testing::TestService::Service.rpc_descs.values.first}
8
+ let(:rpc_desc) { Grpc::Testing::TestService::Service.rpc_descs.values.first }
9
9
  let(:message) { Grpc::Testing::SimpleRequest.new }
10
10
 
11
11
  describe '#fail!' do
@@ -18,10 +18,13 @@ RSpec.describe GrpcRest::BaseInterceptor, type: :class do
18
18
  service: rpc_service,
19
19
  rpc_desc: rpc_desc,
20
20
  active_call: nil,
21
- message: message)
21
+ message: message
22
+ )
22
23
  interceptor = GrpcRest::BaseInterceptor.new(request, Gruf::Error.new)
23
24
 
24
- expect{ interceptor.fail!(error_code, error_code, error_message) }.to raise_error(GRPC::InvalidArgument) do |error|
25
+ expect do
26
+ interceptor.fail!(error_code, error_code, error_message)
27
+ end.to raise_error(GRPC::InvalidArgument) do |error|
25
28
  expect(error.message).to match(error_message)
26
29
  expect(error.code).to eq(GRPC::Core::StatusCodes::INVALID_ARGUMENT)
27
30
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
4
  # source: protoc-gen-openapiv2/options/annotations.proto
4
5
 
@@ -15,7 +16,7 @@ pool = Google::Protobuf::DescriptorPool.generated_pool
15
16
 
16
17
  begin
17
18
  pool.add_serialized_file(descriptor_data)
18
- rescue TypeError => e
19
+ rescue TypeError
19
20
  # Compatibility code: will be removed in the next major version.
20
21
  require 'google/protobuf/descriptor_pb'
21
22
  parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
@@ -24,7 +25,7 @@ rescue TypeError => e
24
25
  file = pool.add_serialized_file(serialized)
25
26
  warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
26
27
  imports = [
27
- ["grpc.gateway.protoc_gen_openapiv2.options.Swagger", "protoc-gen-openapiv2/options/openapiv2.proto"],
28
+ ['grpc.gateway.protoc_gen_openapiv2.options.Swagger', 'protoc-gen-openapiv2/options/openapiv2.proto']
28
29
  ]
29
30
  imports.each do |type_name, expected_filename|
30
31
  import_file = pool.lookup(type_name).file_descriptor
@@ -32,8 +33,8 @@ rescue TypeError => e
32
33
  warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
33
34
  end
34
35
  end
35
- warn "Each proto file must use a consistent fully-qualified name."
36
- warn "This will become an error in the next major version."
36
+ warn 'Each proto file must use a consistent fully-qualified name.'
37
+ warn 'This will become an error in the next major version.'
37
38
  end
38
39
 
39
40
  module Grpc
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
4
  # source: protoc-gen-openapiv2/options/openapiv2.proto
4
5
 
@@ -14,7 +15,7 @@ pool = Google::Protobuf::DescriptorPool.generated_pool
14
15
 
15
16
  begin
16
17
  pool.add_serialized_file(descriptor_data)
17
- rescue TypeError => e
18
+ rescue TypeError
18
19
  # Compatibility code: will be removed in the next major version.
19
20
  require 'google/protobuf/descriptor_pb'
20
21
  parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
@@ -23,7 +24,7 @@ rescue TypeError => e
23
24
  file = pool.add_serialized_file(serialized)
24
25
  warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
25
26
  imports = [
26
- ["google.protobuf.Value", "google/protobuf/struct.proto"],
27
+ ['google.protobuf.Value', 'google/protobuf/struct.proto']
27
28
  ]
28
29
  imports.each do |type_name, expected_filename|
29
30
  import_file = pool.lookup(type_name).file_descriptor
@@ -31,39 +32,39 @@ rescue TypeError => e
31
32
  warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
32
33
  end
33
34
  end
34
- warn "Each proto file must use a consistent fully-qualified name."
35
- warn "This will become an error in the next major version."
35
+ warn 'Each proto file must use a consistent fully-qualified name.'
36
+ warn 'This will become an error in the next major version.'
36
37
  end
37
38
 
38
39
  module Grpc
39
40
  module Gateway
40
41
  module ProtocGenOpenapiv2
41
42
  module Options
42
- Swagger = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Swagger").msgclass
43
- Operation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Operation").msgclass
44
- Parameters = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Parameters").msgclass
45
- HeaderParameter = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.HeaderParameter").msgclass
46
- HeaderParameter::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.HeaderParameter.Type").enummodule
47
- Header = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Header").msgclass
48
- Response = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Response").msgclass
49
- Info = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Info").msgclass
50
- Contact = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Contact").msgclass
51
- License = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.License").msgclass
52
- ExternalDocumentation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.ExternalDocumentation").msgclass
53
- Schema = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Schema").msgclass
54
- JSONSchema = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.JSONSchema").msgclass
55
- JSONSchema::FieldConfiguration = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.FieldConfiguration").msgclass
56
- JSONSchema::JSONSchemaSimpleTypes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.JSONSchemaSimpleTypes").enummodule
57
- Tag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Tag").msgclass
58
- SecurityDefinitions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions").msgclass
59
- SecurityScheme = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme").msgclass
60
- SecurityScheme::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Type").enummodule
61
- SecurityScheme::In = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.In").enummodule
62
- SecurityScheme::Flow = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Flow").enummodule
63
- SecurityRequirement = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement").msgclass
64
- SecurityRequirement::SecurityRequirementValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementValue").msgclass
65
- Scopes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Scopes").msgclass
66
- Scheme = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.gateway.protoc_gen_openapiv2.options.Scheme").enummodule
43
+ Swagger = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Swagger').msgclass
44
+ Operation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Operation').msgclass
45
+ Parameters = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Parameters').msgclass
46
+ HeaderParameter = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.HeaderParameter').msgclass
47
+ HeaderParameter::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.HeaderParameter.Type').enummodule
48
+ Header = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Header').msgclass
49
+ Response = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Response').msgclass
50
+ Info = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Info').msgclass
51
+ Contact = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Contact').msgclass
52
+ License = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.License').msgclass
53
+ ExternalDocumentation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.ExternalDocumentation').msgclass
54
+ Schema = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Schema').msgclass
55
+ JSONSchema = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.JSONSchema').msgclass
56
+ JSONSchema::FieldConfiguration = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.FieldConfiguration').msgclass
57
+ JSONSchema::JSONSchemaSimpleTypes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.JSONSchemaSimpleTypes').enummodule
58
+ Tag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Tag').msgclass
59
+ SecurityDefinitions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions').msgclass
60
+ SecurityScheme = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme').msgclass
61
+ SecurityScheme::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Type').enummodule
62
+ SecurityScheme::In = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.In').enummodule
63
+ SecurityScheme::Flow = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Flow').enummodule
64
+ SecurityRequirement = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement').msgclass
65
+ SecurityRequirement::SecurityRequirementValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementValue').msgclass
66
+ Scopes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Scopes').msgclass
67
+ Scheme = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Scheme').enummodule
67
68
  end
68
69
  end
69
70
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
4
+ # source: test.proto
5
+
6
+ require 'google/protobuf'
7
+
8
+ descriptor_data = "\n\ntest.proto\x12\x04test\"\x14\n\x04Test\x12\x0c\n\x04test\x18\x01 \x01(\tb\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Test
14
+ Test = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('test.Test').msgclass
15
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
4
+ # source: test_service.proto
5
+
6
+ require 'google/protobuf'
7
+
8
+ require 'google/api/annotations_pb'
9
+ require 'google/protobuf/struct_pb'
10
+ require 'google/protobuf/timestamp_pb'
11
+ require 'protoc-gen-openapiv2/options/annotations_pb'
12
+
13
+ descriptor_data = "\n\x12test_service.proto\x12\x08testdata\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\xd7\x03\n\x0bTestRequest\x12\x0f\n\x07test_id\x18\x01 \x01(\t\x12\x0e\n\x06\x66oobar\x18\x02 \x01(\t\x12\x17\n\x0frepeated_string\x18\x03 \x03(\t\x12\'\n\nsub_record\x18\x04 \x01(\x0b\x32\x13.testdata.SubRecord\x12*\n\rsecond_record\x18\x05 \x01(\x0b\x32\x13.testdata.SubRecord\x12-\n\x0cstruct_field\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x33\n\x0ftimestamp_field\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nlist_value\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.ListValue\x12*\n\nbare_value\x18\t \x01(\x0b\x32\x16.google.protobuf.Value\x12(\n\x0bsub_records\x18\n \x03(\x0b\x32\x13.testdata.SubRecord\x12\x10\n\x08some_int\x18\x0b \x01(\x05\x12%\n\tsome_enum\x18\x0c \x01(\x0e\x32\x12.testdata.TestEnum\x12\x16\n\x0erepeated_float\x18\r \x03(\x02\"/\n\tSubRecord\x12\x0e\n\x06sub_id\x18\x01 \x01(\t\x12\x12\n\nanother_id\x18\x02 \x01(\t\"L\n\x0cTestResponse\x12\x10\n\x08some_int\x18\x01 \x01(\x05\x12\x15\n\rfull_response\x18\x02 \x01(\t\x12\x13\n\x0bignored_key\x18\x03 \x01(\t*K\n\x08TestEnum\x12\x19\n\x15TEST_ENUM_UNSPECIFIED\x10\x00\x12\x11\n\rTEST_ENUM_FOO\x10\x01\x12\x11\n\rTEST_ENUM_BAR\x10\x02\x32\x83\x03\n\tMyService\x12x\n\x04Test\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"A\x92\x41!j\x1f\n\x19x-grpc-rest-emit-defaults\x12\x02 \x01\x82\xd3\xe4\x93\x02\x17\x12\x15/test/{foobar=blah/*}\x12U\n\x05Test2\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x06/test2:\rsecond_record\x12Z\n\x05Test3\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\"\x82\xd3\xe4\x93\x02\x1c\"\x1a/test3/{sub_record.sub_id}\x12I\n\x05Test4\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x11\x82\xd3\xe4\x93\x02\x0b\"\x06/test4:\x01*b\x06proto3"
14
+
15
+ pool = Google::Protobuf::DescriptorPool.generated_pool
16
+ pool.add_serialized_file(descriptor_data)
17
+
18
+ module Testdata
19
+ TestRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('testdata.TestRequest').msgclass
20
+ SubRecord = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('testdata.SubRecord').msgclass
21
+ TestResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('testdata.TestResponse').msgclass
22
+ TestEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('testdata.TestEnum').enummodule
23
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
4
+ # Source: test_service.proto for package 'testdata'
5
+
6
+ require 'grpc'
7
+ require 'test_service_pb'
8
+
9
+ module Testdata
10
+ module MyService
11
+ class Service
12
+ include ::GRPC::GenericService
13
+
14
+ self.marshal_class_method = :encode
15
+ self.unmarshal_class_method = :decode
16
+ self.service_name = 'testdata.MyService'
17
+
18
+ rpc :Test, ::Testdata::TestRequest, ::Testdata::TestResponse
19
+ rpc :Test2, ::Testdata::TestRequest, ::Testdata::TestResponse
20
+ rpc :Test3, ::Testdata::TestRequest, ::Testdata::TestResponse
21
+ rpc :Test4, ::Testdata::TestRequest, ::Testdata::TestResponse
22
+ end
23
+
24
+ Stub = Service.rpc_stub_class
25
+ end
26
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is used to check the generated files all at once.
4
+ class MultiFileSerializer
5
+ def process_string(s)
6
+ # Ruby 3.4 changes how hashes are printed
7
+ if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('3.4.0')
8
+ s.gsub(/{"(.*)" => /, '{"\1"=>')
9
+ else
10
+ s
11
+ end
12
+ end
13
+
14
+ def dump(value)
15
+ value.keys.sort.map { |k| "#{k}:\n#{process_string(value[k])}\n" }.join("\n")
16
+ end
17
+ end
18
+
19
+ # The easiest way to test a protoc plugin is by actually running protoc. Here we are specifying
20
+ # the binary to use for the rails plugin and passing in the dependency paths and the
21
+ # place to find the generated Ruby files (which we generated in advance and live inside `spec/gen`.)
22
+ def protoc(files)
23
+ `bundle exec protoc \
24
+ --proto_path=#{__dir__} \
25
+ --proto_path=#{__dir__}/google-deps \
26
+ --plugin=protoc-gen-rails=#{__dir__}/../bin/protoc-gen-rails \
27
+ --rails_out=#{__dir__}/app \
28
+ --rails_opt=require=#{__dir__}/gen #{files.join(' ')}`
29
+ end
30
+
31
+ RSpec.describe 'protoc-gen-rails' do
32
+ let(:files) { Dir['spec/app/**/*.rb'].map { |f| [f, File.read(f)] }.to_h }
33
+ before(:each) do
34
+ FileUtils.mkdir('spec/app') unless File.exist?('spec/app')
35
+ end
36
+ after(:each) do
37
+ FileUtils.rm_rf('spec/app') if File.exist?('spec/app')
38
+ end
39
+
40
+ it 'should generate for a service' do
41
+ protoc(%w[testdata/test.proto testdata/test_service.proto])
42
+ expect(files).to match_snapshot('service', snapshot_serializer: MultiFileSerializer)
43
+ end
44
+
45
+ it 'should not generate if no services' do
46
+ protoc(%w[testdata/test.proto])
47
+ expect(files).to match_snapshot('no_service', snapshot_serializer: MultiFileSerializer)
48
+ end
49
+ end