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.
- checksums.yaml +4 -4
- data/.github/workflows/CI.yml +2 -41
- data/.rubocop.yml +3 -0
- data/CHANGELOG +6 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +21 -10
- data/README.md +7 -8
- data/bin/protoc-gen-rails +6 -0
- data/grpc-rest.gemspec +4 -1
- data/lib/generator/controller.rb.erb +27 -0
- data/lib/generator/grpc.rb.erb +9 -0
- data/lib/generator/method.rb +96 -0
- data/lib/generator/output.rb +28 -0
- data/lib/generator/plugin_pb.rb +25 -0
- data/lib/generator/service.rb +36 -0
- data/lib/generator.rb +88 -0
- data/lib/grpc_rest/version.rb +3 -1
- data/lib/grpc_rest.rb +40 -38
- data/{protoc-gen-rails/testdata/base/app/controllers/my_service_controller.rb → spec/__snapshots__/service.snap} +33 -27
- data/spec/base_interceptor_spec.rb +6 -3
- data/spec/{protoc-gen-openapiv2 → gen/protoc-gen-openapiv2}/options/annotations_pb.rb +5 -4
- data/spec/{protoc-gen-openapiv2 → gen/protoc-gen-openapiv2}/options/openapiv2_pb.rb +30 -29
- data/spec/gen/test_pb.rb +15 -0
- data/spec/gen/test_service_pb.rb +23 -0
- data/spec/gen/test_service_services_pb.rb +26 -0
- data/spec/generator_spec.rb +49 -0
- data/spec/grpc_rest_spec.rb +71 -25
- data/spec/gruf_spec.rb +4 -3
- data/spec/spec_helper.rb +8 -6
- data/spec/test_service_pb.rb +1 -1
- data/spec/test_service_services_pb.rb +2 -1
- data/spec/testdata/base/app/controllers/my_service_controller.rb +65 -0
- data/spec/testdata/no_service/.keep +0 -0
- data/{protoc-gen-rails → spec}/testdata/test_service.proto +1 -0
- metadata +90 -26
- data/protoc-gen-rails/.goreleaser.yml +0 -27
- data/protoc-gen-rails/LICENSE +0 -21
- data/protoc-gen-rails/go.mod +0 -25
- data/protoc-gen-rails/go.sum +0 -49
- data/protoc-gen-rails/internal/output.go +0 -165
- data/protoc-gen-rails/internal/parse.go +0 -101
- data/protoc-gen-rails/internal/utils.go +0 -57
- data/protoc-gen-rails/main.go +0 -104
- data/protoc-gen-rails/main_test.go +0 -158
- /data/{protoc-gen-rails/testdata/no_service/.keep → spec/__snapshots__/no_service.snap} +0 -0
- /data/{protoc-gen-rails → spec}/google-deps/google/api/annotations.proto +0 -0
- /data/{protoc-gen-rails → spec}/google-deps/google/api/http.proto +0 -0
- /data/{protoc-gen-rails → spec}/google-deps/protoc-gen-openapiv2/options/annotations.proto +0 -0
- /data/{protoc-gen-rails → spec}/google-deps/protoc-gen-openapiv2/options/openapiv2.proto +0 -0
- /data/{protoc-gen-rails → spec}/testdata/base/config/routes/grpc.rb +0 -0
- /data/{protoc-gen-rails → spec}/testdata/test.proto +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57ad95cccdb8e4034e4635b2f373dd3db5e31ff4e4a5bddfbd6d977f9b93bf29
|
4
|
+
data.tar.gz: '09b6320949f7894835e1596721ea0f38df5543998b19a7598172be1f1b79d188'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 605c7f2ea415104673b4693acaf5a1d90079172affb814bc4684ddbaa9698c2558abaaff19355b80e2cbced8715e7367b58541b4e49bf341d436b540b7a3d5ec
|
7
|
+
data.tar.gz: e4ff129327451f1101a8a3dec623a4a80b4e8eec3882f6d9ab0f52ed450c4a403226178391633001c4f3f6a3dbecc8130ae7afd55adc9e74102dfd878645305a
|
data/.github/workflows/CI.yml
CHANGED
@@ -8,23 +8,6 @@ on:
|
|
8
8
|
workflow_dispatch:
|
9
9
|
|
10
10
|
jobs:
|
11
|
-
test-go:
|
12
|
-
runs-on: [ubuntu-latest]
|
13
|
-
steps:
|
14
|
-
- name: Checkout code
|
15
|
-
uses: actions/checkout@v4
|
16
|
-
with:
|
17
|
-
fetch-depth: 0
|
18
|
-
- name: Setup Go
|
19
|
-
uses: actions/setup-go@v2
|
20
|
-
with:
|
21
|
-
go-version: '1.21'
|
22
|
-
- name: Install Protoc
|
23
|
-
uses: arduino/setup-protoc@v2
|
24
|
-
- run: git reset --hard
|
25
|
-
- run: git clean -f -d
|
26
|
-
- run: cd protoc-gen-rails && go test ./...
|
27
|
-
|
28
11
|
test-ruby:
|
29
12
|
runs-on: [ubuntu-latest]
|
30
13
|
steps:
|
@@ -37,28 +20,6 @@ jobs:
|
|
37
20
|
with:
|
38
21
|
ruby-version: '3.3'
|
39
22
|
bundler-cache: true
|
23
|
+
- name: Install Protoc
|
24
|
+
uses: arduino/setup-protoc@v2
|
40
25
|
- run: bundle exec rspec
|
41
|
-
|
42
|
-
build_and_deploy:
|
43
|
-
needs: [test-go, test-ruby]
|
44
|
-
runs-on: [ubuntu-latest]
|
45
|
-
steps:
|
46
|
-
- name: Checkout code
|
47
|
-
uses: actions/checkout@v4
|
48
|
-
with:
|
49
|
-
fetch-depth: 0
|
50
|
-
- name: Setup Go
|
51
|
-
uses: actions/setup-go@v2
|
52
|
-
with:
|
53
|
-
go-version: '1.21'
|
54
|
-
- run: git reset --hard
|
55
|
-
- run: git clean -f -d
|
56
|
-
- name: Run GoReleaser
|
57
|
-
uses: goreleaser/goreleaser-action@v3
|
58
|
-
with:
|
59
|
-
distribution: goreleaser
|
60
|
-
version: latest
|
61
|
-
workdir: ./protoc-gen-rails
|
62
|
-
args: release --clean
|
63
|
-
env:
|
64
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
data/.rubocop.yml
ADDED
data/CHANGELOG
CHANGED
@@ -7,8 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## UNRELEASED
|
9
9
|
|
10
|
+
- Rewrite protobuf plugin in Ruby.
|
11
|
+
|
12
|
+
# 0.1.25 - 2025-04-30
|
13
|
+
- Fix for crash when parsing map fields
|
14
|
+
|
10
15
|
# 0.1.24 - 2024-12-09
|
11
|
-
- Log error backtraces.
|
16
|
+
- Log error backtraces.
|
12
17
|
|
13
18
|
# 0.1.23 - 2024-11-25
|
14
19
|
- Fix: Return a 400 status code when payload is invalid JSON
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
grpc-rest (0.
|
4
|
+
grpc-rest (0.2.0)
|
5
|
+
google-protobuf (>= 4.30.2)
|
5
6
|
grpc
|
6
7
|
rails (>= 6.0)
|
7
8
|
|
@@ -73,7 +74,10 @@ GEM
|
|
73
74
|
i18n (>= 1.6, < 2)
|
74
75
|
minitest (>= 5.1)
|
75
76
|
tzinfo (~> 2.0)
|
77
|
+
awesome_print (1.9.2)
|
78
|
+
bigdecimal (3.1.9)
|
76
79
|
builder (3.2.4)
|
80
|
+
byebug (12.0.0)
|
77
81
|
concurrent-ruby (1.2.3)
|
78
82
|
crass (1.0.6)
|
79
83
|
date (3.3.4)
|
@@ -81,15 +85,13 @@ GEM
|
|
81
85
|
erubi (1.12.0)
|
82
86
|
globalid (1.2.1)
|
83
87
|
activesupport (>= 6.1)
|
84
|
-
google-protobuf (
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
grpc (1.62.0-x86_64-linux)
|
92
|
-
google-protobuf (~> 3.25)
|
88
|
+
google-protobuf (4.30.2-arm64-darwin)
|
89
|
+
bigdecimal
|
90
|
+
rake (>= 13)
|
91
|
+
googleapis-common-protos-types (1.19.0)
|
92
|
+
google-protobuf (>= 3.18, < 5.a)
|
93
|
+
grpc (1.71.0-arm64-darwin)
|
94
|
+
google-protobuf (>= 3.25, < 5.0)
|
93
95
|
googleapis-common-protos-types (~> 1.0)
|
94
96
|
grpc-tools (1.64.0)
|
95
97
|
gruf (2.20.0)
|
@@ -162,6 +164,10 @@ GEM
|
|
162
164
|
thor (~> 1.0)
|
163
165
|
zeitwerk (~> 2.5)
|
164
166
|
rake (13.2.1)
|
167
|
+
rspec (3.13.0)
|
168
|
+
rspec-core (~> 3.13.0)
|
169
|
+
rspec-expectations (~> 3.13.0)
|
170
|
+
rspec-mocks (~> 3.13.0)
|
165
171
|
rspec-core (3.13.0)
|
166
172
|
rspec-support (~> 3.13.0)
|
167
173
|
rspec-expectations (3.13.0)
|
@@ -178,6 +184,9 @@ GEM
|
|
178
184
|
rspec-expectations (~> 3.13)
|
179
185
|
rspec-mocks (~> 3.13)
|
180
186
|
rspec-support (~> 3.13)
|
187
|
+
rspec-snapshot (2.0.3)
|
188
|
+
awesome_print (> 1.0.0)
|
189
|
+
rspec (> 3.0.0)
|
181
190
|
rspec-support (3.13.1)
|
182
191
|
slop (4.10.1)
|
183
192
|
thor (1.3.1)
|
@@ -194,9 +203,11 @@ PLATFORMS
|
|
194
203
|
x86_64-linux
|
195
204
|
|
196
205
|
DEPENDENCIES
|
206
|
+
byebug
|
197
207
|
grpc-rest!
|
198
208
|
gruf
|
199
209
|
rspec-rails
|
210
|
+
rspec-snapshot
|
200
211
|
|
201
212
|
BUNDLED WITH
|
202
213
|
2.5.6
|
data/README.md
CHANGED
@@ -23,15 +23,15 @@ The protobuf generator uses the same annotations as [grpc-gateway](https://githu
|
|
23
23
|
|
24
24
|
## Installation
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
Then, add the following to your `Gemfile`:
|
26
|
+
Add the following to your `Gemfile`:
|
29
27
|
|
30
28
|
```ruby
|
31
29
|
gem 'grpc-rest'
|
32
30
|
```
|
33
31
|
|
34
|
-
and run `bundle install`.
|
32
|
+
and run `bundle install`. Then when using `protoc` or `buf generate`, ensure you prefix the command with `bundle exec`, e.g.
|
33
|
+
|
34
|
+
`bundle exec buf generate`
|
35
35
|
|
36
36
|
## Example
|
37
37
|
|
@@ -78,6 +78,9 @@ plugins:
|
|
78
78
|
- paths=source_relative
|
79
79
|
- name: rails
|
80
80
|
out: .
|
81
|
+
opt:
|
82
|
+
# this should be the same directory as the output of your Ruby plugin
|
83
|
+
- require=app/gen
|
81
84
|
```
|
82
85
|
|
83
86
|
Then, you can run `buf generate` to generate the Ruby files. This will generate:
|
@@ -172,10 +175,6 @@ module Interceptors
|
|
172
175
|
end
|
173
176
|
```
|
174
177
|
|
175
|
-
## To Do
|
176
|
-
|
177
|
-
* Replace Go implementation with Ruby (+ executable)
|
178
|
-
|
179
178
|
## Contributing
|
180
179
|
|
181
180
|
Bug reports and pull requests are welcome on GitHub at https://github.com/flipp-oss/grpc-rest.
|
data/grpc-rest.gemspec
CHANGED
@@ -18,9 +18,12 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
+
spec.add_runtime_dependency('google-protobuf', '>= 4.30.2')
|
21
22
|
spec.add_runtime_dependency('grpc')
|
22
23
|
spec.add_runtime_dependency('rails', '>= 6.0')
|
23
24
|
|
24
|
-
spec.add_development_dependency('
|
25
|
+
spec.add_development_dependency('byebug')
|
25
26
|
spec.add_development_dependency('gruf')
|
27
|
+
spec.add_development_dependency('rspec-rails')
|
28
|
+
spec.add_development_dependency('rspec-snapshot')
|
26
29
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
2
|
+
|
3
|
+
require 'grpc_rest'
|
4
|
+
class <%= service.name.demodulize %>Controller < ActionController::Base
|
5
|
+
protect_from_forgery with: :null_session
|
6
|
+
|
7
|
+
rescue_from StandardError do |e|
|
8
|
+
render json: GrpcRest.error_msg(e), status: :internal_server_error
|
9
|
+
end
|
10
|
+
rescue_from GRPC::BadStatus do |e|
|
11
|
+
render json: GrpcRest.error_msg(e), status: GrpcRest.grpc_http_status(e.code)
|
12
|
+
end
|
13
|
+
rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
|
14
|
+
render json: GrpcRest.error_msg(e), status: :bad_request
|
15
|
+
end
|
16
|
+
METHOD_PARAM_MAP = <%= service.methods.to_h { |m| [m.name.underscore, m.path_info.map(&:to_h)]}.pretty_inspect %>.freeze
|
17
|
+
|
18
|
+
<% service.methods.each do |method| %>
|
19
|
+
def <%= method.name %>
|
20
|
+
fields = <%= method.request_type %>.descriptor.to_a.map(&:name)
|
21
|
+
parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
|
22
|
+
grpc_request = GrpcRest.init_request(<%= method.request_type %>, parameters.slice(*fields))
|
23
|
+
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["<%= method.name.underscore %>"], "<%= method.option_body %>", request.parameters)
|
24
|
+
render json: GrpcRest.send_request("<%= service.namespace %>::<%= service.name.classify %>", "<%= method.name.underscore %>", grpc_request, <%= method.rest_options.inspect %>)
|
25
|
+
end
|
26
|
+
<% end %>
|
27
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
4
|
+
|
5
|
+
<% services.each do |service| -%>
|
6
|
+
<% service.methods.each do |method| %>
|
7
|
+
<%= method.http_method %> '<%= method.sanitized_path %>' => '<%= service.name.demodulize.underscore %>#<%= method.name.underscore %>' <% -%>
|
8
|
+
<% end %>
|
9
|
+
<% end %>
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ProtocGenRails
|
4
|
+
class Method
|
5
|
+
PathInfo = Struct.new(:name, :val, :split_name)
|
6
|
+
|
7
|
+
attr_accessor :http_method, :path, :path_info, :rest_options
|
8
|
+
|
9
|
+
# @param proto_method [Google::Protobuf::MethodDescriptor]
|
10
|
+
def initialize(proto_method)
|
11
|
+
@method = proto_method
|
12
|
+
@rest_options = extract_rest_options
|
13
|
+
@options = extract_options
|
14
|
+
@http_method, @path = method_and_path
|
15
|
+
@path_info = extract_path_info
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String]
|
19
|
+
def option_body = @options&.body
|
20
|
+
# @return [String]
|
21
|
+
def name = @method.name.underscore
|
22
|
+
|
23
|
+
# @return [String]
|
24
|
+
def request_type
|
25
|
+
@method.input_type.name.split('.').map(&:camelcase).join('::')
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String]
|
29
|
+
def sanitized_path
|
30
|
+
path = @path
|
31
|
+
re = /\{(.*?)}/
|
32
|
+
matches = path.scan(re)
|
33
|
+
matches.each do |match|
|
34
|
+
repl = match[0]
|
35
|
+
equal = repl.index('=')
|
36
|
+
repl = repl[0...equal] if equal
|
37
|
+
dot = repl.index('.')
|
38
|
+
repl = repl[(dot + 1)..] if dot
|
39
|
+
path = path.sub("{#{match[0]}}", "*#{repl}")
|
40
|
+
end
|
41
|
+
path
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Google::Api::HttpRule]
|
45
|
+
def extract_options
|
46
|
+
return nil if @method.options.nil?
|
47
|
+
|
48
|
+
extension = Google::Protobuf::DescriptorPool.generated_pool.lookup('google.api.http')
|
49
|
+
extension.get(@method.options)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Hash]
|
53
|
+
def extract_rest_options
|
54
|
+
return nil if @method.options.nil?
|
55
|
+
|
56
|
+
extension = Google::Protobuf::DescriptorPool.generated_pool
|
57
|
+
.lookup('grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation')
|
58
|
+
result = extension.get(@method.options)
|
59
|
+
return {} if result.nil?
|
60
|
+
|
61
|
+
emit_defaults = result.extensions['x-grpc-rest-emit-defaults']&.bool_value || false
|
62
|
+
{
|
63
|
+
emit_defaults: emit_defaults
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [String, String]
|
68
|
+
def method_and_path
|
69
|
+
return if @options.nil?
|
70
|
+
|
71
|
+
if @options.pattern == :custom
|
72
|
+
[@options.custom.kind, @options.custom.path]
|
73
|
+
else
|
74
|
+
[@options.pattern, @options.send(@options.pattern)]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [PathInfo]
|
79
|
+
def extract_path_info
|
80
|
+
@path.scan(/\{(.*?)}/).map do |match|
|
81
|
+
name = match[0]
|
82
|
+
val = ''
|
83
|
+
equal = name.index('=')
|
84
|
+
if equal
|
85
|
+
val = name[equal..]
|
86
|
+
name = name[0..equal - 1]
|
87
|
+
end
|
88
|
+
PathInfo.new(
|
89
|
+
name: name,
|
90
|
+
val: val,
|
91
|
+
split_name: name.split('.')
|
92
|
+
)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ProtocGenRails
|
4
|
+
module Output
|
5
|
+
class << self
|
6
|
+
# @param files [Array<FileResult>]
|
7
|
+
# @return [String]
|
8
|
+
def response(files)
|
9
|
+
response = Google::Protobuf::Compiler::CodeGeneratorResponse.new
|
10
|
+
response.supported_features = Google::Protobuf::Compiler::CodeGeneratorResponse::Feature::FEATURE_PROTO3_OPTIONAL
|
11
|
+
files.each do |file|
|
12
|
+
response.file << Google::Protobuf::Compiler::CodeGeneratorResponse::File.new(name: file.name,
|
13
|
+
content: file.content)
|
14
|
+
end
|
15
|
+
response.to_proto
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param error [String]
|
19
|
+
def exit_with_error(error)
|
20
|
+
response = Google::Protobuf::Compiler::CodeGeneratorResponse.new
|
21
|
+
response.error = error
|
22
|
+
$stderr << "#{error}\n"
|
23
|
+
$stdout << response.to_proto
|
24
|
+
exit(1)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# source: google/protobuf/compiler/plugin.proto
|
5
|
+
|
6
|
+
require 'google/protobuf'
|
7
|
+
|
8
|
+
require 'google/protobuf/descriptor_pb'
|
9
|
+
|
10
|
+
descriptor_data = "\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"F\n\x07Version\x12\r\n\x05major\x18\x01 \x01(\x05\x12\r\n\x05minor\x18\x02 \x01(\x05\x12\r\n\x05patch\x18\x03 \x01(\x05\x12\x0e\n\x06suffix\x18\x04 \x01(\t\"\x81\x02\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12\x45\n\x17source_file_descriptors\x18\x11 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12;\n\x10\x63ompiler_version\x18\x03 \x01(\x0b\x32!.google.protobuf.compiler.Version\"\x92\x03\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x1a\n\x12supported_features\x18\x02 \x01(\x04\x12\x17\n\x0fminimum_edition\x18\x03 \x01(\x05\x12\x17\n\x0fmaximum_edition\x18\x04 \x01(\x05\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a\x7f\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\t\x12?\n\x13generated_code_info\x18\x10 \x01(\x0b\x32\".google.protobuf.GeneratedCodeInfo\"W\n\x07\x46\x65\x61ture\x12\x10\n\x0c\x46\x45\x41TURE_NONE\x10\x00\x12\x1b\n\x17\x46\x45\x41TURE_PROTO3_OPTIONAL\x10\x01\x12\x1d\n\x19\x46\x45\x41TURE_SUPPORTS_EDITIONS\x10\x02\x42r\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtosZ)google.golang.org/protobuf/types/pluginpb\xaa\x02\x18Google.Protobuf.Compiler"
|
11
|
+
|
12
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
|
15
|
+
module Google
|
16
|
+
module Protobuf
|
17
|
+
module Compiler
|
18
|
+
Version = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.Version').msgclass
|
19
|
+
CodeGeneratorRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.CodeGeneratorRequest').msgclass
|
20
|
+
CodeGeneratorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.CodeGeneratorResponse').msgclass
|
21
|
+
CodeGeneratorResponse::File = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.CodeGeneratorResponse.File').msgclass
|
22
|
+
CodeGeneratorResponse::Feature = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.CodeGeneratorResponse.Feature').enummodule
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'method'
|
4
|
+
|
5
|
+
module ProtocGenRails
|
6
|
+
class Service
|
7
|
+
attr_accessor :methods
|
8
|
+
|
9
|
+
# @param service_proto [Google::Protobuf::ServiceDescriptorProto]
|
10
|
+
# @param package [String]
|
11
|
+
def initialize(service_proto, package)
|
12
|
+
# see https://github.com/protocolbuffers/protobuf/issues/21091 for why this is needed
|
13
|
+
# this will return a Google::Protobuf::ServiceDescriptor
|
14
|
+
@service = Google::Protobuf::DescriptorPool.generated_pool.lookup("#{package}.#{service_proto.name}")
|
15
|
+
if @service.nil?
|
16
|
+
ProtocGenRails::Output.exit_with_error("Could not find generated service: #{package}.#{service_proto.name}")
|
17
|
+
end
|
18
|
+
@methods = []
|
19
|
+
@package = package
|
20
|
+
@service.each do |m|
|
21
|
+
# m is a Google::Protobuf::MethodDescriptor
|
22
|
+
@methods.push(ProtocGenRails::Method.new(m))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String]
|
27
|
+
def name
|
28
|
+
@service.name.split('.').map(&:camelcase).join('::').demodulize
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String]
|
32
|
+
def namespace
|
33
|
+
@package.split('.').map(&:camelcase).join('::')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/generator.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'google/protobuf'
|
4
|
+
require 'erb'
|
5
|
+
require 'active_support/all'
|
6
|
+
require 'google/protobuf/well_known_types'
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
require_relative 'generator/output'
|
10
|
+
require_relative 'generator/service'
|
11
|
+
require_relative 'generator/plugin_pb'
|
12
|
+
|
13
|
+
module ProtocGenRails
|
14
|
+
FileResult = Struct.new(:name, :content)
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
# @param params [String]
|
19
|
+
def require_directories(params)
|
20
|
+
params.split(',').each do |param|
|
21
|
+
key, value = param.split('=')
|
22
|
+
next unless key == 'require'
|
23
|
+
|
24
|
+
dirs = value.split(',')
|
25
|
+
dirs.each do |v|
|
26
|
+
$LOAD_PATH.unshift(v)
|
27
|
+
dir = File.expand_path(v)
|
28
|
+
Dir["#{dir}/**/*.rb"].each { |file| require file }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param input [String]
|
34
|
+
# @return [String]
|
35
|
+
def process(input)
|
36
|
+
request = Google::Protobuf::Compiler::CodeGeneratorRequest.decode(input)
|
37
|
+
files = []
|
38
|
+
|
39
|
+
require_directories(request.parameter)
|
40
|
+
|
41
|
+
services = []
|
42
|
+
request.proto_file.each do |proto_file|
|
43
|
+
next if request.file_to_generate.exclude?(proto_file.name)
|
44
|
+
next if proto_file.service.none?
|
45
|
+
|
46
|
+
proto_file.service.each do |service_descriptor|
|
47
|
+
service = ProtocGenRails::Service.new(service_descriptor, proto_file.package)
|
48
|
+
services.push(service)
|
49
|
+
file = process_service(service)
|
50
|
+
files.push(file) if file
|
51
|
+
end
|
52
|
+
end
|
53
|
+
if files.any?
|
54
|
+
route_output = route_file(services)
|
55
|
+
files.push(route_output) if route_output
|
56
|
+
end
|
57
|
+
Output.response(files)
|
58
|
+
end
|
59
|
+
|
60
|
+
# @param service [ProtocGenRails::Service]
|
61
|
+
# @return [FileResult]
|
62
|
+
def process_service(service)
|
63
|
+
content = parse_erb('controller', { service: service })
|
64
|
+
FileResult.new(
|
65
|
+
content: content,
|
66
|
+
name: "app/controllers/#{service.name.underscore}_controller.rb"
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param services [Array<ProtocGenRails::Service>]
|
71
|
+
# @return [FileResult]
|
72
|
+
def route_file(services)
|
73
|
+
content = parse_erb('grpc', { services: services })
|
74
|
+
FileResult.new(
|
75
|
+
name: 'config/routes/grpc.rb',
|
76
|
+
content: content
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param filename [String]
|
81
|
+
# @param data [Object]
|
82
|
+
# @return [String]
|
83
|
+
def parse_erb(filename, data)
|
84
|
+
erb = File.read("#{__dir__}/generator/#{filename}.rb.erb")
|
85
|
+
ERB.new(erb, trim_mode: '-').result_with_hash(data.to_h)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/grpc_rest/version.rb
CHANGED