rbs_protobuf 1.0.0 → 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/.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
|