rbs_protobuf 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +9 -7
- data/.gitmodules +0 -3
- data/CHANGELOG.md +12 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +31 -18
- data/README.md +36 -16
- data/Rakefile +4 -2
- data/Steepfile +0 -1
- data/bin/protoc-gen-dumper +3 -1
- data/bin/setup +0 -9
- data/example/d.proto +6 -0
- data/exe/protoc-gen-rbs +18 -0
- data/lib/rbs_protobuf/rbs_factory.rb +1 -0
- data/lib/rbs_protobuf/translator/base.rb +72 -7
- data/lib/rbs_protobuf/translator/protobuf_gem.rb +268 -127
- data/lib/rbs_protobuf/version.rb +1 -1
- data/rbs_collection.lock.yaml +39 -45
- data/rbs_collection.yaml +1 -9
- data/sig/rbs_protobuf/rbs_factory.rbs +1 -1
- data/sig/rbs_protobuf/translator/base.rbs +14 -2
- data/sig/rbs_protobuf/translator/protobuf_gem.rbs +2 -1
- metadata +4 -4
- data/.protoc-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcaf6201c92331c28b9fa7d1791711def79ccb4803d81692a220b60d08e640a6
|
4
|
+
data.tar.gz: 93651dffc7e86d657f5ed5298b3ab43042a7e663fd07a502b25fe968ede6cef2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09835d51dd74b278a376dc721bbde2527f6e501596dd5239b29a0da5aa96af69cfc08831e2dafc7b6ac67491ef3e5c35b2ec2dca536fbc66864291b3a2109e6a'
|
7
|
+
data.tar.gz: 42b4c2d53a767f7b8732f8d4ee7a74d724ba334280cf006326a1ebfcd5f1dc4031d44404d149ee63e8c66f46da5dee2f519eaa6539d7789fb8b9b5e5a9dfb863
|
data/.github/workflows/test.yml
CHANGED
@@ -12,12 +12,13 @@ jobs:
|
|
12
12
|
strategy:
|
13
13
|
matrix:
|
14
14
|
container_tag:
|
15
|
-
-
|
16
|
-
- 3.
|
17
|
-
- 3.
|
15
|
+
- 3.0-dev-focal
|
16
|
+
- 3.1-dev-jammy
|
17
|
+
- 3.2-dev-jammy
|
18
18
|
protoc_version:
|
19
|
-
- 3.18.2
|
20
|
-
- 3.19.4
|
19
|
+
- "3.18.2"
|
20
|
+
- "3.19.4"
|
21
|
+
- "24.0"
|
21
22
|
container:
|
22
23
|
image: rubylang/ruby:${{ matrix.container_tag }}
|
23
24
|
steps:
|
@@ -31,8 +32,9 @@ jobs:
|
|
31
32
|
mv bin/protoc /usr/local/bin/protoc
|
32
33
|
protoc --version
|
33
34
|
- uses: actions/checkout@v3
|
34
|
-
|
35
|
-
|
35
|
+
- name: Set up git safe.directory
|
36
|
+
run: |
|
37
|
+
git config --global --add safe.directory /__w/rbs_protobuf/rbs_protobuf
|
36
38
|
- name: Run test
|
37
39
|
run: |
|
38
40
|
ruby -v
|
data/.gitmodules
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 1.2.0 (2023-09-06)
|
4
|
+
|
5
|
+
* Add `RBS_PROTOBUF_CONCAT_LEVEL` option ([#38](https://github.com/square/rbs_protobuf/pull/38))
|
6
|
+
* Generate rpc method types and interfaces ([#37](https://github.com/square/rbs_protobuf/pull/37))
|
7
|
+
* Generate `record` type of each proto message ([#36](https://github.com/square/rbs_protobuf/pull/36))
|
8
|
+
* Add filter ([#34](https://github.com/square/rbs_protobuf/pull/34))
|
9
|
+
|
10
|
+
## 1.1.0 (2023-08-16)
|
11
|
+
|
12
|
+
* Support optional fields in proto3 ([\#32](https://github.com/square/rbs_protobuf/pull/32))
|
13
|
+
* Update Steep to 1.5 and RBS to 3.1 ([\#30](https://github.com/square/rbs_protobuf/pull/30))
|
14
|
+
|
3
15
|
## 1.0.0 (2022-04-25)
|
4
16
|
|
5
17
|
This is version 1.0.0. 🎉
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,59 +1,72 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rbs_protobuf (1.
|
4
|
+
rbs_protobuf (1.2.0)
|
5
5
|
activesupport (>= 4.0)
|
6
6
|
rbs (>= 2.2.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activesupport (7.0.2
|
11
|
+
activesupport (7.0.7.2)
|
12
12
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
13
|
i18n (>= 1.6, < 2)
|
14
14
|
minitest (>= 5.1)
|
15
15
|
tzinfo (~> 2.0)
|
16
16
|
ast (2.4.2)
|
17
|
-
concurrent-ruby (1.
|
17
|
+
concurrent-ruby (1.2.2)
|
18
|
+
csv (3.2.7)
|
18
19
|
ffi (1.15.5)
|
19
|
-
|
20
|
+
fileutils (1.7.1)
|
21
|
+
i18n (1.14.1)
|
20
22
|
concurrent-ruby (~> 1.0)
|
21
|
-
|
22
|
-
|
23
|
+
json (2.6.3)
|
24
|
+
language_server-protocol (3.17.0.3)
|
25
|
+
listen (3.8.0)
|
23
26
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
24
27
|
rb-inotify (~> 0.9, >= 0.9.10)
|
28
|
+
logger (1.5.3)
|
25
29
|
middleware (0.1.0)
|
26
|
-
minitest (5.
|
27
|
-
|
28
|
-
parser (3.1.2.0)
|
30
|
+
minitest (5.19.0)
|
31
|
+
parser (3.2.2.3)
|
29
32
|
ast (~> 2.4.1)
|
33
|
+
racc
|
30
34
|
protobuf (3.10.5)
|
31
35
|
activesupport (>= 3.2)
|
32
36
|
middleware
|
33
37
|
thor
|
34
38
|
thread_safe
|
39
|
+
racc (1.7.1)
|
35
40
|
rainbow (3.1.1)
|
36
41
|
rake (12.3.3)
|
37
|
-
rb-fsevent (0.11.
|
42
|
+
rb-fsevent (0.11.2)
|
38
43
|
rb-inotify (0.10.1)
|
39
44
|
ffi (~> 1.0)
|
40
|
-
rbs (
|
41
|
-
|
45
|
+
rbs (3.1.3)
|
46
|
+
securerandom (0.2.2)
|
47
|
+
steep (1.5.3)
|
42
48
|
activesupport (>= 5.1)
|
49
|
+
concurrent-ruby (>= 1.1.10)
|
50
|
+
csv (>= 3.0.9)
|
51
|
+
fileutils (>= 1.1.0)
|
52
|
+
json (>= 2.1.0)
|
43
53
|
language_server-protocol (>= 3.15, < 4.0)
|
44
54
|
listen (~> 3.0)
|
45
|
-
|
46
|
-
parser (>= 3.
|
55
|
+
logger (>= 1.3.0)
|
56
|
+
parser (>= 3.1)
|
47
57
|
rainbow (>= 2.2.2, < 4.0)
|
48
|
-
rbs (>=
|
58
|
+
rbs (>= 3.1.0)
|
59
|
+
securerandom (>= 0.1)
|
60
|
+
strscan (>= 1.0.0)
|
49
61
|
terminal-table (>= 2, < 4)
|
62
|
+
strscan (3.0.6)
|
50
63
|
terminal-table (3.0.2)
|
51
64
|
unicode-display_width (>= 1.1.1, < 3)
|
52
65
|
thor (1.2.1)
|
53
66
|
thread_safe (0.3.6)
|
54
|
-
tzinfo (2.0.
|
67
|
+
tzinfo (2.0.6)
|
55
68
|
concurrent-ruby (~> 1.0)
|
56
|
-
unicode-display_width (2.
|
69
|
+
unicode-display_width (2.4.2)
|
57
70
|
|
58
71
|
PLATFORMS
|
59
72
|
ruby
|
@@ -62,7 +75,7 @@ DEPENDENCIES
|
|
62
75
|
minitest (~> 5.0)
|
63
76
|
protobuf (~> 3.10)
|
64
77
|
rake (~> 12.0)
|
65
|
-
rbs
|
78
|
+
rbs (~> 3.1)
|
66
79
|
rbs_protobuf!
|
67
80
|
steep
|
68
81
|
|
data/README.md
CHANGED
@@ -82,21 +82,6 @@ Run `protoc` with `--rbs_out` option.
|
|
82
82
|
|
83
83
|
You may need `bundle exec protoc ...` to let bundler set up PATH.
|
84
84
|
|
85
|
-
## Type checking
|
86
|
-
|
87
|
-
To type check the output, you need to configure your tools to import [gem_rbs_collection](https://github.com/ruby/gem_rbs_collection) with `rbs collection` command.
|
88
|
-
|
89
|
-
```yaml
|
90
|
-
# Add the dependency in rbs_collection.yaml
|
91
|
-
gems:
|
92
|
-
- name: rbs_protobuf
|
93
|
-
```
|
94
|
-
|
95
|
-
We assume that you don't type check the generated `.pb.rb` code.
|
96
|
-
If you want to type check them, you need the definition of `Google::Protobuf`, which can be generated from [`descriptor.proto`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto).
|
97
|
-
|
98
|
-
Note: `rbs_protobuf` generates RBS files assuming some types added in [this PR](https://github.com/ruby/gem_rbs_collection/pull/145). Make sure you are using one of the newer versions of `rbs_gem_collection` definitions.
|
99
|
-
|
100
85
|
### Options
|
101
86
|
|
102
87
|
* `RBS_PROTOBUF_BACKEND` specifies the Ruby code generator gem. Supported value is `protobuf`. (We will add `google-protobuf` for `google-protobuf` gem.)
|
@@ -104,6 +89,20 @@ Note: `rbs_protobuf` generates RBS files assuming some types added in [this PR](
|
|
104
89
|
* `RBS_PROTOBUF_NO_NESTED_NAMESPACE` is to make the RBS declarations flat.
|
105
90
|
* `RBS_PROTOBUF_EXTENSION` specifies what to do for extensions.
|
106
91
|
* `RBS_PROTOBUF_ACCEPT_NIL_ATTR_WRITER` is to allow passing `nil` to required fields.
|
92
|
+
* `RBS_PROTOBUF_FILTERS` contains filter Ruby script paths separated by `File::PATH_SEPARATOR`
|
93
|
+
* `RBS_PROTOBUF_CONCAT_LEVEL` contains the number of dir levels that groups generated RBS files to concat
|
94
|
+
|
95
|
+
## Type checking
|
96
|
+
|
97
|
+
To type check the output, make sure your type checker configuration loads type definitions of `protobuf` gem.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
# Declare in Gemfile and load it with rbs-collection
|
101
|
+
gem 'protobuf'
|
102
|
+
```
|
103
|
+
|
104
|
+
We assume that you don't type check the generated `.pb.rb` code.
|
105
|
+
If you want to type check them, you need the definition of `Google::Protobuf`, which can be generated from [`descriptor.proto`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto).
|
107
106
|
|
108
107
|
## Supported features
|
109
108
|
|
@@ -118,7 +117,7 @@ Note: `rbs_protobuf` generates RBS files assuming some types added in [this PR](
|
|
118
117
|
| Services | Only generates classes |
|
119
118
|
| Oneof | No support in `protobuf` gem |
|
120
119
|
|
121
|
-
|
120
|
+
## Extensions
|
122
121
|
|
123
122
|
Adding extensions may cause problems if the name of new attribute conflicts.
|
124
123
|
|
@@ -144,6 +143,27 @@ You can control the behavior with `RBS_PROTOBUF_EXTENSION` environment variable.
|
|
144
143
|
* Any value else: Generates RBS for extensions.
|
145
144
|
* undefined: Ignores extensions but print messages to ask you to specify a value.
|
146
145
|
|
146
|
+
## Filters
|
147
|
+
|
148
|
+
You can apply filters that modifies generated RBS files.
|
149
|
+
|
150
|
+
A filter is a proc object with type of `^(String rbs_name, String rbs_content, untyped proto_file) -> [String, String]`:
|
151
|
+
It receives the file name of RBS file, the content of RBS file, the source protobuf object, and returns a pair of RBS file name and content.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
# example_fitler.rb: It adds a warning comment at the top of the RBS content.
|
155
|
+
->(rbs_name, rbs_content, _proto_file) {
|
156
|
+
[
|
157
|
+
rbs_name,
|
158
|
+
"# Don't modify this file. This is generated with rbs_protobuf.\n\n" + rbs_content
|
159
|
+
]
|
160
|
+
}
|
161
|
+
```
|
162
|
+
|
163
|
+
You can apply filters by setting `RBS_PROTOBUF_FILTERS` environment variable.
|
164
|
+
|
165
|
+
$ RBS_PROTOBUF_BACKEND=protobuf RBS_PROTOBUF_FILTERS=example_filter.rb protoc ...
|
166
|
+
|
147
167
|
## Development
|
148
168
|
|
149
169
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test example:typecheck` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/Rakefile
CHANGED
@@ -27,7 +27,8 @@ namespace :example do
|
|
27
27
|
"-I#{proto_path}",
|
28
28
|
"example/a.proto",
|
29
29
|
"example/b.proto",
|
30
|
-
"example/c.proto"
|
30
|
+
"example/c.proto",
|
31
|
+
"example/d.proto"
|
31
32
|
)
|
32
33
|
sh(
|
33
34
|
{ "RBS_PROTOBUF_BACKEND" => "protobuf", "RBS_PROTOBUF_EXTENSION" => "true" },
|
@@ -35,7 +36,8 @@ namespace :example do
|
|
35
36
|
"--rbs_out=example/protobuf-gem",
|
36
37
|
"-Iexample",
|
37
38
|
"example/a.proto",
|
38
|
-
"example/b.proto"
|
39
|
+
"example/b.proto",
|
40
|
+
"example/d.proto"
|
39
41
|
)
|
40
42
|
sh(
|
41
43
|
{ "RBS_PROTOBUF_BACKEND" => "protobuf", "RBS_PROTOBUF_EXTENSION" => "true", "RUBYOPT" => "-rbundler/setup -Iexample/protobuf-gem -rc.pb" },
|
data/Steepfile
CHANGED
data/bin/protoc-gen-dumper
CHANGED
@@ -7,5 +7,7 @@ require "rbs_protobuf"
|
|
7
7
|
input = STDIN.read()
|
8
8
|
File.write(ENV["PROTOC_DUMPER_OUT"] || "a.pb.out", input)
|
9
9
|
|
10
|
-
response = Google::Protobuf::Compiler::CodeGeneratorResponse.new
|
10
|
+
response = Google::Protobuf::Compiler::CodeGeneratorResponse.new(
|
11
|
+
:supported_features => ::Google::Protobuf::Compiler::CodeGeneratorResponse::Feature::FEATURE_PROTO3_OPTIONAL.to_i
|
12
|
+
)
|
11
13
|
print Google::Protobuf::Compiler::CodeGeneratorResponse.encode(response)
|
data/bin/setup
CHANGED
@@ -9,13 +9,4 @@ echo ">>> Checking if protoc is available... 👀"
|
|
9
9
|
protoc --version
|
10
10
|
|
11
11
|
echo ">>> Setting up gem_rbs_collection... 💎"
|
12
|
-
REPODIR=$(cd $(dirname $0)/..; pwd)/tmp/rbs/gem_rbs_collection
|
13
|
-
if [ -e $REPODIR ]; then
|
14
|
-
echo " ${REPODIR} exists"
|
15
|
-
else
|
16
|
-
echo " Cloning git repo into ${REPODIR}..."
|
17
|
-
mkdir -p $REPODIR/..
|
18
|
-
git clone https://github.com/ruby/gem_rbs_collection.git ${REPODIR}
|
19
|
-
fi
|
20
|
-
|
21
12
|
bundle exec rbs collection install
|
data/example/d.proto
ADDED
data/exe/protoc-gen-rbs
CHANGED
@@ -13,6 +13,20 @@ unless backend
|
|
13
13
|
exit 1
|
14
14
|
end
|
15
15
|
|
16
|
+
filters = []
|
17
|
+
|
18
|
+
if string = ENV["RBS_PROTOBUF_FILTERS"]
|
19
|
+
string.split(File::PATH_SEPARATOR).each do |file|
|
20
|
+
filter = Module.new.instance_eval(File.read(file), file)
|
21
|
+
|
22
|
+
if filter.respond_to?(:call)
|
23
|
+
filters << filter
|
24
|
+
else
|
25
|
+
raise "A filter `#{file}` returns `#{filter.inspect}`, but a proc object of type `^(String rbs_name, String rbs_content, untyped proto_file) -> [String, String]` is expected"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
16
30
|
input = Google::Protobuf::Compiler::CodeGeneratorRequest.decode(STDIN.read)
|
17
31
|
|
18
32
|
translator = case backend
|
@@ -34,6 +48,7 @@ translator = case backend
|
|
34
48
|
|
35
49
|
RBSProtobuf::Translator::ProtobufGem.new(
|
36
50
|
input,
|
51
|
+
filters,
|
37
52
|
upcase_enum: upcase_enum,
|
38
53
|
nested_namespace: !no_nested_namespace,
|
39
54
|
extension: extension,
|
@@ -43,6 +58,9 @@ translator = case backend
|
|
43
58
|
raise NotImplementedError
|
44
59
|
end
|
45
60
|
|
61
|
+
if level = ENV["RBS_PROTOBUF_CONCAT_LEVEL"]
|
62
|
+
translator.rbs_concat_level = level.to_i
|
63
|
+
end
|
46
64
|
translator.generate_rbs!
|
47
65
|
|
48
66
|
response = translator.response
|
@@ -3,10 +3,19 @@ module RBSProtobuf
|
|
3
3
|
class Base
|
4
4
|
FieldDescriptorProto = Google::Protobuf::FieldDescriptorProto
|
5
5
|
|
6
|
-
attr_reader :input
|
6
|
+
attr_reader :input, :filters
|
7
7
|
|
8
|
-
|
8
|
+
attr_accessor :rbs_concat_level
|
9
|
+
|
10
|
+
def initialize(input, filters = [])
|
9
11
|
@input = input
|
12
|
+
@filters = filters
|
13
|
+
end
|
14
|
+
|
15
|
+
def apply_filter(rbs_name, rbs_content, proto_files)
|
16
|
+
filters.inject([rbs_name, rbs_content]) do |(rbs_name, rbs_content), filter| #$ [String, String]
|
17
|
+
filter[rbs_name, rbs_content, proto_files] or return
|
18
|
+
end
|
10
19
|
end
|
11
20
|
|
12
21
|
def factory
|
@@ -14,18 +23,65 @@ module RBSProtobuf
|
|
14
23
|
end
|
15
24
|
|
16
25
|
def response
|
17
|
-
@response ||= Google::Protobuf::Compiler::CodeGeneratorResponse.new
|
26
|
+
@response ||= Google::Protobuf::Compiler::CodeGeneratorResponse.new(:supported_features => ::Google::Protobuf::Compiler::CodeGeneratorResponse::Feature::FEATURE_PROTO3_OPTIONAL.to_i)
|
18
27
|
end
|
19
28
|
|
20
29
|
def generate_rbs!
|
30
|
+
rbs_decls = {} #: Hash[Pathname, [Array[RBS::AST::Declarations::t], untyped]]
|
31
|
+
|
21
32
|
input.proto_file.each do |file|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
33
|
+
path = Pathname(file.name).sub_ext(".rbs")
|
34
|
+
decls = rbs_content(file)
|
35
|
+
rbs_decls[path] = [decls, file]
|
36
|
+
end
|
37
|
+
|
38
|
+
rbs_contents = {} #: Hash[Pathname, [String, Array[untyped]]]
|
39
|
+
|
40
|
+
if (level = rbs_concat_level)&.nonzero?
|
41
|
+
groups = rbs_decls.each_key.group_by do |path|
|
42
|
+
path.sub_ext("").to_s.split(File::SEPARATOR).take(level).join(File::SEPARATOR)
|
43
|
+
end
|
44
|
+
|
45
|
+
groups.each do |prefix, paths|
|
46
|
+
path = Pathname(prefix).sub_ext(".rbs")
|
47
|
+
|
48
|
+
decls = [] #: Array[RBS::AST::Declarations::t]
|
49
|
+
files = [] #: Array[untyped]
|
50
|
+
|
51
|
+
paths.each do |path|
|
52
|
+
ds, file = rbs_decls.fetch(path)
|
53
|
+
decls.concat(ds)
|
54
|
+
files.push(file)
|
55
|
+
end
|
56
|
+
|
57
|
+
rbs_contents[path] = [
|
58
|
+
format_rbs(decls: decls),
|
59
|
+
files
|
60
|
+
]
|
61
|
+
end
|
62
|
+
else
|
63
|
+
rbs_decls.each do |path, (decls, file)|
|
64
|
+
content = format_rbs(decls: decls)
|
65
|
+
rbs_contents[path] = [content, [file]]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
rbs_contents.each do |path, (content, files)|
|
70
|
+
if (name, content = apply_filter(path.to_s, content, files))
|
71
|
+
response.file << Google::Protobuf::Compiler::CodeGeneratorResponse::File.new(
|
72
|
+
name: name,
|
73
|
+
content: content
|
74
|
+
)
|
75
|
+
end
|
26
76
|
end
|
27
77
|
end
|
28
78
|
|
79
|
+
def format_rbs(dirs: [], decls: [])
|
80
|
+
StringIO.new.tap do |io|
|
81
|
+
RBS::Writer.new(out: io).write(dirs + decls)
|
82
|
+
end.string
|
83
|
+
end
|
84
|
+
|
29
85
|
def rbs_name(proto_name)
|
30
86
|
dirname = File.dirname(proto_name)
|
31
87
|
basename = File.basename(proto_name, File.extname(proto_name))
|
@@ -120,6 +176,15 @@ module RBSProtobuf
|
|
120
176
|
)
|
121
177
|
)
|
122
178
|
end
|
179
|
+
|
180
|
+
def optional_type(type)
|
181
|
+
case type
|
182
|
+
when RBS::Types::Optional
|
183
|
+
type
|
184
|
+
else
|
185
|
+
RBS::Types::Optional.new(type: type, location: nil)
|
186
|
+
end
|
187
|
+
end
|
123
188
|
end
|
124
189
|
end
|
125
190
|
end
|