sorbet-rails 0.6.3 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitattributes +1 -2
- data/.gitignore +2 -1
- data/.travis.yml +3 -1
- data/README.md +54 -7
- data/Rakefile +3 -3
- data/lib/bundled_rbi/customizabel_rbi_formatter.rbi +29 -0
- data/lib/bundled_rbi/pluck_to_tstruct.rbi +2 -1
- data/lib/bundled_rbi/typed_enum.rbi +7 -0
- data/lib/sorbet-rails.rb +1 -3
- data/lib/sorbet-rails/active_record_rbi_formatter.rb +8 -2
- data/lib/sorbet-rails/config.rb +11 -0
- data/lib/sorbet-rails/deprecation.rb +1 -0
- data/lib/sorbet-rails/gem_plugins/active_flag_plugin.rb +0 -1
- data/lib/sorbet-rails/gem_plugins/kaminari_plugin.rb +8 -0
- data/lib/sorbet-rails/gem_plugins/paperclip_plugin.rb +0 -1
- data/lib/sorbet-rails/job_rbi_formatter.rb +73 -62
- data/lib/sorbet-rails/mailer_rbi_formatter.rb +40 -27
- data/lib/sorbet-rails/model_column_utils.rb +129 -0
- data/lib/sorbet-rails/model_plugins/active_record_assoc.rb +37 -3
- data/lib/sorbet-rails/model_plugins/active_record_attribute.rb +0 -103
- data/lib/sorbet-rails/model_plugins/active_record_enum.rb +0 -1
- data/lib/sorbet-rails/model_plugins/active_record_named_scope.rb +15 -6
- data/lib/sorbet-rails/model_plugins/active_record_querying.rb +34 -3
- data/lib/sorbet-rails/model_plugins/active_storage_methods.rb +1 -1
- data/lib/sorbet-rails/model_plugins/base.rb +0 -9
- data/lib/sorbet-rails/model_rbi_formatter.rb +4 -8
- data/lib/sorbet-rails/model_utils.rb +73 -32
- data/lib/sorbet-rails/rails_mixins/generated_url_helpers.rb +2 -3
- data/lib/sorbet-rails/rails_mixins/pluck_to_tstruct.rb +17 -7
- data/lib/sorbet-rails/railtie.rb +0 -2
- data/lib/sorbet-rails/sorbet_utils.rb +152 -150
- data/lib/sorbet-rails/tasks/rails_rbi.rake +18 -26
- data/sorbet-rails.gemspec +1 -1
- data/spec/generators/rails-template.rb +3 -6
- data/spec/generators/sorbet_test_cases.rb +66 -88
- data/spec/job_rbi_formatter_spec.rb +1 -1
- data/spec/pluck_to_tstruct_spec.rb +74 -1
- data/spec/rails_helper.rb +2 -2
- data/spec/rake_rails_rbi_jobs_spec.rb +20 -0
- data/spec/rake_rails_rbi_mailers_spec.rb +21 -0
- data/spec/support/v5.0/Gemfile +1 -1
- data/spec/support/v5.0/Gemfile.lock +9 -9
- data/spec/support/v5.0/app/models/spell_book.rb +2 -0
- data/spec/support/v5.0/app/models/wizard.rb +1 -1
- data/spec/support/v5.0/sorbet_test_cases.rb +66 -88
- data/spec/support/v5.1/Gemfile.lock +7 -7
- data/spec/support/v5.1/app/models/spell_book.rb +2 -0
- data/spec/support/v5.1/app/models/wizard.rb +1 -1
- data/spec/support/v5.1/sorbet_test_cases.rb +66 -88
- data/spec/support/v5.2/Gemfile +1 -1
- data/spec/support/v5.2/Gemfile.lock +9 -9
- data/spec/support/v5.2/app/models/spell_book.rb +2 -0
- data/spec/support/v5.2/app/models/wizard.rb +1 -1
- data/spec/support/v5.2/sorbet_test_cases.rb +66 -88
- data/spec/support/v6.0/.gitignore +6 -0
- data/spec/support/v6.0/Gemfile +3 -3
- data/spec/support/v6.0/Gemfile.lock +77 -76
- data/spec/support/v6.0/app/models/spell_book.rb +2 -0
- data/spec/support/v6.0/app/models/wizard.rb +1 -1
- data/spec/support/v6.0/bin/bundle +22 -13
- data/spec/support/v6.0/config/environments/test.rb +1 -1
- data/spec/support/v6.0/sorbet_test_cases.rb +66 -88
- data/spec/support/v6.0/tmp/pids/.keep +0 -0
- data/spec/test_data/v5.0/expected_active_record_base.rbi +2 -2
- data/spec/test_data/v5.0/expected_active_record_relation.rbi +2 -2
- data/spec/test_data/v5.0/expected_custom_application_job.rbi +21 -0
- data/spec/test_data/v5.0/expected_custom_application_mailer.rbi +6 -0
- data/spec/test_data/v5.0/expected_custom_award_house_point_hourglasses.rbi +21 -0
- data/spec/test_data/v5.0/expected_custom_daily_prophet_mailer.rbi +8 -0
- data/spec/test_data/v5.0/expected_custom_hogwarts_acceptance_mailer.rbi +21 -0
- data/spec/test_data/v5.0/expected_headmaster.rbi +60 -190
- data/spec/test_data/v5.0/expected_internal_metadata.rbi +42 -188
- data/spec/test_data/v5.0/expected_potion.rbi +51 -188
- data/spec/test_data/v5.0/expected_robe.rbi +51 -190
- data/spec/test_data/v5.0/expected_schema_migration.rbi +42 -188
- data/spec/test_data/v5.0/expected_school.rbi +51 -190
- data/spec/test_data/v5.0/expected_spell.rbi +42 -190
- data/spec/test_data/v5.0/expected_spell/habtm_spell_books.rbi +60 -190
- data/spec/test_data/v5.0/expected_spell_book.rbi +86 -215
- data/spec/test_data/v5.0/expected_spell_book/habtm_spells.rbi +60 -190
- data/spec/test_data/v5.0/expected_squib.rbi +131 -263
- data/spec/test_data/v5.0/expected_subject.rbi +42 -190
- data/spec/test_data/v5.0/expected_subject/habtm_wizards.rbi +60 -190
- data/spec/test_data/v5.0/expected_wand.rbi +84 -225
- data/spec/test_data/v5.0/expected_wizard.rbi +131 -263
- data/spec/test_data/v5.0/expected_wizard/habtm_subjects.rbi +60 -190
- data/spec/test_data/v5.0/expected_wizard_wo_spellbook.rbi +131 -263
- data/spec/test_data/v5.1/expected_active_record_base.rbi +2 -2
- data/spec/test_data/v5.1/expected_active_record_relation.rbi +2 -2
- data/spec/test_data/v5.1/expected_custom_application_job.rbi +21 -0
- data/spec/test_data/v5.1/expected_custom_application_mailer.rbi +6 -0
- data/spec/test_data/v5.1/expected_custom_award_house_point_hourglasses.rbi +21 -0
- data/spec/test_data/v5.1/expected_custom_daily_prophet_mailer.rbi +8 -0
- data/spec/test_data/v5.1/expected_custom_hogwarts_acceptance_mailer.rbi +21 -0
- data/spec/test_data/v5.1/expected_headmaster.rbi +60 -196
- data/spec/test_data/v5.1/expected_internal_metadata.rbi +42 -194
- data/spec/test_data/v5.1/expected_potion.rbi +51 -194
- data/spec/test_data/v5.1/expected_robe.rbi +51 -196
- data/spec/test_data/v5.1/expected_schema_migration.rbi +42 -194
- data/spec/test_data/v5.1/expected_school.rbi +51 -196
- data/spec/test_data/v5.1/expected_spell.rbi +42 -196
- data/spec/test_data/v5.1/expected_spell/habtm_spell_books.rbi +60 -196
- data/spec/test_data/v5.1/expected_spell_book.rbi +86 -221
- data/spec/test_data/v5.1/expected_spell_book/habtm_spells.rbi +60 -196
- data/spec/test_data/v5.1/expected_squib.rbi +132 -270
- data/spec/test_data/v5.1/expected_subject.rbi +42 -196
- data/spec/test_data/v5.1/expected_subject/habtm_wizards.rbi +60 -196
- data/spec/test_data/v5.1/expected_wand.rbi +84 -231
- data/spec/test_data/v5.1/expected_wizard.rbi +132 -270
- data/spec/test_data/v5.1/expected_wizard/habtm_subjects.rbi +60 -196
- data/spec/test_data/v5.1/expected_wizard_wo_spellbook.rbi +132 -270
- data/spec/test_data/v5.2/expected_active_record_base.rbi +2 -2
- data/spec/test_data/v5.2/expected_active_record_relation.rbi +2 -2
- data/spec/test_data/v5.2/expected_attachment.rbi +60 -194
- data/spec/test_data/v5.2/expected_blob.rbi +80 -214
- data/spec/test_data/v5.2/expected_custom_application_job.rbi +21 -0
- data/spec/test_data/v5.2/expected_custom_application_mailer.rbi +6 -0
- data/spec/test_data/v5.2/expected_custom_award_house_point_hourglasses.rbi +21 -0
- data/spec/test_data/v5.2/expected_custom_daily_prophet_mailer.rbi +8 -0
- data/spec/test_data/v5.2/expected_custom_hogwarts_acceptance_mailer.rbi +21 -0
- data/spec/test_data/v5.2/expected_headmaster.rbi +60 -196
- data/spec/test_data/v5.2/expected_internal_metadata.rbi +42 -194
- data/spec/test_data/v5.2/expected_potion.rbi +51 -194
- data/spec/test_data/v5.2/expected_robe.rbi +51 -196
- data/spec/test_data/v5.2/expected_schema_migration.rbi +42 -194
- data/spec/test_data/v5.2/expected_school.rbi +51 -196
- data/spec/test_data/v5.2/expected_spell.rbi +42 -196
- data/spec/test_data/v5.2/expected_spell/habtm_spell_books.rbi +60 -196
- data/spec/test_data/v5.2/expected_spell_book.rbi +86 -221
- data/spec/test_data/v5.2/expected_spell_book/habtm_spells.rbi +60 -196
- data/spec/test_data/v5.2/expected_squib.rbi +156 -276
- data/spec/test_data/v5.2/expected_subject.rbi +42 -196
- data/spec/test_data/v5.2/expected_subject/habtm_wizards.rbi +60 -196
- data/spec/test_data/v5.2/expected_wand.rbi +84 -231
- data/spec/test_data/v5.2/expected_wizard.rbi +156 -276
- data/spec/test_data/v5.2/expected_wizard/habtm_subjects.rbi +60 -196
- data/spec/test_data/v5.2/expected_wizard_wo_spellbook.rbi +156 -276
- data/spec/test_data/v6.0/expected_active_record_base.rbi +2 -2
- data/spec/test_data/v6.0/expected_active_record_relation.rbi +10 -10
- data/spec/test_data/v6.0/expected_attachment.rbi +60 -218
- data/spec/test_data/v6.0/expected_blob.rbi +80 -238
- data/spec/test_data/v6.0/expected_custom_application_job.rbi +21 -0
- data/spec/test_data/v6.0/expected_custom_application_mailer.rbi +6 -0
- data/spec/test_data/v6.0/expected_custom_award_house_point_hourglasses.rbi +21 -0
- data/spec/test_data/v6.0/expected_custom_daily_prophet_mailer.rbi +8 -0
- data/spec/test_data/v6.0/expected_custom_hogwarts_acceptance_mailer.rbi +21 -0
- data/spec/test_data/v6.0/expected_headmaster.rbi +60 -220
- data/spec/test_data/v6.0/expected_internal_metadata.rbi +42 -218
- data/spec/test_data/v6.0/expected_potion.rbi +51 -218
- data/spec/test_data/v6.0/expected_robe.rbi +51 -220
- data/spec/test_data/v6.0/expected_routes.rbi +14 -7
- data/spec/test_data/v6.0/expected_schema_migration.rbi +42 -218
- data/spec/test_data/v6.0/expected_school.rbi +51 -220
- data/spec/test_data/v6.0/expected_spell.rbi +42 -220
- data/spec/test_data/v6.0/expected_spell/habtm_spell_books.rbi +60 -220
- data/spec/test_data/v6.0/expected_spell_book.rbi +98 -257
- data/spec/test_data/v6.0/expected_spell_book/habtm_spells.rbi +60 -220
- data/spec/test_data/v6.0/expected_squib.rbi +182 -326
- data/spec/test_data/v6.0/expected_subject.rbi +42 -220
- data/spec/test_data/v6.0/expected_subject/habtm_wizards.rbi +60 -220
- data/spec/test_data/v6.0/expected_wand.rbi +100 -271
- data/spec/test_data/v6.0/expected_wizard.rbi +182 -326
- data/spec/test_data/v6.0/expected_wizard/habtm_subjects.rbi +60 -220
- data/spec/test_data/v6.0/expected_wizard_wo_spellbook.rbi +182 -326
- metadata +46 -11
- data/lib/bundled_rbi/parameters.rbi +0 -28
- data/lib/sorbet-rails/custom_types/boolean_string.rb +0 -42
- data/lib/sorbet-rails/custom_types/integer_string.rb +0 -45
- data/lib/sorbet-rails/rails_mixins/custom_params_methods.rb +0 -57
- data/spec/boolean_string_spec.rb +0 -59
- data/spec/custom_params_methods_spec.rb +0 -138
- data/spec/integer_string_spec.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc9807ef098eeb05a61378ffe82fa56864f5d0543ba20031153bd86ac604a356
|
4
|
+
data.tar.gz: e9fa8ed4c3390685d352486d3bde21b4301ce3f9d1b600b79198aba797bee560
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0374a3b24474fbf04051edfdf372b11132dcd4293d9cca7a1a692e15e63aad07a55d5f72c10830bb96799aa31d175ffd20584d81c58bbee2b4c293c27ddcc33f
|
7
|
+
data.tar.gz: a8826daddfef144295b9df4438e669e7cf42d494666d47073f7868b6481c329b9e8058cc2d308598c0d34035065d6b2f1c7611113a85c5a0b8912f91af363d3c
|
data/.gitattributes
CHANGED
data/.gitignore
CHANGED
@@ -79,6 +79,7 @@ build-iPhoneSimulator/
|
|
79
79
|
/spec/support/**/config/credentials.yml.enc
|
80
80
|
|
81
81
|
# Ignore sorbet generated files
|
82
|
+
/sorbet/rbi/hidden-definitions/
|
82
83
|
/spec/support/**/sorbet/*
|
83
84
|
/spec/support/**/sorbet/**/*
|
84
85
|
|
@@ -93,7 +94,7 @@ build-iPhoneSimulator/
|
|
93
94
|
*.swl
|
94
95
|
*.swk
|
95
96
|
|
96
|
-
|
97
|
+
sorbet/rbi/hidden-definitions/errors.txt
|
97
98
|
.vscode
|
98
99
|
|
99
100
|
.rake_tasks~
|
data/.travis.yml
CHANGED
@@ -16,7 +16,7 @@ rvm:
|
|
16
16
|
matrix:
|
17
17
|
include:
|
18
18
|
- rvm: 2.5
|
19
|
-
env: RAILS_VERSION=5.2 SORBET_VERSION=0.5.
|
19
|
+
env: RAILS_VERSION=5.2 SORBET_VERSION=0.5.5737
|
20
20
|
exclude:
|
21
21
|
- rvm: 2.3
|
22
22
|
env: RAILS_VERSION=6.0
|
@@ -24,6 +24,8 @@ matrix:
|
|
24
24
|
env: RAILS_VERSION=6.0
|
25
25
|
allow_failures:
|
26
26
|
- rvm: ruby-head
|
27
|
+
- rvm: 2.7
|
28
|
+
env: RAILS_VERSION=6.0
|
27
29
|
before_install:
|
28
30
|
- gem install bundler -v 2.0.1 --no-doc
|
29
31
|
- gem install bundler -v 1.17.3 --no-doc
|
data/README.md
CHANGED
@@ -73,7 +73,7 @@ It is possible to add custom RBI generation logic for your custom module or gems
|
|
73
73
|
We also add following methods to make type-checking more easily:
|
74
74
|
- [`find_n`, `first_n`, `last_n`](https://github.com/chanzuckerberg/sorbet-rails#find-first-and-last)
|
75
75
|
- [`pluck_to_tstruct`](#pluck_to_tstruct-instead-of-pluck)
|
76
|
-
- [`typed_enum`](#
|
76
|
+
- [`typed_enum`](#typed_enum-instead-of-enum)
|
77
77
|
- [`Model::RelationType`](#relationtype-alias)
|
78
78
|
|
79
79
|
#### `pluck_to_tstruct` instead of `pluck`
|
@@ -94,9 +94,31 @@ Wizard.pluck_to_tstruct(TA[WizardStruct].new) # T::Array[WizardStruct]
|
|
94
94
|
Wizard.all.pluck_to_tstruct(TA[WizardStruct].new) # T::Array[WizardStruct]
|
95
95
|
```
|
96
96
|
|
97
|
+
You can also pass a keyword argument called `associations` that represents a mapping of a `T::Struct`'s keys to an associated table's columns.
|
98
|
+
```ruby
|
99
|
+
# -- API
|
100
|
+
Arel.pluck_to_tstruct(TA[ <TStructSubclass> ].new, associations: < Hash<Symbol, String> >)
|
101
|
+
|
102
|
+
# -- example
|
103
|
+
class WizardWithWandStruct < T::Struct
|
104
|
+
const :name, String
|
105
|
+
const :house, T.nilable(String)
|
106
|
+
const :wand_wood_type, String
|
107
|
+
end
|
108
|
+
|
109
|
+
Wizard.joins(:wand).pluck_to_tstruct(
|
110
|
+
TA[WizardWithWandStruct].new,
|
111
|
+
associations: { wand_wood_type: "wands.wood_type" }
|
112
|
+
)
|
113
|
+
Wizard.all.joins(:wand).pluck_to_tstruct(
|
114
|
+
TA[WizardWithWandStruct].new,
|
115
|
+
associations: { wand_wood_type: "wands.wood_type" }
|
116
|
+
)
|
117
|
+
````
|
118
|
+
|
97
119
|
This method is based on [pluck_to_hash](https://github.com/girishso/pluck_to_hash) gem.
|
98
120
|
|
99
|
-
####
|
121
|
+
#### `typed_enum` instead of `enum`
|
100
122
|
|
101
123
|
If you use [Rails `enum`](https://guides.rubyonrails.org/active_record_querying.html#enums), `sorbet-rails` will generate a corresponding `T::Enum`. It will also include getters, setters, and scope methods in the rbi file it generates.
|
102
124
|
|
@@ -203,7 +225,7 @@ end
|
|
203
225
|
If it fails to coerce the params into the right type, an `ActionController::BadRequest` exception will be raised with the coercion context for debugging.
|
204
226
|
|
205
227
|
Note: The API `TypedParams[...].new.extract!` may seem verbose, but necessary to support this feature. Ideally, the API can be simply `TypedParams.extract!(...)`. However, `sorbet` [doesn't support](http://github.com/sorbet/sorbet/issues/62) defining a method that accept a type and return an instance of the type. If this feature is supported by `sorbet` in the future, it will be easy to codemod to be `TypedParams.extract(...)!` part from your code.
|
206
|
-
Note: [`require_typed` and `fetch_typed`](https://github.com/chanzuckerberg/sorbet-rails/blob/v0.5.9.1/README.md) are deprecated in favor of `TypedParams`.
|
228
|
+
Note: [`require_typed` and `fetch_typed`](https://github.com/chanzuckerberg/sorbet-rails/blob/v0.5.9.1/README.md) are deprecated in favor of `TypedParams`. They will be removed in v0.7.
|
207
229
|
|
208
230
|
### Routes
|
209
231
|
|
@@ -412,11 +434,13 @@ If you run into the following issue when running rspec, it's likely because you'
|
|
412
434
|
if you're really stuck.
|
413
435
|
```
|
414
436
|
|
415
|
-
## Extending
|
437
|
+
## Extending RBI Generation logic
|
438
|
+
|
439
|
+
### Extending Model Generation Task with Custom Plugins
|
416
440
|
|
417
441
|
`sorbet-rails` support a customizable plugin system that you can use to generate additional RBI for each model. This will be useful to generate RBI for methods dynamically added by gems or private concerns. If you write plugins for public gems, please feel free to contribute it to this repo.
|
418
442
|
|
419
|
-
|
443
|
+
#### Defining a Custom `ModelPlugin`
|
420
444
|
|
421
445
|
A custom plugin should be a subclass of `SorbetRails::ModelPlugins::Base`. Each plugin would implement a `generate(root)` method that generate additional rbi for the model.
|
422
446
|
|
@@ -465,14 +489,14 @@ It is also recommended to check if the generated methods are detected by `sorbet
|
|
465
489
|
|
466
490
|
Check out the [plugins](https://github.com/chanzuckerberg/sorbet-rails/tree/master/lib/sorbet-rails/model_plugins) written for `sorbet-rails`'s own model RBI generation logic for examples.
|
467
491
|
|
468
|
-
|
492
|
+
#### Registering new plugins
|
469
493
|
You can register your plugins in an initializer:
|
470
494
|
```ruby
|
471
495
|
# -- config/initializers/sorbet_rails.rb
|
472
496
|
SorbetRails::ModelRbiFormatter.register_plugin(MyCustomPlugin)
|
473
497
|
```
|
474
498
|
|
475
|
-
|
499
|
+
#### Enabling built-in plugins
|
476
500
|
|
477
501
|
sorbet-rails comes with a handful of gem plugins that can be enabled in an initializer. You can pass enabled gem plugins to `config.enabled_gem_plugins`, like so:
|
478
502
|
|
@@ -508,6 +532,29 @@ You can also configure the core model plugins if needed. The default plugins are
|
|
508
532
|
[active_flag]: https://github.com/kenn/active_flag
|
509
533
|
[Paperclip]: https://github.com/thoughtbot/paperclip
|
510
534
|
|
535
|
+
### Customize Generation Class
|
536
|
+
|
537
|
+
For mailer and job rbi generation, you can customize the logic by
|
538
|
+
setting the generation class in the config:
|
539
|
+
|
540
|
+
```ruby
|
541
|
+
SorbetRails.configure do |config|
|
542
|
+
config.job_generator_class = CustomJobRbiGenerator
|
543
|
+
config.mailer_generator_class = CustomMailerRbiGenerator
|
544
|
+
end
|
545
|
+
```
|
546
|
+
|
547
|
+
The custom generator can subclass the [provided generators](lib/bundled_rbi/customizabel_rbi_formatter.rbi) and override the populate_rbi method. For example:
|
548
|
+
|
549
|
+
```ruby
|
550
|
+
class CustomJobRbiGenerator < SorbetRails::JobRbiFormatter
|
551
|
+
def populate_rbi
|
552
|
+
rbi_generator.root.add_comment("== Custom Generator ==")
|
553
|
+
super
|
554
|
+
end
|
555
|
+
end
|
556
|
+
```
|
557
|
+
|
511
558
|
## Contributing
|
512
559
|
|
513
560
|
Contributions and ideas are welcome! Please see [our contributing guide](CONTRIBUTING.md) and don't hesitate to open an issue or send a pull request to improve the functionality of this gem.
|
data/Rakefile
CHANGED
@@ -20,9 +20,9 @@ namespace :update_spec do
|
|
20
20
|
task :v6_0 do |t, args|
|
21
21
|
Bundler.with_clean_env do
|
22
22
|
FileUtils.rm_rf 'spec/support/v6.0' if File.directory?('spec/support/v6.0')
|
23
|
-
system("gem install rails -v 6.0.
|
24
|
-
system("rails _6.0.
|
25
|
-
system("RAILS_VERSION='6.0' rails _6.0.
|
23
|
+
system("gem install rails -v 6.0.3")
|
24
|
+
system("rails _6.0.3_ -v")
|
25
|
+
system("RAILS_VERSION='6.0' rails _6.0.3_ new --template spec/generators/rails-template.rb spec/support/v6.0 --skip-javascript --skip-action-cable --skip-test --skip-sprockets --skip-spring --skip-bootsnap --skip-listen")
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# typed: strong
|
2
|
+
module SorbetRails
|
3
|
+
class MailerRbiFormatter
|
4
|
+
extend T::Sig
|
5
|
+
Parameter = ::Parlour::RbiGenerator::Parameter
|
6
|
+
|
7
|
+
sig { returns(T.class_of(ActionMailer::Base)) }
|
8
|
+
attr_reader :mailer_class
|
9
|
+
|
10
|
+
sig { returns(Parlour::RbiGenerator) }
|
11
|
+
def rbi_generator; end
|
12
|
+
|
13
|
+
sig { void }
|
14
|
+
def populate_rbi; end
|
15
|
+
end
|
16
|
+
|
17
|
+
class JobRbiFormatter
|
18
|
+
Parameter = ::Parlour::RbiGenerator::Parameter
|
19
|
+
|
20
|
+
sig { returns(Parlour::RbiGenerator) }
|
21
|
+
attr_reader :rbi_generator
|
22
|
+
|
23
|
+
sig { returns(T.class_of(ActiveJob::Base)) }
|
24
|
+
attr_reader :job_class
|
25
|
+
|
26
|
+
sig { void }
|
27
|
+
def populate_rbi; end
|
28
|
+
end
|
29
|
+
end
|
@@ -6,10 +6,11 @@ module SorbetRails::PluckToTStruct
|
|
6
6
|
type_parameters(:U).
|
7
7
|
params(
|
8
8
|
ta_struct: ITypeAssert[T.type_parameter(:U)],
|
9
|
+
associations: T::Hash[Symbol, String],
|
9
10
|
).
|
10
11
|
returns(T::Array[T.type_parameter(:U)])
|
11
12
|
}
|
12
|
-
def pluck_to_tstruct(ta_struct,
|
13
|
+
def pluck_to_tstruct(ta_struct, associations: {}); end
|
13
14
|
end
|
14
15
|
|
15
16
|
class ActiveRecord::Base
|
data/lib/sorbet-rails.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
module SorbetRails
|
3
3
|
if defined?(Rails)
|
4
4
|
require 'sorbet-rails/railtie'
|
5
5
|
require 'sorbet-rails/model_rbi_formatter'
|
6
6
|
require 'sorbet-rails/type_assert/type_assert'
|
7
|
-
require 'sorbet-rails/custom_types/integer_string'
|
8
|
-
require 'sorbet-rails/custom_types/boolean_string'
|
9
7
|
require 'sorbet-rails/typed_params'
|
10
8
|
end
|
11
9
|
end
|
@@ -85,11 +85,18 @@ class SorbetRails::ActiveRecordRbiFormatter
|
|
85
85
|
# parameters than the ones defined by `create_elem_specific_query_methods` so
|
86
86
|
# we need to match the signatures in that conflicting rbi.
|
87
87
|
build_methods = %w(new build create create!)
|
88
|
+
# This needs to match the generated method signature in activerecord.rbi and
|
89
|
+
# in Rails 5.0 and 5.1 the param is a splat.
|
90
|
+
if Rails.version =~ /^5\./
|
91
|
+
build_param = Parameter.new("*args", type: "T.untyped")
|
92
|
+
else
|
93
|
+
build_param = Parameter.new("attributes", type: "T.untyped", default: 'nil')
|
94
|
+
end
|
88
95
|
build_methods.each do |build_method|
|
89
96
|
class_rbi.create_method(
|
90
97
|
build_method,
|
91
98
|
parameters: [
|
92
|
-
|
99
|
+
build_param,
|
93
100
|
Parameter.new(
|
94
101
|
"&block",
|
95
102
|
type: "T.nilable(T.proc.params(object: Elem).void)",
|
@@ -264,7 +271,6 @@ class SorbetRails::ActiveRecordRbiFormatter
|
|
264
271
|
],
|
265
272
|
return_type: "T::Enumerator[#{inner_type}]",
|
266
273
|
class_method: class_method,
|
267
|
-
override: true,
|
268
274
|
)
|
269
275
|
end
|
270
276
|
end
|
data/lib/sorbet-rails/config.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
# typed: true
|
2
|
+
require("sorbet-rails/mailer_rbi_formatter")
|
3
|
+
require("sorbet-rails/job_rbi_formatter")
|
4
|
+
|
2
5
|
module SorbetRails
|
3
6
|
class << self
|
4
7
|
extend T::Sig
|
@@ -37,6 +40,12 @@ module SorbetRails
|
|
37
40
|
sig { returns(T::Array[String]) }
|
38
41
|
attr_accessor :extra_helper_includes
|
39
42
|
|
43
|
+
sig { returns(T.class_of(SorbetRails::JobRbiFormatter))}
|
44
|
+
attr_accessor :job_generator_class
|
45
|
+
|
46
|
+
sig { returns(T.class_of(SorbetRails::MailerRbiFormatter))}
|
47
|
+
attr_accessor :mailer_generator_class
|
48
|
+
|
40
49
|
sig { void }
|
41
50
|
def initialize
|
42
51
|
@enabled_gem_plugins = []
|
@@ -52,6 +61,8 @@ module SorbetRails
|
|
52
61
|
]
|
53
62
|
@enabled_model_plugins << :active_storage_methods if defined?(T.unsafe(ActiveStorage))
|
54
63
|
@extra_helper_includes = []
|
64
|
+
@mailer_generator_class = SorbetRails::MailerRbiFormatter
|
65
|
+
@job_generator_class = SorbetRails::JobRbiFormatter
|
55
66
|
end
|
56
67
|
|
57
68
|
sig { returns(T::Array[Symbol]) }
|
@@ -7,7 +7,6 @@ class ActiveFlagPlugin < SorbetRails::ModelPlugins::Base
|
|
7
7
|
|
8
8
|
module_name = self.model_module_name("GeneratedActiveFlagMethods")
|
9
9
|
module_rbi = root.create_module(module_name)
|
10
|
-
module_rbi.create_extend("T::Sig")
|
11
10
|
|
12
11
|
model_class_rbi = root.create_class(self.model_class_name)
|
13
12
|
model_class_rbi.create_include(module_name)
|
@@ -35,5 +35,13 @@ class KaminariPlugin < SorbetRails::ModelPlugins::Base
|
|
35
35
|
Parameter.new('num', type: 'Integer')
|
36
36
|
],
|
37
37
|
)
|
38
|
+
|
39
|
+
# https://github.com/kaminari/kaminari/blob/c5186f5d9b7f23299d115408e62047447fd3189d/kaminari-core/lib/kaminari/models/configuration_methods.rb#L19
|
40
|
+
model_class_rbi = root.create_class(model_class_name)
|
41
|
+
model_class_rbi.create_method(
|
42
|
+
"default_per_page",
|
43
|
+
return_type: "Integer",
|
44
|
+
class_method: true,
|
45
|
+
)
|
38
46
|
end
|
39
47
|
end
|
@@ -8,7 +8,6 @@ class PaperclipPlugin < SorbetRails::ModelPlugins::Base
|
|
8
8
|
|
9
9
|
module_name = self.model_module_name("GeneratedPaperclipMethods")
|
10
10
|
module_rbi = root.create_module(module_name)
|
11
|
-
module_rbi.create_extend("T::Sig")
|
12
11
|
|
13
12
|
model_class_rbi = root.create_class(self.model_class_name)
|
14
13
|
model_class_rbi.create_include(module_name)
|
@@ -2,74 +2,85 @@
|
|
2
2
|
require('parlour')
|
3
3
|
require('sorbet-rails/sorbet_utils.rb')
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
module SorbetRails
|
6
|
+
class JobRbiFormatter
|
7
|
+
extend T::Sig
|
7
8
|
|
8
|
-
|
9
|
+
Parameter = ::Parlour::RbiGenerator::Parameter
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
sig { returns(Parlour::RbiGenerator) }
|
12
|
+
attr_reader :rbi_generator
|
13
|
+
|
14
|
+
sig { returns(T.class_of(ActiveJob::Base)) }
|
15
|
+
attr_reader :job_class
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
sig { params(job_class: T.class_of(ActiveJob::Base)).void }
|
18
|
+
def initialize(job_class)
|
19
|
+
@job_class = T.let(job_class, T.class_of(ActiveJob::Base))
|
20
|
+
@rbi_generator = T.let(Parlour::RbiGenerator.new, Parlour::RbiGenerator)
|
21
|
+
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
sig { void }
|
24
|
+
def populate_rbi
|
25
|
+
@rbi_generator.root.add_comments([
|
26
|
+
'This is an autogenerated file for Rails\' jobs.',
|
27
|
+
'Please rerun bundle exec rake rails_rbi:jobs to regenerate.'
|
28
|
+
])
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
30
|
+
@rbi_generator.root.create_class(@job_class.name) do |job_rbi|
|
31
|
+
method_def = @job_class.instance_method(:perform)
|
32
|
+
parameters = SorbetRails::SorbetUtils.parameters_from_method_def(method_def)
|
33
|
+
job_rbi.create_method(
|
34
|
+
"perform_later",
|
35
|
+
parameters: parameters,
|
36
|
+
class_method: true,
|
37
|
+
)
|
38
|
+
job_rbi.create_method(
|
39
|
+
"perform_now",
|
40
|
+
parameters: parameters,
|
41
|
+
class_method: true,
|
42
|
+
)
|
43
|
+
# Override the signature for "set" so that we can support it
|
44
|
+
# At run-time, this method returns a `ActiveJob::ConfiguredJob` but
|
45
|
+
# we fake the signature to return "T.self_class" so that
|
46
|
+
# sorbet can type-check when `perform_later` is called on it
|
47
|
+
# See: https://guides.rubyonrails.org/active_job_basics.html#enqueue-the-job
|
48
|
+
job_rbi.create_method(
|
49
|
+
"set",
|
50
|
+
# Documentation: https://api.rubyonrails.org/classes/ActiveJob/Core/ClassMethods.html
|
51
|
+
parameters: [
|
52
|
+
Parameter.new(
|
53
|
+
"wait:",
|
54
|
+
type: "T.nilable(ActiveSupport::Duration)",
|
55
|
+
default: "nil",
|
56
|
+
),
|
57
|
+
Parameter.new(
|
58
|
+
"wait_until:",
|
59
|
+
type: "T.nilable(T.any(ActiveSupport::TimeWithZone, Date, Time))",
|
60
|
+
default: "nil",
|
61
|
+
),
|
62
|
+
Parameter.new(
|
63
|
+
"queue:",
|
64
|
+
type: "T.nilable(T.any(String, Symbol))",
|
65
|
+
default: "nil",
|
66
|
+
),
|
67
|
+
Parameter.new(
|
68
|
+
"priority:",
|
69
|
+
type: "T.nilable(Integer)",
|
70
|
+
default: "nil",
|
71
|
+
),
|
72
|
+
],
|
73
|
+
return_type: "T.self_type",
|
74
|
+
class_method: true,
|
75
|
+
)
|
76
|
+
end
|
71
77
|
end
|
72
78
|
|
73
|
-
|
79
|
+
sig { returns(String) }
|
80
|
+
def generate_rbi
|
81
|
+
puts "-- Generate sigs for mailer #{@job_class.name} --"
|
82
|
+
populate_rbi
|
83
|
+
@rbi_generator.rbi
|
84
|
+
end
|
74
85
|
end
|
75
86
|
end
|