protobuf_transpiler 1.1.2 → 1.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/CHANGELOG.md +8 -0
- data/README.md +13 -4
- data/lib/protobuf_transpiler/version.rb +1 -1
- data/lib/protobuf_transpiler.rb +49 -17
- data/lib/tasks/grpc_stubs.rake +9 -6
- metadata +5 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ae36cca017f8dc92d448d3312284e2462934a87b522675684d3e987e53e1029
|
4
|
+
data.tar.gz: 781b649dd1a6dcace6b68e9fea32efb5699c63008af53106f4a4b081b0b103ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9eedd08deb9598d3d6a978e57549ae8472e8129021e3d5d7a775c301b4198633c999c376ef6356755d358530e695b056e1c0a6d08b1601a650ae6d60c90dd15
|
7
|
+
data.tar.gz: 4fcd0154d6e585a43331d65e6077689abeacd7abafeabf4f6689c65cb56aacbff99b96be5d73606ab939e2bd06e8dfa058bd60731c5696c0f2fdf55dc5137086
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,14 @@
|
|
8
8
|
### Bug fixes
|
9
9
|
)-->
|
10
10
|
|
11
|
+
## 1.2.0 2025-04-10
|
12
|
+
- generate task can create an initializer that allows the generated stubs to work with zeitwerk
|
13
|
+
- added possibility to specify stubs path for generate task
|
14
|
+
- added possibility to specify stubs path for annotate task
|
15
|
+
|
16
|
+
## 1.1.3 2025-02-28
|
17
|
+
- remove rails versions constraints, keep only dependency
|
18
|
+
|
11
19
|
## 1.1.2 2023-11-20
|
12
20
|
### Bug fixes
|
13
21
|
- provide compatibility to ruby < 3.1
|
data/README.md
CHANGED
@@ -21,7 +21,7 @@ bundle
|
|
21
21
|
|
22
22
|
## Usage
|
23
23
|
|
24
|
-
This gem provides two rake tasks, `grpc_stubs:generate` and `grpc_stubs:annotate`. `generate` transpiles all `.proto` files nested in a `public` folder looking in the `$LOAD_PATH`, putting the generated ruby stubs in `app/stubs
|
24
|
+
This gem provides two rake tasks, `grpc_stubs:generate` and `grpc_stubs:annotate`. `generate` transpiles all `.proto` files nested in a `public` folder looking in the `$LOAD_PATH`, putting the generated ruby stubs in `app/stubs` (or a path specified by the user), respecting the inner nesting. `annotate` annotates all the generated stubs with a comment section leveraging reflection.
|
25
25
|
|
26
26
|
Beware that at the moment this gem does not support nested messages definition.
|
27
27
|
|
@@ -30,9 +30,15 @@ To generate the stubs simply run:
|
|
30
30
|
```bash
|
31
31
|
rake grpc_stubs:generate
|
32
32
|
```
|
33
|
-
The task accepts
|
34
|
-
|
35
|
-
|
33
|
+
The task accepts four optional positional arguments:
|
34
|
+
- `annotate` (default: `'yes'`): This specifies whether the task `annotate` should also be run. Options are `'yes'` and `'no'`
|
35
|
+
- `keep_require` (default: `'no'`): This specifies whether `generate` should remove all the `require ...` generated by `grpc_tools_ruby_protoc` or keep them. Options are `'yes'` and `'no'`
|
36
|
+
- `path` (default: `'app/stubs'`): This specifies the folder in which the stubs should be generated.
|
37
|
+
- `create_initializer` (default: `'yes'`): This specifies whether to create the file `config/initializers/protobuf_transpiler.rb`. Options are `'yes'` and `'no'`
|
38
|
+
|
39
|
+
This means that by default the `generate` task also runs the `annotate` one, and the behavior can be changed by specifying the first argument as `'no'`. Furthermore, the default behavior of `generate` removes all the `require ...` generated by `grpc_tools_ruby_protoc`; if, for any reason, you may want to keep them, you need to specify the second argument as `'yes'` (which implies you need to explicitly state the first parameter, even if you want to keep the default behavior).
|
40
|
+
Following the stubs generation, the task also creates a ruby file for all the proto packages, which corresponds to the created folders in `app/stubs`, containing `require_relative` instructions to the corresponding stubs.
|
41
|
+
To allow `zeitwerk` to work properly despite `grpc_tools_ruby_protoc` not respecting the naming conventions, by default the task will create an initializer that requires the generated stubs and stops the specified folder from being autoloaded (if it's inside of the `app` directory).
|
36
42
|
|
37
43
|
For example if you have a gem defining proto files with this structure:
|
38
44
|
```
|
@@ -61,6 +67,9 @@ To annotate generated stubs simply run:
|
|
61
67
|
```bash
|
62
68
|
rake grpc_stubs:annotate
|
63
69
|
```
|
70
|
+
|
71
|
+
This task has just one positional argument: `path`. It represents the folder in which the stubs were generated.
|
72
|
+
|
64
73
|
As stated in [generate](#generate) this task is executed automatically unless you opt out after the generation step. Leveraging reflection, Messages and Services are inspected and a comment summary is prepended in the corresponding stub file.
|
65
74
|
|
66
75
|
The annotations of messages follow these conventions:
|
data/lib/protobuf_transpiler.rb
CHANGED
@@ -7,26 +7,30 @@ module ProtobufTranspiler
|
|
7
7
|
require_relative 'railtie'
|
8
8
|
|
9
9
|
class << self
|
10
|
-
def generate_stubs(keep_require = false)
|
10
|
+
def generate_stubs(keep_require = false, path = 'app/stubs')
|
11
11
|
paths = $LOAD_PATH.map { |p| "#{p}/**/public/**/*.proto" }
|
12
12
|
proto_files = Dir[*paths].join ' '
|
13
13
|
proto_paths = proto_files
|
14
14
|
.split.map { |p| p.sub %r{(?<=public).*}, '' }
|
15
15
|
.uniq.join ' '
|
16
|
-
out_path = "#{Rails.root}/
|
16
|
+
out_path = "#{Rails.root}/#{path}/"
|
17
17
|
FileUtils.mkdir_p out_path
|
18
18
|
`grpc_tools_ruby_protoc --ruby_out=#{out_path} --grpc_out=#{out_path} #{proto_files} -I #{proto_paths}`
|
19
19
|
|
20
20
|
# remove possibly useless require from stub file
|
21
21
|
unless keep_require
|
22
|
-
Dir[
|
22
|
+
Dir["#{path}/**/*.rb"].each do |fp|
|
23
23
|
f = File.read fp
|
24
24
|
File.write fp, (f.sub %r{\n(require.*?'\n)+}, '')
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
if path_in_app path
|
29
|
+
Rails.autoloaders.main.ignore "#{path}/**/*"
|
30
|
+
end
|
31
|
+
|
28
32
|
# make zeitwerk happy
|
29
|
-
Dir[
|
33
|
+
Dir["#{path}/**"]
|
30
34
|
.filter { |f| File.directory? f }
|
31
35
|
.each { |dir|
|
32
36
|
requires = Dir.chdir dir do
|
@@ -37,15 +41,15 @@ module ProtobufTranspiler
|
|
37
41
|
}
|
38
42
|
end
|
39
43
|
|
40
|
-
def annotate_stubs
|
44
|
+
def annotate_stubs path = 'app/stubs'
|
41
45
|
require 'active_support/core_ext/string/inflections'
|
42
46
|
|
43
|
-
Dir[
|
47
|
+
Dir["#{path}/**/*.rb"]
|
44
48
|
.map { |s| File.absolute_path s }
|
45
|
-
.each { |f|
|
49
|
+
.each { |f| zeitwerk_original_require f }
|
46
50
|
|
47
|
-
stubs_modules = Dir[
|
48
|
-
.map { |s| s.sub(
|
51
|
+
stubs_modules = Dir["#{path}/*.rb"]
|
52
|
+
.map { |s| s.sub(path, '') }
|
49
53
|
.map { |s| s.sub '.rb', '' }
|
50
54
|
.uniq
|
51
55
|
.map { |c| Object.const_get c.camelize }
|
@@ -54,7 +58,8 @@ module ProtobufTranspiler
|
|
54
58
|
out = m
|
55
59
|
.constants
|
56
60
|
.sort
|
57
|
-
.map { |c| m.const_get c }
|
61
|
+
.map { |c| ignore_errors(NameError) { m.const_get c } }
|
62
|
+
.filter(&:present?)
|
58
63
|
.each_with_object({ messages: [], services: [] }) { |c, acc|
|
59
64
|
if c.is_a? Class
|
60
65
|
acc[:messages] << class_annotations(c)
|
@@ -62,7 +67,7 @@ module ProtobufTranspiler
|
|
62
67
|
acc[:services] << module_annotations(c)
|
63
68
|
end
|
64
69
|
}
|
65
|
-
types_file, services_file = Dir["
|
70
|
+
types_file, services_file = Dir["#{path}/#{m.name.underscore}/*.rb"]
|
66
71
|
.sort_by { |s| s.scan('services').count }
|
67
72
|
[types_file, services_file]
|
68
73
|
.zip([out[:messages], out[:services]])
|
@@ -70,10 +75,30 @@ module ProtobufTranspiler
|
|
70
75
|
end
|
71
76
|
end
|
72
77
|
|
78
|
+
def generate_initializer stubs_path = 'app/stubs'
|
79
|
+
file_content = ''
|
80
|
+
|
81
|
+
if path_in_app stubs_path
|
82
|
+
# Ignore the path in zeitwerk
|
83
|
+
file_content += "Rails.autoloaders.main.ignore '#{stubs_path}/**/*'\n"
|
84
|
+
end
|
85
|
+
|
86
|
+
file_content += "Dir[\"\#{Rails.root}/#{stubs_path}/*\"].each { |f| require_relative f }\n"
|
87
|
+
|
88
|
+
File.write "#{Rails.root}/config/initializers/protobuf_transpiler.rb", file_content
|
89
|
+
end
|
90
|
+
|
73
91
|
private
|
74
92
|
|
75
93
|
ANNOTATE_DELIMITER = '# ===== Protobuf Annotation ====='
|
76
94
|
|
95
|
+
def path_in_app path
|
96
|
+
stubs_path = File.realdirpath path, Rails.root
|
97
|
+
app_folder = File.realdirpath 'app', Rails.root
|
98
|
+
|
99
|
+
stubs_path.start_with? app_folder
|
100
|
+
end
|
101
|
+
|
77
102
|
def class_annotations klass
|
78
103
|
oneof_fields, oneof_annotations = lambda do |descriptor|
|
79
104
|
[
|
@@ -124,13 +149,20 @@ module ProtobufTranspiler
|
|
124
149
|
end.to_s
|
125
150
|
end
|
126
151
|
|
152
|
+
def ignore_errors(*errors, &block)
|
153
|
+
begin
|
154
|
+
block.call
|
155
|
+
rescue errors
|
156
|
+
nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
127
160
|
def module_annotations mod
|
128
|
-
mod
|
129
|
-
|
130
|
-
.
|
131
|
-
.
|
132
|
-
|
133
|
-
.join "\n"
|
161
|
+
ignore_errors(NameError, NoMethodError) { mod.const_get('Service') }
|
162
|
+
&.sort
|
163
|
+
&.map { |_, d| "\t#{d.name}(#{d.input}): #{d.output}" }
|
164
|
+
&.prepend(mod.name.to_s)
|
165
|
+
&.join "\n"
|
134
166
|
end
|
135
167
|
|
136
168
|
def annotate_file file, content
|
data/lib/tasks/grpc_stubs.rake
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
namespace :grpc_stubs do
|
2
2
|
desc 'Generate stubs for all .proto files (looking into entire LOAD_PATH)'
|
3
|
-
task :generate, [:annotate, :keep_require] do |_, args|
|
4
|
-
args.with_defaults annotate: :yes, keep_require: :no
|
3
|
+
task :generate, [:annotate, :keep_require, :path, :create_initializer] => :environment do |_, args|
|
4
|
+
args.with_defaults annotate: :yes, keep_require: :no, path: 'app/stubs', create_initializer: :yes
|
5
5
|
require_relative '../protobuf_transpiler'
|
6
|
-
ProtobufTranspiler.generate_stubs args[:keep_require].to_sym == :yes
|
7
|
-
ProtobufTranspiler.
|
6
|
+
ProtobufTranspiler.generate_stubs args[:keep_require].to_sym == :yes, args[:path]
|
7
|
+
ProtobufTranspiler.generate_initializer args[:path] unless args[:create_initializer].to_sym == :no
|
8
|
+
ProtobufTranspiler.annotate_stubs args[:path] unless args[:annotate].to_sym == :no
|
8
9
|
end
|
9
10
|
|
10
11
|
desc 'Annotate generated stubs'
|
11
|
-
task :annotate do
|
12
|
+
task :annotate, [:path, :create_initializer] => :environment do |_, args|
|
13
|
+
args.with_defaults path: 'app/stubs', create_initializer: :no
|
12
14
|
require_relative '../protobuf_transpiler'
|
13
|
-
ProtobufTranspiler.
|
15
|
+
ProtobufTranspiler.generate_initializer args[:path] unless args[:create_initializer].to_sym == :no
|
16
|
+
ProtobufTranspiler.annotate_stubs args[:path]
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protobuf_transpiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Moku S.r.l.
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-04-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: google-protobuf
|
@@ -63,22 +63,16 @@ dependencies:
|
|
63
63
|
name: rails
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '7.0'
|
69
66
|
- - ">="
|
70
67
|
- !ruby/object:Gem::Version
|
71
|
-
version:
|
68
|
+
version: '0'
|
72
69
|
type: :runtime
|
73
70
|
prerelease: false
|
74
71
|
version_requirements: !ruby/object:Gem::Requirement
|
75
72
|
requirements:
|
76
|
-
- - "~>"
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
version: '7.0'
|
79
73
|
- - ">="
|
80
74
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
75
|
+
version: '0'
|
82
76
|
description: This gem provides a quick way to generate annotated ruby stubs for protobufs
|
83
77
|
leveraging Ruby gRPC Tools, adopting an opinionated Rails oriented approach.
|
84
78
|
email:
|
@@ -120,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
114
|
- !ruby/object:Gem::Version
|
121
115
|
version: '0'
|
122
116
|
requirements: []
|
123
|
-
rubygems_version: 3.
|
117
|
+
rubygems_version: 3.5.22
|
124
118
|
signing_key:
|
125
119
|
specification_version: 4
|
126
120
|
summary: A protobuf transpiler and annotator for Rails applications.
|