rbs_rails 0.9.0 → 0.11.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/ci.yml +1 -1
- data/CHANGELOG.md +28 -0
- data/DESIGN.md +36 -0
- data/Gemfile +3 -3
- data/Gemfile.lock +104 -106
- data/README.md +14 -30
- data/lib/generators/rbs_rails/install_generator.rb +26 -0
- data/lib/rbs_rails/active_record.rb +102 -11
- data/lib/rbs_rails/dependency_builder.rb +2 -2
- data/lib/rbs_rails/rake_task.rb +1 -0
- data/lib/rbs_rails/version.rb +1 -1
- data/rbs_collection.lock.yaml +56 -44
- data/rbs_collection.yaml +10 -19
- data/sig/{activerecord.rbs → _internal/activerecord.rbs} +0 -0
- data/sig/{fileutils.rbs → _internal/fileutils.rbs} +0 -0
- data/sig/_internal/thor.rbs +5 -0
- data/sig/install_generator.rbs +5 -0
- data/sig/rbs_rails/active_record.rbs +5 -0
- data/sig/rbs_rails/dependency_builder.rbs +1 -0
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66770df53a677c589c39cfd828149a60b4ef261979e11cc7dc823a1df475495f
|
4
|
+
data.tar.gz: 88de9ae8cc7597b4e28978f9a72a696742a5ece83b4d401fed92061fdd2b1590
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e76c5de12b626f50db6f7e032dc323de1c79067a3cb9f8e0c4e3ba5ebd71d30d4e1679144573b3eec2788d75edd33b4ff084c5ffb7ccb8839f2293e5f061595e
|
7
|
+
data.tar.gz: b259952abf7664a8335a8cebda843e869a1b38c27fa010d0a927134aa56d11d63e4df20ce3850c9c2d12f62228593bd14f75ff95b7f782d00dc90d19610e71c1
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,34 @@
|
|
2
2
|
|
3
3
|
## master (unreleased)
|
4
4
|
|
5
|
+
## 0.11.0 (2022-03-24)
|
6
|
+
|
7
|
+
### New Features
|
8
|
+
|
9
|
+
* Add rails generator to generate rbs.rake. [#217](https://github.com/pocke/rbs_rails/pull/217)
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Do not expose polyfil RBSs. [#218](https://github.com/pocke/rbs_rails/pull/218)
|
14
|
+
|
15
|
+
## 0.10.1 (2022-03-23)
|
16
|
+
|
17
|
+
### Bug Fixes
|
18
|
+
|
19
|
+
* Generate dependency types of relations. [#216](https://github.com/pocke/rbs_rails/pull/216)
|
20
|
+
|
21
|
+
## 0.10.0 (2022-03-18)
|
22
|
+
|
23
|
+
### New Features
|
24
|
+
|
25
|
+
* Support `has_secure_password`. [#193](https://github.com/pocke/rbs_rails/pull/193)
|
26
|
+
* Support Active Storage. [#195](https://github.com/pocke/rbs_rails/pull/195)
|
27
|
+
|
28
|
+
### Bug Fixes
|
29
|
+
|
30
|
+
* Use absolute path for class names to avoid using incorrect class. [#201](https://github.com/pocke/rbs_rails/pull/201)
|
31
|
+
* Fix NoMethodError on enum with `_default` option. [#208](https://github.com/pocke/rbs_rails/pull/208)
|
32
|
+
|
5
33
|
## 0.9.0 (2021-09-18)
|
6
34
|
|
7
35
|
### New Features
|
data/DESIGN.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# RBS Generator for Active Record models
|
2
|
+
|
3
|
+
The RBS generator for Active Record models focus on generating methods that are generated by Active Record.
|
4
|
+
For example, it generates the following things.
|
5
|
+
|
6
|
+
* Classes which inherit `ActiveRecord::Base`
|
7
|
+
* Generated methods by Active Record
|
8
|
+
* Column methods. e.g. `name` and `name=` methods for `name` column.
|
9
|
+
* Relation methods. e.g. `users` and `users=` methods for `has_many :users`.
|
10
|
+
* And so on.
|
11
|
+
|
12
|
+
I designed it generates "valid" RBSs. "valid" means the generated RBSs pass `rbs validate` only with `rbs collection`.
|
13
|
+
So if you need to do something to pass `rbs validate`, it's a bug. For example, if you see `RBS::NoSuperclassFoundError` for the generated RBS, it is a bug.
|
14
|
+
|
15
|
+
RBS Rails focuses on generating "generated" methods. It means it doesn't generate methods that are defined by the user.
|
16
|
+
For example:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
class User < ApplicationRecord
|
20
|
+
# RBS Rails generates articles methods and so on
|
21
|
+
# becasue they are generated by Active Record.
|
22
|
+
has_many :articles
|
23
|
+
|
24
|
+
# RBS Rails does NOT generate full_name method
|
25
|
+
# because the user defines it.
|
26
|
+
def full_name
|
27
|
+
first_name + last_name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
You can use `rbs prototype rb`, `rbs prototype runtime` and `typeprof` commands to generate them.
|
33
|
+
|
34
|
+
# RBS Generator for the path helper
|
35
|
+
|
36
|
+
TODO
|
data/Gemfile
CHANGED
@@ -6,7 +6,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
6
6
|
gemspec
|
7
7
|
|
8
8
|
gem "rake", "~> 13.0"
|
9
|
-
gem 'rails', '<
|
10
|
-
gem 'rbs', '>=
|
11
|
-
gem 'steep'
|
9
|
+
gem 'rails', '< 7', '>= 6.0'
|
10
|
+
gem 'rbs', '>= 2'
|
11
|
+
gem 'steep'
|
12
12
|
gem 'minitest'
|
data/Gemfile.lock
CHANGED
@@ -1,167 +1,165 @@
|
|
1
|
-
GIT
|
2
|
-
remote: https://github.com/soutaro/steep
|
3
|
-
revision: 0673d88395fb0ea380463fef1aed568dfb077a60
|
4
|
-
specs:
|
5
|
-
steep (0.46.0)
|
6
|
-
activesupport (>= 5.1)
|
7
|
-
language_server-protocol (>= 3.15, < 4.0)
|
8
|
-
listen (~> 3.0)
|
9
|
-
parallel (>= 1.0.0)
|
10
|
-
parser (>= 3.0)
|
11
|
-
rainbow (>= 2.2.2, < 4.0)
|
12
|
-
rbs (>= 1.6.0)
|
13
|
-
terminal-table (>= 2, < 4)
|
14
|
-
|
15
1
|
PATH
|
16
2
|
remote: .
|
17
3
|
specs:
|
18
|
-
rbs_rails (0.
|
4
|
+
rbs_rails (0.11.0)
|
19
5
|
parser
|
20
6
|
rbs (>= 1)
|
21
7
|
|
22
8
|
GEM
|
23
9
|
remote: https://rubygems.org/
|
24
10
|
specs:
|
25
|
-
actioncable (6.
|
26
|
-
actionpack (= 6.
|
11
|
+
actioncable (6.1.5)
|
12
|
+
actionpack (= 6.1.5)
|
13
|
+
activesupport (= 6.1.5)
|
27
14
|
nio4r (~> 2.0)
|
28
15
|
websocket-driver (>= 0.6.1)
|
29
|
-
actionmailbox (6.
|
30
|
-
actionpack (= 6.
|
31
|
-
activejob (= 6.
|
32
|
-
activerecord (= 6.
|
33
|
-
activestorage (= 6.
|
34
|
-
activesupport (= 6.
|
16
|
+
actionmailbox (6.1.5)
|
17
|
+
actionpack (= 6.1.5)
|
18
|
+
activejob (= 6.1.5)
|
19
|
+
activerecord (= 6.1.5)
|
20
|
+
activestorage (= 6.1.5)
|
21
|
+
activesupport (= 6.1.5)
|
35
22
|
mail (>= 2.7.1)
|
36
|
-
actionmailer (6.
|
37
|
-
actionpack (= 6.
|
38
|
-
actionview (= 6.
|
39
|
-
activejob (= 6.
|
23
|
+
actionmailer (6.1.5)
|
24
|
+
actionpack (= 6.1.5)
|
25
|
+
actionview (= 6.1.5)
|
26
|
+
activejob (= 6.1.5)
|
27
|
+
activesupport (= 6.1.5)
|
40
28
|
mail (~> 2.5, >= 2.5.4)
|
41
29
|
rails-dom-testing (~> 2.0)
|
42
|
-
actionpack (6.
|
43
|
-
actionview (= 6.
|
44
|
-
activesupport (= 6.
|
45
|
-
rack (~> 2.0, >= 2.0.
|
30
|
+
actionpack (6.1.5)
|
31
|
+
actionview (= 6.1.5)
|
32
|
+
activesupport (= 6.1.5)
|
33
|
+
rack (~> 2.0, >= 2.0.9)
|
46
34
|
rack-test (>= 0.6.3)
|
47
35
|
rails-dom-testing (~> 2.0)
|
48
36
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
49
|
-
actiontext (6.
|
50
|
-
actionpack (= 6.
|
51
|
-
activerecord (= 6.
|
52
|
-
activestorage (= 6.
|
53
|
-
activesupport (= 6.
|
37
|
+
actiontext (6.1.5)
|
38
|
+
actionpack (= 6.1.5)
|
39
|
+
activerecord (= 6.1.5)
|
40
|
+
activestorage (= 6.1.5)
|
41
|
+
activesupport (= 6.1.5)
|
54
42
|
nokogiri (>= 1.8.5)
|
55
|
-
actionview (6.
|
56
|
-
activesupport (= 6.
|
43
|
+
actionview (6.1.5)
|
44
|
+
activesupport (= 6.1.5)
|
57
45
|
builder (~> 3.1)
|
58
46
|
erubi (~> 1.4)
|
59
47
|
rails-dom-testing (~> 2.0)
|
60
48
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
61
|
-
activejob (6.
|
62
|
-
activesupport (= 6.
|
49
|
+
activejob (6.1.5)
|
50
|
+
activesupport (= 6.1.5)
|
63
51
|
globalid (>= 0.3.6)
|
64
|
-
activemodel (6.
|
65
|
-
activesupport (= 6.
|
66
|
-
activerecord (6.
|
67
|
-
activemodel (= 6.
|
68
|
-
activesupport (= 6.
|
69
|
-
activestorage (6.
|
70
|
-
actionpack (= 6.
|
71
|
-
activejob (= 6.
|
72
|
-
activerecord (= 6.
|
73
|
-
|
74
|
-
|
52
|
+
activemodel (6.1.5)
|
53
|
+
activesupport (= 6.1.5)
|
54
|
+
activerecord (6.1.5)
|
55
|
+
activemodel (= 6.1.5)
|
56
|
+
activesupport (= 6.1.5)
|
57
|
+
activestorage (6.1.5)
|
58
|
+
actionpack (= 6.1.5)
|
59
|
+
activejob (= 6.1.5)
|
60
|
+
activerecord (= 6.1.5)
|
61
|
+
activesupport (= 6.1.5)
|
62
|
+
marcel (~> 1.0)
|
63
|
+
mini_mime (>= 1.1.0)
|
64
|
+
activesupport (6.1.5)
|
75
65
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
76
|
-
i18n (>=
|
77
|
-
minitest (
|
78
|
-
tzinfo (~>
|
79
|
-
zeitwerk (~> 2.
|
66
|
+
i18n (>= 1.6, < 2)
|
67
|
+
minitest (>= 5.1)
|
68
|
+
tzinfo (~> 2.0)
|
69
|
+
zeitwerk (~> 2.3)
|
80
70
|
ast (2.4.2)
|
81
71
|
builder (3.2.4)
|
82
72
|
concurrent-ruby (1.1.9)
|
83
73
|
crass (1.0.6)
|
84
74
|
erubi (1.10.0)
|
85
|
-
ffi (1.15.
|
86
|
-
globalid (0.
|
75
|
+
ffi (1.15.5)
|
76
|
+
globalid (1.0.0)
|
87
77
|
activesupport (>= 5.0)
|
88
|
-
i18n (1.
|
78
|
+
i18n (1.10.0)
|
89
79
|
concurrent-ruby (~> 1.0)
|
90
80
|
language_server-protocol (3.16.0.3)
|
91
|
-
listen (3.7.
|
81
|
+
listen (3.7.1)
|
92
82
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
93
83
|
rb-inotify (~> 0.9, >= 0.9.10)
|
94
|
-
loofah (2.
|
84
|
+
loofah (2.15.0)
|
95
85
|
crass (~> 1.0.2)
|
96
86
|
nokogiri (>= 1.5.9)
|
97
87
|
mail (2.7.1)
|
98
88
|
mini_mime (>= 0.1.1)
|
99
|
-
marcel (1.0.
|
89
|
+
marcel (1.0.2)
|
100
90
|
method_source (1.0.0)
|
101
|
-
mini_mime (1.1.
|
102
|
-
mini_portile2 (2.
|
103
|
-
minitest (5.
|
91
|
+
mini_mime (1.1.2)
|
92
|
+
mini_portile2 (2.8.0)
|
93
|
+
minitest (5.15.0)
|
104
94
|
nio4r (2.5.8)
|
105
|
-
nokogiri (1.
|
106
|
-
mini_portile2 (~> 2.
|
95
|
+
nokogiri (1.13.3)
|
96
|
+
mini_portile2 (~> 2.8.0)
|
107
97
|
racc (~> 1.4)
|
108
|
-
parallel (1.
|
109
|
-
parser (3.
|
98
|
+
parallel (1.21.0)
|
99
|
+
parser (3.1.1.0)
|
110
100
|
ast (~> 2.4.1)
|
111
|
-
racc (1.
|
101
|
+
racc (1.6.0)
|
112
102
|
rack (2.2.3)
|
113
103
|
rack-test (1.1.0)
|
114
104
|
rack (>= 1.0, < 3)
|
115
|
-
rails (6.
|
116
|
-
actioncable (= 6.
|
117
|
-
actionmailbox (= 6.
|
118
|
-
actionmailer (= 6.
|
119
|
-
actionpack (= 6.
|
120
|
-
actiontext (= 6.
|
121
|
-
actionview (= 6.
|
122
|
-
activejob (= 6.
|
123
|
-
activemodel (= 6.
|
124
|
-
activerecord (= 6.
|
125
|
-
activestorage (= 6.
|
126
|
-
activesupport (= 6.
|
127
|
-
bundler (>= 1.
|
128
|
-
railties (= 6.
|
105
|
+
rails (6.1.5)
|
106
|
+
actioncable (= 6.1.5)
|
107
|
+
actionmailbox (= 6.1.5)
|
108
|
+
actionmailer (= 6.1.5)
|
109
|
+
actionpack (= 6.1.5)
|
110
|
+
actiontext (= 6.1.5)
|
111
|
+
actionview (= 6.1.5)
|
112
|
+
activejob (= 6.1.5)
|
113
|
+
activemodel (= 6.1.5)
|
114
|
+
activerecord (= 6.1.5)
|
115
|
+
activestorage (= 6.1.5)
|
116
|
+
activesupport (= 6.1.5)
|
117
|
+
bundler (>= 1.15.0)
|
118
|
+
railties (= 6.1.5)
|
129
119
|
sprockets-rails (>= 2.0.0)
|
130
120
|
rails-dom-testing (2.0.3)
|
131
121
|
activesupport (>= 4.2.0)
|
132
122
|
nokogiri (>= 1.6)
|
133
123
|
rails-html-sanitizer (1.4.2)
|
134
124
|
loofah (~> 2.3)
|
135
|
-
railties (6.
|
136
|
-
actionpack (= 6.
|
137
|
-
activesupport (= 6.
|
125
|
+
railties (6.1.5)
|
126
|
+
actionpack (= 6.1.5)
|
127
|
+
activesupport (= 6.1.5)
|
138
128
|
method_source
|
139
|
-
rake (>=
|
140
|
-
thor (
|
141
|
-
rainbow (3.
|
129
|
+
rake (>= 12.2)
|
130
|
+
thor (~> 1.0)
|
131
|
+
rainbow (3.1.1)
|
142
132
|
rake (13.0.6)
|
143
|
-
rb-fsevent (0.11.
|
133
|
+
rb-fsevent (0.11.1)
|
144
134
|
rb-inotify (0.10.1)
|
145
135
|
ffi (~> 1.0)
|
146
|
-
rbs (
|
147
|
-
sprockets (4.0.
|
136
|
+
rbs (2.2.2)
|
137
|
+
sprockets (4.0.3)
|
148
138
|
concurrent-ruby (~> 1.0)
|
149
139
|
rack (> 1, < 3)
|
150
|
-
sprockets-rails (3.
|
151
|
-
actionpack (>=
|
152
|
-
activesupport (>=
|
140
|
+
sprockets-rails (3.4.2)
|
141
|
+
actionpack (>= 5.2)
|
142
|
+
activesupport (>= 5.2)
|
153
143
|
sprockets (>= 3.0.0)
|
154
|
-
|
144
|
+
steep (0.49.1)
|
145
|
+
activesupport (>= 5.1)
|
146
|
+
language_server-protocol (>= 3.15, < 4.0)
|
147
|
+
listen (~> 3.0)
|
148
|
+
parallel (>= 1.0.0)
|
149
|
+
parser (>= 3.0)
|
150
|
+
rainbow (>= 2.2.2, < 4.0)
|
151
|
+
rbs (>= 2.2.0)
|
152
|
+
terminal-table (>= 2, < 4)
|
153
|
+
terminal-table (3.0.2)
|
155
154
|
unicode-display_width (>= 1.1.1, < 3)
|
156
|
-
thor (1.1
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
unicode-display_width (2.0.0)
|
155
|
+
thor (1.2.1)
|
156
|
+
tzinfo (2.0.4)
|
157
|
+
concurrent-ruby (~> 1.0)
|
158
|
+
unicode-display_width (2.1.0)
|
161
159
|
websocket-driver (0.7.5)
|
162
160
|
websocket-extensions (>= 0.1.0)
|
163
161
|
websocket-extensions (0.1.5)
|
164
|
-
zeitwerk (2.4
|
162
|
+
zeitwerk (2.5.4)
|
165
163
|
|
166
164
|
PLATFORMS
|
167
165
|
ruby
|
@@ -169,11 +167,11 @@ PLATFORMS
|
|
169
167
|
|
170
168
|
DEPENDENCIES
|
171
169
|
minitest
|
172
|
-
rails (>= 6.0, <
|
170
|
+
rails (>= 6.0, < 7)
|
173
171
|
rake (~> 13.0)
|
174
|
-
rbs (>=
|
172
|
+
rbs (>= 2)
|
175
173
|
rbs_rails!
|
176
|
-
steep
|
174
|
+
steep
|
177
175
|
|
178
176
|
BUNDLED WITH
|
179
|
-
2.
|
177
|
+
2.3.9
|
data/README.md
CHANGED
@@ -20,12 +20,10 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
Run the following command. It generates `lib/tasks/rbs.rake`.
|
24
24
|
|
25
|
-
```
|
26
|
-
|
27
|
-
|
28
|
-
RbsRails::RakeTask.new
|
25
|
+
```console
|
26
|
+
$ bin/rails g rbs_rails:install
|
29
27
|
```
|
30
28
|
|
31
29
|
Then, the following three tasks are available.
|
@@ -35,44 +33,30 @@ Then, the following three tasks are available.
|
|
35
33
|
* `rbs_rails:all`: Execute all tasks of RBS Rails
|
36
34
|
|
37
35
|
|
36
|
+
### Install RBS for `rails` gem
|
37
|
+
|
38
|
+
You need to install `rails` gem's RBS files. I highly recommend using `rbs collection`.
|
38
39
|
|
40
|
+
1. Add `gem 'rails'` to your `Gemfile`.
|
41
|
+
1. Then execute the following commands
|
42
|
+
```console
|
43
|
+
$ bundle install
|
44
|
+
$ bundle exec rbs collection install
|
45
|
+
```
|
39
46
|
|
40
47
|
### Steep integration
|
41
48
|
|
42
|
-
|
49
|
+
Put the following code as `Steepfile`.
|
43
50
|
|
44
51
|
```ruby
|
45
|
-
# Steepfile
|
46
|
-
|
47
52
|
target :app do
|
48
53
|
signature 'sig'
|
49
54
|
|
50
55
|
check 'app'
|
51
|
-
|
52
|
-
repo_path "path/to/rbs_repo"
|
53
|
-
|
54
|
-
library 'pathname'
|
55
|
-
library 'logger'
|
56
|
-
library 'mutex_m'
|
57
|
-
library 'date'
|
58
|
-
library 'monitor'
|
59
|
-
library 'singleton'
|
60
|
-
library 'tsort'
|
61
|
-
library 'time'
|
62
|
-
|
63
|
-
library 'rack'
|
64
|
-
|
65
|
-
library 'activesupport'
|
66
|
-
library 'actionpack'
|
67
|
-
library 'activejob'
|
68
|
-
library 'activemodel'
|
69
|
-
library 'actionview'
|
70
|
-
library 'activerecord'
|
71
|
-
library 'railties'
|
72
56
|
end
|
73
57
|
```
|
74
58
|
|
75
|
-
|
59
|
+
That's all! Now you can check your Rails app statically with `steep check` command.
|
76
60
|
|
77
61
|
## Development
|
78
62
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module RbsRails
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
def create_raketask
|
6
|
+
create_file "lib/tasks/rbs.rake", <<~RUBY
|
7
|
+
require 'rbs_rails/rake_task'
|
8
|
+
|
9
|
+
RbsRails::RakeTask.new do |task|
|
10
|
+
# If you want to avoid generating RBS for some classes, comment in it.
|
11
|
+
# default: nil
|
12
|
+
#
|
13
|
+
# task.ignore_model_if = -> (klass) { klass == MyClass }
|
14
|
+
|
15
|
+
# If you want to change the rake task namespace, comment in it.
|
16
|
+
# default: :rbs_rails
|
17
|
+
# task.name = :cool_rbs_rails
|
18
|
+
|
19
|
+
# If you want to change where RBS Rails writes RBSs into, comment in it.
|
20
|
+
# default: Rails.root / 'sig/rbs_rails'
|
21
|
+
# task.signature_root_dir = Rails.root / 'my_sig/rbs_rails'
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -32,6 +32,8 @@ module RbsRails
|
|
32
32
|
|
33
33
|
#{columns}
|
34
34
|
#{associations}
|
35
|
+
#{generated_association_methods}
|
36
|
+
#{has_secure_password}
|
35
37
|
#{delegated_type_instance}
|
36
38
|
#{delegated_type_scope(singleton: true)}
|
37
39
|
#{enum_instance_methods}
|
@@ -68,7 +70,7 @@ module RbsRails
|
|
68
70
|
|
69
71
|
private def relation_decl
|
70
72
|
<<~RBS
|
71
|
-
class #{relation_class_name} < ActiveRecord::Relation
|
73
|
+
class #{relation_class_name} < ::ActiveRecord::Relation
|
72
74
|
include GeneratedRelationMethods
|
73
75
|
include _ActiveRecord_Relation[#{klass_name}, #{pk_type}]
|
74
76
|
include Enumerable[#{klass_name}]
|
@@ -78,7 +80,7 @@ module RbsRails
|
|
78
80
|
|
79
81
|
private def collection_proxy_decl
|
80
82
|
<<~RBS
|
81
|
-
class ActiveRecord_Associations_CollectionProxy < ActiveRecord::Associations::CollectionProxy
|
83
|
+
class ActiveRecord_Associations_CollectionProxy < ::ActiveRecord::Associations::CollectionProxy
|
82
84
|
include GeneratedRelationMethods
|
83
85
|
include _ActiveRecord_Relation[#{klass_name}, #{pk_type}]
|
84
86
|
end
|
@@ -97,7 +99,7 @@ module RbsRails
|
|
97
99
|
superclass_name = Util.module_name(superclass)
|
98
100
|
@dependencies << superclass_name
|
99
101
|
|
100
|
-
"class #{mod_name} <
|
102
|
+
"class #{mod_name} < ::#{superclass_name}"
|
101
103
|
when Module
|
102
104
|
"module #{mod_name}"
|
103
105
|
else
|
@@ -120,9 +122,13 @@ module RbsRails
|
|
120
122
|
|
121
123
|
private def has_many
|
122
124
|
klass.reflect_on_all_associations(:has_many).map do |a|
|
125
|
+
@dependencies << a.klass.name
|
126
|
+
|
123
127
|
singular_name = a.name.to_s.singularize
|
124
128
|
type = Util.module_name(a.klass)
|
125
129
|
collection_type = "#{type}::ActiveRecord_Associations_CollectionProxy"
|
130
|
+
@dependencies << collection_type
|
131
|
+
|
126
132
|
<<~RUBY.chomp
|
127
133
|
def #{a.name}: () -> #{collection_type}
|
128
134
|
def #{a.name}=: (#{collection_type} | Array[#{type}]) -> (#{collection_type} | Array[#{type}])
|
@@ -134,6 +140,8 @@ module RbsRails
|
|
134
140
|
|
135
141
|
private def has_one
|
136
142
|
klass.reflect_on_all_associations(:has_one).map do |a|
|
143
|
+
@dependencies << a.klass.name unless a.polymorphic?
|
144
|
+
|
137
145
|
type = a.polymorphic? ? 'untyped' : Util.module_name(a.klass)
|
138
146
|
type_optional = optional(type)
|
139
147
|
<<~RUBY.chomp
|
@@ -149,6 +157,8 @@ module RbsRails
|
|
149
157
|
|
150
158
|
private def belongs_to
|
151
159
|
klass.reflect_on_all_associations(:belongs_to).map do |a|
|
160
|
+
@dependencies << a.klass.name unless a.polymorphic?
|
161
|
+
|
152
162
|
type = a.polymorphic? ? 'untyped' : Util.module_name(a.klass)
|
153
163
|
type_optional = optional(type)
|
154
164
|
# @type var methods: Array[String]
|
@@ -165,6 +175,41 @@ module RbsRails
|
|
165
175
|
end.join("\n")
|
166
176
|
end
|
167
177
|
|
178
|
+
private def generated_association_methods
|
179
|
+
# @type var sigs: Array[String]
|
180
|
+
sigs = []
|
181
|
+
|
182
|
+
# Needs to require "active_storage/engine"
|
183
|
+
if klass.respond_to?(:attachment_reflections)
|
184
|
+
sigs << "module GeneratedAssociationMethods"
|
185
|
+
sigs << klass.attachment_reflections.map do |name, reflection|
|
186
|
+
case reflection.macro
|
187
|
+
when :has_one_attached
|
188
|
+
<<~EOS
|
189
|
+
def #{name}: () -> ActiveStorage::Attached::One
|
190
|
+
def #{name}=: (ActionDispatch::Http::UploadedFile) -> ActionDispatch::Http::UploadedFile
|
191
|
+
| (Rack::Test::UploadedFile) -> Rack::Test::UploadedFile
|
192
|
+
| (ActiveStorage::Blob) -> ActiveStorage::Blob
|
193
|
+
| (String) -> String
|
194
|
+
| ({ io: IO, filename: String, content_type: String? }) -> { io: IO, filename: String, content_type: String? }
|
195
|
+
| (nil) -> nil
|
196
|
+
EOS
|
197
|
+
when :has_many_attached
|
198
|
+
<<~EOS
|
199
|
+
def #{name}: () -> ActiveStorage::Attached::Many
|
200
|
+
def #{name}=: (untyped) -> untyped
|
201
|
+
EOS
|
202
|
+
else
|
203
|
+
raise
|
204
|
+
end
|
205
|
+
end.join("\n")
|
206
|
+
sigs << "end"
|
207
|
+
sigs << "include GeneratedAssociationMethods"
|
208
|
+
end
|
209
|
+
|
210
|
+
sigs.join("\n")
|
211
|
+
end
|
212
|
+
|
168
213
|
private def delegated_type_scope(singleton:)
|
169
214
|
definitions = delegated_type_definitions
|
170
215
|
return "" unless definitions
|
@@ -236,12 +281,42 @@ module RbsRails
|
|
236
281
|
end.compact
|
237
282
|
end
|
238
283
|
|
284
|
+
private def has_secure_password
|
285
|
+
ast = parse_model_file
|
286
|
+
return unless ast
|
287
|
+
|
288
|
+
traverse(ast).map do |node|
|
289
|
+
# @type block: String?
|
290
|
+
next unless node.type == :send
|
291
|
+
next unless node.children[0].nil?
|
292
|
+
next unless node.children[1] == :has_secure_password
|
293
|
+
|
294
|
+
attribute_node = node.children[2]
|
295
|
+
attribute = if attribute_node && attribute_node.type == :sym
|
296
|
+
attribute_node.children[0]
|
297
|
+
else
|
298
|
+
:password
|
299
|
+
end
|
300
|
+
|
301
|
+
<<~EOS
|
302
|
+
module ActiveModel_SecurePassword_InstanceMethodsOnActivation_#{attribute}
|
303
|
+
attr_reader #{attribute}: String?
|
304
|
+
def #{attribute}=: (String) -> String
|
305
|
+
def #{attribute}_confirmation=: (String) -> String
|
306
|
+
def authenticate_#{attribute}: (String) -> (#{klass_name} | false)
|
307
|
+
#{attribute == :password ? "alias authenticate authenticate_password" : ""}
|
308
|
+
end
|
309
|
+
include ActiveModel_SecurePassword_InstanceMethodsOnActivation_#{attribute}
|
310
|
+
EOS
|
311
|
+
end.compact.join("\n")
|
312
|
+
end
|
313
|
+
|
239
314
|
private def enum_instance_methods
|
240
315
|
# @type var methods: Array[String]
|
241
316
|
methods = []
|
242
317
|
enum_definitions.each do |hash|
|
243
318
|
hash.each do |name, values|
|
244
|
-
next if name == :_prefix || name == :_suffix
|
319
|
+
next if name == :_prefix || name == :_suffix || name == :_default
|
245
320
|
|
246
321
|
values.each do |label, value|
|
247
322
|
value_method_name = enum_method_name(hash, name, label)
|
@@ -259,7 +334,7 @@ module RbsRails
|
|
259
334
|
methods = []
|
260
335
|
enum_definitions.each do |hash|
|
261
336
|
hash.each do |name, values|
|
262
|
-
next if name == :_prefix || name == :_suffix
|
337
|
+
next if name == :_prefix || name == :_suffix || name == :_default
|
263
338
|
|
264
339
|
values.each do |label, value|
|
265
340
|
value_method_name = enum_method_name(hash, name, label)
|
@@ -320,7 +395,9 @@ module RbsRails
|
|
320
395
|
ast = parse_model_file
|
321
396
|
return '' unless ast
|
322
397
|
|
323
|
-
|
398
|
+
prefix = singleton ? 'self.' : ''
|
399
|
+
|
400
|
+
sigs = traverse(ast).map do |node|
|
324
401
|
# @type block: nil | String
|
325
402
|
next unless node.type == :send
|
326
403
|
next unless node.children[0].nil?
|
@@ -336,8 +413,16 @@ module RbsRails
|
|
336
413
|
next unless body_node.type == :block
|
337
414
|
|
338
415
|
args = args_to_type(body_node.children[1])
|
339
|
-
"def #{
|
340
|
-
end.compact
|
416
|
+
"def #{prefix}#{name}: #{args} -> #{relation_class_name}"
|
417
|
+
end.compact
|
418
|
+
|
419
|
+
if klass.respond_to?(:attachment_reflections)
|
420
|
+
klass.attachment_reflections.each do |name, _reflection|
|
421
|
+
sigs << "def #{prefix}with_attached_#{name}: () -> #{relation_class_name}"
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
sigs.join("\n")
|
341
426
|
end
|
342
427
|
|
343
428
|
private def args_to_type(args_node)
|
@@ -396,7 +481,8 @@ module RbsRails
|
|
396
481
|
end
|
397
482
|
|
398
483
|
private def columns
|
399
|
-
|
484
|
+
mod_sig = +"module GeneratedAttributeMethods\n"
|
485
|
+
mod_sig << klass.columns.map do |col|
|
400
486
|
class_name = if enum_definitions.any? { |hash| hash.key?(col.name) || hash.key?(col.name.to_sym) }
|
401
487
|
'String'
|
402
488
|
else
|
@@ -405,7 +491,9 @@ module RbsRails
|
|
405
491
|
class_name_opt = optional(class_name)
|
406
492
|
column_type = col.null ? class_name_opt : class_name
|
407
493
|
sig = <<~EOS
|
408
|
-
|
494
|
+
def #{col.name}: () -> #{column_type}
|
495
|
+
def #{col.name}=: (#{column_type}) -> #{column_type}
|
496
|
+
def #{col.name}?: () -> bool
|
409
497
|
def #{col.name}_changed?: () -> bool
|
410
498
|
def #{col.name}_change: () -> [#{class_name_opt}, #{class_name_opt}]
|
411
499
|
def #{col.name}_will_change!: () -> void
|
@@ -422,9 +510,12 @@ module RbsRails
|
|
422
510
|
def restore_#{col.name}!: () -> void
|
423
511
|
def clear_#{col.name}_change: () -> void
|
424
512
|
EOS
|
425
|
-
sig << "
|
513
|
+
sig << "\n"
|
426
514
|
sig
|
427
515
|
end.join("\n")
|
516
|
+
mod_sig << "\nend\n"
|
517
|
+
mod_sig << "include GeneratedAttributeMethods"
|
518
|
+
mod_sig
|
428
519
|
end
|
429
520
|
|
430
521
|
private def optional(class_name)
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module RbsRails
|
2
2
|
class DependencyBuilder
|
3
|
-
attr_reader :deps
|
3
|
+
attr_reader :deps, :done
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@deps = []
|
7
|
+
@done = Set.new(['ActiveRecord::Base', 'ActiveRecord', 'Object'])
|
7
8
|
end
|
8
9
|
|
9
10
|
def build
|
10
11
|
dep_rbs = +""
|
11
|
-
done = Set.new(['ActiveRecord::Base', 'ActiveRecord', 'Object'])
|
12
12
|
deps.uniq!
|
13
13
|
while dep = deps.shift
|
14
14
|
next unless done.add?(dep)
|
data/lib/rbs_rails/rake_task.rb
CHANGED
data/lib/rbs_rails/version.rb
CHANGED
data/rbs_collection.lock.yaml
CHANGED
@@ -6,59 +6,31 @@ sources:
|
|
6
6
|
repo_dir: gems
|
7
7
|
path: ".gem_rbs_collection"
|
8
8
|
gems:
|
9
|
-
- name: pathname
|
10
|
-
version: '0'
|
11
|
-
source:
|
12
|
-
type: stdlib
|
13
9
|
- name: logger
|
14
10
|
version: '0'
|
15
11
|
source:
|
16
12
|
type: stdlib
|
17
|
-
- name:
|
18
|
-
version: '0'
|
19
|
-
source:
|
20
|
-
type: stdlib
|
21
|
-
- name: date
|
22
|
-
version: '0'
|
23
|
-
source:
|
24
|
-
type: stdlib
|
25
|
-
- name: monitor
|
26
|
-
version: '0'
|
27
|
-
source:
|
28
|
-
type: stdlib
|
29
|
-
- name: singleton
|
30
|
-
version: '0'
|
31
|
-
source:
|
32
|
-
type: stdlib
|
33
|
-
- name: tsort
|
13
|
+
- name: set
|
34
14
|
version: '0'
|
35
15
|
source:
|
36
16
|
type: stdlib
|
37
|
-
- name:
|
17
|
+
- name: pathname
|
38
18
|
version: '0'
|
39
19
|
source:
|
40
20
|
type: stdlib
|
41
|
-
- name:
|
21
|
+
- name: json
|
42
22
|
version: '0'
|
43
23
|
source:
|
44
24
|
type: stdlib
|
45
|
-
- name:
|
46
|
-
version: 2.2.2
|
47
|
-
source:
|
48
|
-
type: git
|
49
|
-
name: ruby/gem_rbs_collection
|
50
|
-
revision: 51880bed87fbc3dc8076fedb5cf798be05148220
|
51
|
-
remote: https://github.com/ruby/gem_rbs_collection.git
|
52
|
-
repo_dir: gems
|
53
|
-
- name: json
|
25
|
+
- name: optparse
|
54
26
|
version: '0'
|
55
27
|
source:
|
56
28
|
type: stdlib
|
57
|
-
- name:
|
29
|
+
- name: rubygems
|
58
30
|
version: '0'
|
59
31
|
source:
|
60
32
|
type: stdlib
|
61
|
-
- name:
|
33
|
+
- name: tsort
|
62
34
|
version: '0'
|
63
35
|
source:
|
64
36
|
type: stdlib
|
@@ -67,7 +39,7 @@ gems:
|
|
67
39
|
source:
|
68
40
|
type: git
|
69
41
|
name: ruby/gem_rbs_collection
|
70
|
-
revision:
|
42
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
71
43
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
72
44
|
repo_dir: gems
|
73
45
|
- name: actionview
|
@@ -75,7 +47,7 @@ gems:
|
|
75
47
|
source:
|
76
48
|
type: git
|
77
49
|
name: ruby/gem_rbs_collection
|
78
|
-
revision:
|
50
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
79
51
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
80
52
|
repo_dir: gems
|
81
53
|
- name: activejob
|
@@ -83,7 +55,7 @@ gems:
|
|
83
55
|
source:
|
84
56
|
type: git
|
85
57
|
name: ruby/gem_rbs_collection
|
86
|
-
revision:
|
58
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
87
59
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
88
60
|
repo_dir: gems
|
89
61
|
- name: activemodel
|
@@ -91,15 +63,23 @@ gems:
|
|
91
63
|
source:
|
92
64
|
type: git
|
93
65
|
name: ruby/gem_rbs_collection
|
94
|
-
revision:
|
66
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
95
67
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
96
68
|
repo_dir: gems
|
97
69
|
- name: activerecord
|
98
|
-
version: '6.
|
70
|
+
version: '6.1'
|
71
|
+
source:
|
72
|
+
type: git
|
73
|
+
name: ruby/gem_rbs_collection
|
74
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
75
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
76
|
+
repo_dir: gems
|
77
|
+
- name: activestorage
|
78
|
+
version: '6.1'
|
99
79
|
source:
|
100
80
|
type: git
|
101
81
|
name: ruby/gem_rbs_collection
|
102
|
-
revision:
|
82
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
103
83
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
104
84
|
repo_dir: gems
|
105
85
|
- name: activesupport
|
@@ -107,7 +87,7 @@ gems:
|
|
107
87
|
source:
|
108
88
|
type: git
|
109
89
|
name: ruby/gem_rbs_collection
|
110
|
-
revision:
|
90
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
111
91
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
112
92
|
repo_dir: gems
|
113
93
|
- name: parallel
|
@@ -115,7 +95,15 @@ gems:
|
|
115
95
|
source:
|
116
96
|
type: git
|
117
97
|
name: ruby/gem_rbs_collection
|
118
|
-
revision:
|
98
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
99
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
100
|
+
repo_dir: gems
|
101
|
+
- name: rack
|
102
|
+
version: 2.2.2
|
103
|
+
source:
|
104
|
+
type: git
|
105
|
+
name: ruby/gem_rbs_collection
|
106
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
119
107
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
120
108
|
repo_dir: gems
|
121
109
|
- name: railties
|
@@ -123,10 +111,34 @@ gems:
|
|
123
111
|
source:
|
124
112
|
type: git
|
125
113
|
name: ruby/gem_rbs_collection
|
126
|
-
revision:
|
114
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
127
115
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
128
116
|
repo_dir: gems
|
129
117
|
- name: rbs
|
130
|
-
version:
|
118
|
+
version: 2.2.2
|
131
119
|
source:
|
132
120
|
type: rubygems
|
121
|
+
- name: monitor
|
122
|
+
version: '0'
|
123
|
+
source:
|
124
|
+
type: stdlib
|
125
|
+
- name: tempfile
|
126
|
+
version: '0'
|
127
|
+
source:
|
128
|
+
type: stdlib
|
129
|
+
- name: date
|
130
|
+
version: '0'
|
131
|
+
source:
|
132
|
+
type: stdlib
|
133
|
+
- name: singleton
|
134
|
+
version: '0'
|
135
|
+
source:
|
136
|
+
type: stdlib
|
137
|
+
- name: mutex_m
|
138
|
+
version: '0'
|
139
|
+
source:
|
140
|
+
type: stdlib
|
141
|
+
- name: time
|
142
|
+
version: '0'
|
143
|
+
source:
|
144
|
+
type: stdlib
|
data/rbs_collection.yaml
CHANGED
@@ -9,25 +9,6 @@ sources:
|
|
9
9
|
path: .gem_rbs_collection
|
10
10
|
|
11
11
|
gems:
|
12
|
-
# stdlibs
|
13
|
-
- name: 'pathname'
|
14
|
-
- name: 'logger'
|
15
|
-
- name: 'mutex_m'
|
16
|
-
- name: 'date'
|
17
|
-
- name: 'monitor'
|
18
|
-
- name: 'singleton'
|
19
|
-
- name: 'tsort'
|
20
|
-
- name: 'time'
|
21
|
-
- name: 'set'
|
22
|
-
|
23
|
-
# gems
|
24
|
-
- name: 'rack'
|
25
|
-
|
26
|
-
# RBS gem dependencies
|
27
|
-
- name: 'json'
|
28
|
-
- name: 'strscan'
|
29
|
-
- name: 'optparse'
|
30
|
-
|
31
12
|
# Ignores - Gemfile.lock contains them but their RBSs are unnecessary
|
32
13
|
- name: steep
|
33
14
|
ignore: true
|
@@ -43,3 +24,13 @@ gems:
|
|
43
24
|
# ignore RBS Rails itself
|
44
25
|
- name: rbs_rails
|
45
26
|
ignore: true
|
27
|
+
|
28
|
+
# They'are necessary to load RBS gem.
|
29
|
+
# See https://github.com/ruby/rbs/pull/921
|
30
|
+
- name: logger
|
31
|
+
- name: set
|
32
|
+
- name: pathname
|
33
|
+
- name: json
|
34
|
+
- name: optparse
|
35
|
+
- name: rubygems
|
36
|
+
- name: tsort
|
File without changes
|
File without changes
|
@@ -5,6 +5,7 @@ end
|
|
5
5
|
|
6
6
|
class RbsRails::ActiveRecord::Generator
|
7
7
|
@parse_model_file: nil | Parser::AST::Node
|
8
|
+
@dependencies: Array[String]
|
8
9
|
|
9
10
|
def initialize: (singleton(ActiveRecord::Base) klass, dependencies: Array[String]) -> untyped
|
10
11
|
|
@@ -32,12 +33,16 @@ class RbsRails::ActiveRecord::Generator
|
|
32
33
|
|
33
34
|
def belongs_to: () -> String
|
34
35
|
|
36
|
+
def generated_association_methods: () -> String
|
37
|
+
|
35
38
|
def delegated_type_scope: (singleton: bool) -> String
|
36
39
|
|
37
40
|
def delegated_type_instance: () -> String
|
38
41
|
|
39
42
|
def delegated_type_definitions: () -> Array[{ role: Symbol, types: Array[String] }]?
|
40
43
|
|
44
|
+
def has_secure_password: () -> String?
|
45
|
+
|
41
46
|
def enum_instance_methods: () -> String
|
42
47
|
|
43
48
|
def enum_scope_methods: (singleton: untyped `singleton`) -> String
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbs_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masataka Pocke Kuwabara
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -50,6 +50,7 @@ files:
|
|
50
50
|
- ".gitignore"
|
51
51
|
- ".gitmodules"
|
52
52
|
- CHANGELOG.md
|
53
|
+
- DESIGN.md
|
53
54
|
- Gemfile
|
54
55
|
- Gemfile.lock
|
55
56
|
- LICENSE
|
@@ -62,6 +63,7 @@ files:
|
|
62
63
|
- bin/rbs-prototype-rb.rb
|
63
64
|
- bin/setup
|
64
65
|
- bin/to-ascii.rb
|
66
|
+
- lib/generators/rbs_rails/install_generator.rb
|
65
67
|
- lib/rbs_rails.rb
|
66
68
|
- lib/rbs_rails/active_record.rb
|
67
69
|
- lib/rbs_rails/dependency_builder.rb
|
@@ -72,8 +74,10 @@ files:
|
|
72
74
|
- rbs_collection.lock.yaml
|
73
75
|
- rbs_collection.yaml
|
74
76
|
- rbs_rails.gemspec
|
75
|
-
- sig/activerecord.rbs
|
76
|
-
- sig/fileutils.rbs
|
77
|
+
- sig/_internal/activerecord.rbs
|
78
|
+
- sig/_internal/fileutils.rbs
|
79
|
+
- sig/_internal/thor.rbs
|
80
|
+
- sig/install_generator.rbs
|
77
81
|
- sig/parser.rbs
|
78
82
|
- sig/rake.rbs
|
79
83
|
- sig/rbs_rails.rbs
|
@@ -105,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
109
|
- !ruby/object:Gem::Version
|
106
110
|
version: '0'
|
107
111
|
requirements: []
|
108
|
-
rubygems_version: 3.
|
112
|
+
rubygems_version: 3.4.0.dev
|
109
113
|
signing_key:
|
110
114
|
specification_version: 4
|
111
115
|
summary: A RBS files generator for Rails application
|