From 8f653b36e4529b93868cf6c07d4c359aa734baee Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 1 Sep 2021 11:18:23 +0100 Subject: [PATCH 01/13] Add readme directions on migrating to Tapioca On initially installing Tapioca I had no idea that it needed a migration in order to work from an existing Sorbet installation. This signals that need directly from the Readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 7110e8337..bb4f13ade 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ As yet, no gem exports type information in a consumable format and it would be a When you run `tapioca sync` in a project, `tapioca` loads all the gems that are in your dependency list from the Gemfile into memory. It then performs runtime introspection on the loaded types to understand their structure and generates an appropriate RBI file for each gem with a versioned filename. +## Migrating to Tapioca from an existing Sorbet installation + +The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. + +In order to start using Sorbet you will need to remove these gems redo all of your automatically generated RBI files. [Full instructions on how migrate are in the wiki](https://github.com/Shopify/tapioca/wiki/Migrating-to-Tapioca). + ## Manual gem requires For gems that have a normal default `require` and load all of their constants through such a require, everything works seamlessly. However, for gems that are marked as `require: false` in the Gemfile, or for gems that export optionally loaded types via different requires, where a single require does not load the whole gem code into memory, `tapioca` will not be able to load some of the types into memory and, thus, won't be able to generate complete RBIs for them. For this reason, we need to keep a small external file named `sorbet/tapioca/require.rb` that is executed after all the gems in the Gemfile have been required and before generation of gem RBIs have started. This file is responsible for adding the requires for additional files from gems, which are not covered by the default require. From a042349684702552892f257ea8f35b80410c34d9 Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 1 Sep 2021 15:14:33 +0100 Subject: [PATCH 02/13] Update README.md Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb4f13ade..3bc57b691 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ When you run `tapioca sync` in a project, `tapioca` loads all the gems that are The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. -In order to start using Sorbet you will need to remove these gems redo all of your automatically generated RBI files. [Full instructions on how migrate are in the wiki](https://github.com/Shopify/tapioca/wiki/Migrating-to-Tapioca). +In order to start using Tapioca you will need to remove these gems redo all of your automatically generated RBI files. [Full instructions on how migrate are in the wiki](https://github.com/Shopify/tapioca/wiki/Migrating-to-Tapioca). ## Manual gem requires From b011722b8dceaba96a750fbff756870801e4db05 Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 1 Sep 2021 15:42:54 +0100 Subject: [PATCH 03/13] Moved "migration" details into readme I swapped a little of the info around on the frontpage so that the two types of installation were next to each other, the commands and flags were placed next to each other and there was a little more context to the intro at the start of the page --- README.md | 201 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 142 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 3bc57b691..bb3dc89f7 100644 --- a/README.md +++ b/README.md @@ -6,59 +6,143 @@ Tapioca is a library used to generate RBI (Ruby interface) files for use with [Sorbet](https://sorbet.org). RBI files provide the structure (classes, modules, methods, parameters) of the gem/library to Sorbet to assist with typechecking. +### Why use Tapioca + As yet, no gem exports type information in a consumable format and it would be a huge effort to manually maintain such an interface file for all the gems that your codebase depends on. Thus, there is a need for an automated way to generate the appropriate RBI file for a given gem. The `tapioca` gem, developed at Shopify, is able to do exactly that to almost 99% accuracy. It can generate the definitions for all statically defined types and most of the runtime defined types exported from Ruby gems (non-Ruby gems are not handled yet). When you run `tapioca sync` in a project, `tapioca` loads all the gems that are in your dependency list from the Gemfile into memory. It then performs runtime introspection on the loaded types to understand their structure and generates an appropriate RBI file for each gem with a versioned filename. -## Migrating to Tapioca from an existing Sorbet installation +Tapioca helps simplify your setup too. Gems such as `sorbet-typed`, `sorbet-rails` are ways to provide accurate typing information for DSLs and gems. However, Tapioca aims to provide the complete tooling to generating RBIs for gems and DSLs, and does not require being combined with other gems, such as `sorbet-rails`, which can be removed from your gemfile. -The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. -In order to start using Tapioca you will need to remove these gems redo all of your automatically generated RBI files. [Full instructions on how migrate are in the wiki](https://github.com/Shopify/tapioca/wiki/Migrating-to-Tapioca). +## Installing Tapioca in a project with no existing RBI files (i.e. a fresh Sorbet project) -## Manual gem requires +### 1. Add this line to your application's `Gemfile` -For gems that have a normal default `require` and load all of their constants through such a require, everything works seamlessly. However, for gems that are marked as `require: false` in the Gemfile, or for gems that export optionally loaded types via different requires, where a single require does not load the whole gem code into memory, `tapioca` will not be able to load some of the types into memory and, thus, won't be able to generate complete RBIs for them. For this reason, we need to keep a small external file named `sorbet/tapioca/require.rb` that is executed after all the gems in the Gemfile have been required and before generation of gem RBIs have started. This file is responsible for adding the requires for additional files from gems, which are not covered by the default require. +```ruby +group :development do + gem 'tapioca', require: false +end +``` +and run `bundle install` -For example, suppose you are using the class `BetterHtml::Parser` exported from the `better_html` gem. Just doing a `require "better_html"` (which is the default require) does not load that type: +### 2, Initialize folder structure -```shell -$ bundle exec pry -[1] pry(main)> require 'better_html' -=> true -[2] pry(main)> BetterHtml -=> BetterHtml -[3] pry(main)> BetterHtml::Parser -NameError: uninitialized constant BetterHtml::Parser -from (pry):3:in `__pry__` -[4] pry(main)> require 'better_html/parser' -=> true -[5] pry(main)> BetterHtml::Parser -=> BetterHtml::Parser -``` +Command: `tapioca init` -In order to make sure that `tapioca` can reflect on that type, we need to add the line `require "better_html/parser"` to the `sorbet/tapioca/require.rb` file. This will make sure `BetterHtml::Parser` is loaded into memory and a type annotation is generated for it in the `better_html.rbi` file. If this extra `require` line is not added to `sorbet/tapioca/require.rb` file, then the definition for that type will be missing from the RBI file. +This will create the `sorbet/config` and `sorbet/tapioca/require.rb` files for you, if they don't exist. If any of the files already exist, they will not be changed. -If you ever run into a case, where you add a gem or update the version of a gem and run `tapioca sync` but don't have some types you expect in the generated gem RBI files, you will need to make sure you have added the necessary requires to the `sorbet/tapioca/require.rb` file. +### 3. Generate for gems -You can use the command `tapioca require` to auto-populate the `sorbet/tapioca/require.rb` file with all the requires found -in your application. Once the file generated, you should review it, remove all unnecessary requires and commit it. +Command: `tapioca generate [gems...]` -## How does tapioca compare to "srb rbi gems" ? +This will generate RBIs for the specified gems and place them in the RBI directory. -[Please see the detailed answer on our wiki](https://github.com/Shopify/tapioca/wiki/How-does-tapioca-compare-to-%22srb-rbi-gems%22-%3F) +### 4. Generate for all gems in Gemfile -## Installation +Command: `tapioca sync` -Add this line to your application's `Gemfile`: +This will sync the RBIs with the gems in the Gemfile and will add, update, and remove RBIs as necessary. -```ruby +### 5. Generate the list of all unresolved constants + +Command: `tapioca todo` + +This will generate the file `sorbet/rbi/todo.rbi` defining all unresolved constants as empty modules. + +### 6. Generate DSL RBI files + +Command: `tapioca dsl [constant...]` + +This will generate DSL RBIs for specified constants (or for all handled constants, if a constant name is not supplied). You can read about DSL RBI generators supplied by `tapioca` in [the manual](manual/generators.md). + +## Installing Tapioca into a project that already uses Sorbet (and has RBI files) + +The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. In order to start using Tapioca you will need to remove these gems and regenerate all of your automatically generated RBI files. + +### 1. Remove current RBIs + +Tapioca does not require other solutions to work. Therefore all gem and DSL RBIs should be generated with it and not an alternative solution. The easiest way to adapt is to start over by removing the entire `sorbet/rbi` folder. + +**Note**: if your application has shims (hand written RBI files), keep them saved somewhere in case you need to restore some of them. Chances are, less shims will be needed after transitioning to Tapioca. + +Additionally, don't forget to keep your `sorbet/config` file too. + +If the previously used alternatives had their own configuration files, remove them as well. + +### 2. Remove other solutions + +As mentioned, Tapioca is meant to be used on its own. Remove `sorbet-rails` or other such alternative solutions from the `Gemfile`. + +### 3. Add Tapioca + +```rb group :development do - gem 'tapioca', require: false + gem "tapioca" +end +``` +and run `bundle install` + +### 4. Run Tapioca init + +Re-initialize the `sorbet` folder structure with `bundle exec tapioca init`. You still need to run this step if you kept the shims around. + +### 5. Run Tapioca generate + +This step is the iterative process to generate the RBIs necessary for your application's gems. This part may vary depending on your setup. + +1. Run `bin/tapioca generate`. This generates RBIs for the gems in your application +2. Try to run the type checker (`bundle exec srb tc`) +3. If you notice that definitions are missing for gems, you might need to add the gem for which those definitions belong to in `sorbet/tapioca/require.rb`. Before manually adding requires, try running `bin/tapioca require` so that Tapioca can figure out the requires. If this still does not work, proceed to write manual requires +4. After requiring the gems inside that file, go back to 1. until there are no more errors coming from gems + +### 6. Run Tapioca DSL + +With all the gem RBIs in place, now Tapioca can generate DSL RBIs. DSL RBIs are definitions that only exist in runtime. For example, +```rb +class Post < ApplicationRecord + # Belongs to will create a few methods in this class + # to be able to access the associated author. Sorbet + # does not know about them, since they only exist during + # runtime. Tapioca can generate the definitions in RBIs + # for methods like this one. + belongs_to :author end ``` +Run `bin/tapioca dsl` to generate the runtime definitions for your application. -and do not forget to execute `tapioca` using `bundler`: +While going through steps 5. and 6., you might realize that some shims have become obsolete or incorrect. Make sure to edit or remove existing shims that are causing errors. + +### 7. Run Tapioca todo + +After steps 5. and 6., if there are still errors for missing definitions, you may want to try bringing back the shims you saved for later. + +If the previous shims do not satisfy all errors, you can also skip fixing them for later with the todo command. Running `bin/tapioca todo` will generate a file with empty definitions, and allows developers to track which definitions are still missing. This is optional, you might want to actually write the complete signatures in shims. + +### 8. Bump strictness on files + +After all the RBIs are generated and no type errors are occurring, some files might actually be ready to move from `typed: false` to `typed: true`. [Spoom](https://github.com/Shopify/spoom) can automatically bump files to `true` if doing so produces no new typing errors. + +To bump all possible files to `true`, simply run `bundle exec spoom bump`. + +### Things that do not need to happen + +Here are some things that do not need to be run for the migration (or ever in some cases). + +1. `bin/tapioca sync`: this command is meant to be used **after** the initial setup is complete to update RBIs for gems that have been upgraded. It does not need to be used as part of the migration process, but should be used later +2. `bundle exec srb rbi hidden-definitions`: not necessary at all, ever +3. `bundle exec srb rbi suggest-typed`: not necessary at all, ever. Prefer `bundle exec spoom bump` + +Done! Your application should be all set and type checking should pass. + +## How does tapioca compare to "srb rbi gems" ? + +[Please see the detailed answer on our wiki](https://github.com/Shopify/tapioca/wiki/How-does-tapioca-compare-to-%22srb-rbi-gems%22-%3F) + + +## Tapioca commands + +Do not forget to execute `tapioca` using `bundler`: ```shell $ bundle exec tapioca @@ -81,45 +165,44 @@ Options: --typed, -t, [--typed-overrides=gem:level [gem:level ...]] # Overrides for typed sigils for generated gem RBIs ``` -## Usage -### Initialize folder structure - -Command: `tapioca init` - -This will create the `sorbet/config` and `sorbet/tapioca/require.rb` files for you, if they don't exist. If any of the files already exist, they will not be changed. - -### Generate for gems - -Command: `tapioca generate [gems...]` - -This will generate RBIs for the specified gems and place them in the RBI directory. - -### Generate for all gems in Gemfile +### Flags -Command: `tapioca sync` +- `--prerequire [file]`: A file to be required before `Bundler.require` is called. +- `--postrequire [file]`: A file to be required after `Bundler.require` is called. +- `--out [directory]`: The output directory for generated RBI files, default to `sorbet/rbi/gems`. +- `--generate-command [command]`: **[DEPRECATED]** The command to run to regenerate RBI files (used in header comment of the RBI files), defaults to the current command. +- `--typed-overrides [gem:level]`: Overrides typed sigils for generated gem RBIs for gem `gem` to level `level` (`level` can be one of `ignore`, `false`, `true`, `strict`, or `strong`, see [the Sorbet docs](https://sorbet.org/docs/static#file-level-granularity-strictness-levels) for more details). -This will sync the RBIs with the gems in the Gemfile and will add, update, and remove RBIs as necessary. -### Generate the list of all unresolved constants +## Manual gem requires -Command: `tapioca todo` +For gems that have a normal default `require` and load all of their constants through such a require, everything works seamlessly. However, for gems that are marked as `require: false` in the Gemfile, or for gems that export optionally loaded types via different requires, where a single require does not load the whole gem code into memory, `tapioca` will not be able to load some of the types into memory and, thus, won't be able to generate complete RBIs for them. For this reason, we need to keep a small external file named `sorbet/tapioca/require.rb` that is executed after all the gems in the Gemfile have been required and before generation of gem RBIs have started. This file is responsible for adding the requires for additional files from gems, which are not covered by the default require. -This will generate the file `sorbet/rbi/todo.rbi` defining all unresolved constants as empty modules. +For example, suppose you are using the class `BetterHtml::Parser` exported from the `better_html` gem. Just doing a `require "better_html"` (which is the default require) does not load that type: -### Generate DSL RBI files +```shell +$ bundle exec pry +[1] pry(main)> require 'better_html' +=> true +[2] pry(main)> BetterHtml +=> BetterHtml +[3] pry(main)> BetterHtml::Parser +NameError: uninitialized constant BetterHtml::Parser +from (pry):3:in `__pry__` +[4] pry(main)> require 'better_html/parser' +=> true +[5] pry(main)> BetterHtml::Parser +=> BetterHtml::Parser +``` -Command: `tapioca dsl [constant...]` +In order to make sure that `tapioca` can reflect on that type, we need to add the line `require "better_html/parser"` to the `sorbet/tapioca/require.rb` file. This will make sure `BetterHtml::Parser` is loaded into memory and a type annotation is generated for it in the `better_html.rbi` file. If this extra `require` line is not added to `sorbet/tapioca/require.rb` file, then the definition for that type will be missing from the RBI file. -This will generate DSL RBIs for specified constants (or for all handled constants, if a constant name is not supplied). You can read about DSL RBI generators supplied by `tapioca` in [the manual](manual/generators.md). +If you ever run into a case, where you add a gem or update the version of a gem and run `tapioca sync` but don't have some types you expect in the generated gem RBI files, you will need to make sure you have added the necessary requires to the `sorbet/tapioca/require.rb` file. -### Flags +You can use the command `tapioca require` to auto-populate the `sorbet/tapioca/require.rb` file with all the requires found +in your application. Once the file generated, you should review it, remove all unnecessary requires and commit it. -- `--prerequire [file]`: A file to be required before `Bundler.require` is called. -- `--postrequire [file]`: A file to be required after `Bundler.require` is called. -- `--out [directory]`: The output directory for generated RBI files, default to `sorbet/rbi/gems`. -- `--generate-command [command]`: **[DEPRECATED]** The command to run to regenerate RBI files (used in header comment of the RBI files), defaults to the current command. -- `--typed-overrides [gem:level]`: Overrides typed sigils for generated gem RBIs for gem `gem` to level `level` (`level` can be one of `ignore`, `false`, `true`, `strict`, or `strong`, see [the Sorbet docs](https://sorbet.org/docs/static#file-level-granularity-strictness-levels) for more details). ## Contributing From d627ac7847ec04176e7e809cb856d0efe2a04c4d Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Tue, 7 Sep 2021 13:18:51 +0100 Subject: [PATCH 04/13] Apply suggestions from code review Apply minor suggestions (prior to looking at larger ones) Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com> --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index bb3dc89f7..09a472809 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Tapioca is a library used to generate RBI (Ruby interface) files for use with [Sorbet](https://sorbet.org). RBI files provide the structure (classes, modules, methods, parameters) of the gem/library to Sorbet to assist with typechecking. -### Why use Tapioca +### Why use Tapioca? As yet, no gem exports type information in a consumable format and it would be a huge effort to manually maintain such an interface file for all the gems that your codebase depends on. Thus, there is a need for an automated way to generate the appropriate RBI file for a given gem. The `tapioca` gem, developed at Shopify, is able to do exactly that to almost 99% accuracy. It can generate the definitions for all statically defined types and most of the runtime defined types exported from Ruby gems (non-Ruby gems are not handled yet). @@ -17,7 +17,7 @@ Tapioca helps simplify your setup too. Gems such as `sorbet-typed`, `sorbet-rail ## Installing Tapioca in a project with no existing RBI files (i.e. a fresh Sorbet project) -### 1. Add this line to your application's `Gemfile` +### Add Tapioca to your application's `Gemfile` ```ruby group :development do @@ -26,31 +26,31 @@ end ``` and run `bundle install` -### 2, Initialize folder structure +### Initialize the folder structure Command: `tapioca init` This will create the `sorbet/config` and `sorbet/tapioca/require.rb` files for you, if they don't exist. If any of the files already exist, they will not be changed. -### 3. Generate for gems +### Generate gems RBIs -Command: `tapioca generate [gems...]` +Command: `tapioca gem [gem...]` This will generate RBIs for the specified gems and place them in the RBI directory. -### 4. Generate for all gems in Gemfile +or: -Command: `tapioca sync` +Command: `tapioca gem` This will sync the RBIs with the gems in the Gemfile and will add, update, and remove RBIs as necessary. -### 5. Generate the list of all unresolved constants +### Generate the list of all unresolved constants Command: `tapioca todo` This will generate the file `sorbet/rbi/todo.rbi` defining all unresolved constants as empty modules. -### 6. Generate DSL RBI files +### Generate DSL RBI files Command: `tapioca dsl [constant...]` @@ -91,7 +91,7 @@ Re-initialize the `sorbet` folder structure with `bundle exec tapioca init`. You This step is the iterative process to generate the RBIs necessary for your application's gems. This part may vary depending on your setup. -1. Run `bin/tapioca generate`. This generates RBIs for the gems in your application +1. Run `bin/tapioca gem`. This generates RBIs for the gems in your application 2. Try to run the type checker (`bundle exec srb tc`) 3. If you notice that definitions are missing for gems, you might need to add the gem for which those definitions belong to in `sorbet/tapioca/require.rb`. Before manually adding requires, try running `bin/tapioca require` so that Tapioca can figure out the requires. If this still does not work, proceed to write manual requires 4. After requiring the gems inside that file, go back to 1. until there are no more errors coming from gems From 7af7981e9fc966788ba41286fcbb076b268db736 Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Tue, 7 Sep 2021 14:22:05 +0100 Subject: [PATCH 05/13] Update readme to add clarity - merged the two installation paths into one path with optional sections - added links to sections as suggested in code review - reduced a lot of annotative text into code blocks to make more readable --- README.md | 146 ++++++++++++++++++++++++++---------------------------- 1 file changed, 71 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 09a472809..9a9a500b6 100644 --- a/README.md +++ b/README.md @@ -12,120 +12,120 @@ As yet, no gem exports type information in a consumable format and it would be a When you run `tapioca sync` in a project, `tapioca` loads all the gems that are in your dependency list from the Gemfile into memory. It then performs runtime introspection on the loaded types to understand their structure and generates an appropriate RBI file for each gem with a versioned filename. -Tapioca helps simplify your setup too. Gems such as `sorbet-typed`, `sorbet-rails` are ways to provide accurate typing information for DSLs and gems. However, Tapioca aims to provide the complete tooling to generating RBIs for gems and DSLs, and does not require being combined with other gems, such as `sorbet-rails`, which can be removed from your gemfile. +Tapioca helps simplify your setup too. Gems such as `sorbet-typed`, `sorbet-rails` are *localized* solutions that provide typing information for DSLs and gems. However, Tapioca aims to provide the *complete tooling* to generating RBIs for gems and DSLs. Tapioca does not require being combined with other gems, such as `sorbet-rails`, which can be removed from your gemfile. -## Installing Tapioca in a project with no existing RBI files (i.e. a fresh Sorbet project) +### How does tapioca compare to "srb rbi gems" ? -### Add Tapioca to your application's `Gemfile` - -```ruby -group :development do - gem 'tapioca', require: false -end -``` -and run `bundle install` - -### Initialize the folder structure +[Please see the detailed answer on our wiki](https://github.com/Shopify/tapioca/wiki/How-does-tapioca-compare-to-%22srb-rbi-gems%22-%3F) -Command: `tapioca init` +# Installing Tapioca -This will create the `sorbet/config` and `sorbet/tapioca/require.rb` files for you, if they don't exist. If any of the files already exist, they will not be changed. +## 1. Preparing an existing Sorbet-installation for Tapioca -### Generate gems RBIs +***If you are not yet using Sorbet then skip straight to [step 2](#install_tapioca_and_generate_rbi files)*** -Command: `tapioca gem [gem...]` +The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. In order to start using Tapioca you will need to remove these gems and regenerate all of your automatically generated RBI files. -This will generate RBIs for the specified gems and place them in the RBI directory. +### Remove any current RBIs -or: +The easiest way to remove existing RBI files is by removing the entire `sorbet/rbi` folder. -Command: `tapioca gem` +**Note**: if your application has shims (hand written RBI files), keep them saved somewhere in case you need to restore some of them. Chances are, fewer shims will be needed after transitioning to Tapioca. Additionally, don't forget to keep your `sorbet/config` file too. -This will sync the RBIs with the gems in the Gemfile and will add, update, and remove RBIs as necessary. +### Remove any other solutions -### Generate the list of all unresolved constants +Remove `sorbet-rails` or other such alternative solutions from the `Gemfile`. As mentioned, Tapioca is meant to be used on its own. -Command: `tapioca todo` +If the previously used alternatives had their own configuration files, you should remove them as well. -This will generate the file `sorbet/rbi/todo.rbi` defining all unresolved constants as empty modules. +## 2. Install Tapioca and generate RBI files +*Star there in a fresh sorbet installation.* -### Generate DSL RBI files +### Add Tapioca to your application's `Gemfile` -Command: `tapioca dsl [constant...]` +```ruby +group :development do + gem 'tapioca', require: false +end +``` +Then run `bundle install` -This will generate DSL RBIs for specified constants (or for all handled constants, if a constant name is not supplied). You can read about DSL RBI generators supplied by `tapioca` in [the manual](manual/generators.md). +### Generate the RBI files for gems -## Installing Tapioca into a project that already uses Sorbet (and has RBI files) +````bash +# Generate sorbet/config and sorbet/tapioca/require.rb if required +# (they won't be touched if they already exist) +bundle exec tapioca init -The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. In order to start using Tapioca you will need to remove these gems and regenerate all of your automatically generated RBI files. +# Generate RBI files for gems +# (Generate only for specific gems using `tapioca gem [gem...]`) +bundle exec tapioca gem -### 1. Remove current RBIs +# Generate the list of all unresolved constants +# This will generate the file `sorbet/rbi/todo.rbi` +# defining all unresolved constants as empty modules +bundle exec tapioca todo -Tapioca does not require other solutions to work. Therefore all gem and DSL RBIs should be generated with it and not an alternative solution. The easiest way to adapt is to start over by removing the entire `sorbet/rbi` folder. +```` -**Note**: if your application has shims (hand written RBI files), keep them saved somewhere in case you need to restore some of them. Chances are, less shims will be needed after transitioning to Tapioca. +### Iterate RBI generation to ensure all gems are covered -Additionally, don't forget to keep your `sorbet/config` file too. +The first step may result in some typechecking errors due to missing definitions. Let's pick them up and dela with them: -If the previously used alternatives had their own configuration files, remove them as well. +````bash +# Check whether any gems are missed by running typechecking +bundle exec srb tc -### 2. Remove other solutions +# If you notice missing definitions for gems, nudge Tapioca to +# look for them by running: +bin/tapioca require -As mentioned, Tapioca is meant to be used on its own. Remove `sorbet-rails` or other such alternative solutions from the `Gemfile`. +# If this doesn't add the requisite gems, add them manually to: +# sorbet/tapioca/require.rb +# repeat as necessary +```` -### 3. Add Tapioca +Still having problems with gems not being included? Check the section on [manual gem requires](#manual-gem-requires). -```rb -group :development do - gem "tapioca" -end -``` -and run `bundle install` -### 4. Run Tapioca init +### Generate RBIs for Runtime DSLs -Re-initialize the `sorbet` folder structure with `bundle exec tapioca init`. You still need to run this step if you kept the shims around. +Methods such as Rails' `belongs_to` will dynamically generate a set of helper-methods +at runtime. Left to its own devices, Sorbet won't see them and will fall over. However Tapioca can figure +out and generate their RBIs: -### 5. Run Tapioca generate +````bash +# Generate runtime definitions +bin/tapioca dsl +```` -This step is the iterative process to generate the RBIs necessary for your application's gems. This part may vary depending on your setup. +While generating RBI files you might realize that some shims have become obsolete or incorrect. Make sure to edit or remove existing shims that are causing errors. You can read about DSL RBI generators supplied by `tapioca` in [the manual](manual/generators.md). -1. Run `bin/tapioca gem`. This generates RBIs for the gems in your application -2. Try to run the type checker (`bundle exec srb tc`) -3. If you notice that definitions are missing for gems, you might need to add the gem for which those definitions belong to in `sorbet/tapioca/require.rb`. Before manually adding requires, try running `bin/tapioca require` so that Tapioca can figure out the requires. If this still does not work, proceed to write manual requires -4. After requiring the gems inside that file, go back to 1. until there are no more errors coming from gems +### Run Tapioca todo (optional) -### 6. Run Tapioca DSL +(If there are still errors for missing definitions, you may want to try bringing back any shims you saved for later) -With all the gem RBIs in place, now Tapioca can generate DSL RBIs. DSL RBIs are definitions that only exist in runtime. For example, -```rb -class Post < ApplicationRecord - # Belongs to will create a few methods in this class - # to be able to access the associated author. Sorbet - # does not know about them, since they only exist during - # runtime. Tapioca can generate the definitions in RBIs - # for methods like this one. - belongs_to :author -end +```bash +# Skip any remaining errors by generate a file with +# empty definitions (to be fixed later on) +bin/tapioca todo ``` -Run `bin/tapioca dsl` to generate the runtime definitions for your application. - -While going through steps 5. and 6., you might realize that some shims have become obsolete or incorrect. Make sure to edit or remove existing shims that are causing errors. -### 7. Run Tapioca todo +### Bump strictness on files -After steps 5. and 6., if there are still errors for missing definitions, you may want to try bringing back the shims you saved for later. -If the previous shims do not satisfy all errors, you can also skip fixing them for later with the todo command. Running `bin/tapioca todo` will generate a file with empty definitions, and allows developers to track which definitions are still missing. This is optional, you might want to actually write the complete signatures in shims. +After generating the RBIs, some files might actually be ready to move from `typed: false` to `typed: true`. If doing so produces no erorrs then [Spoom](https://github.com/Shopify/spoom) can automatically bump files to `true`. -### 8. Bump strictness on files +```bash +# Automatically increase files to the highest level of type-strictness +# they will now support +bundle exec spoom bump +``` -After all the RBIs are generated and no type errors are occurring, some files might actually be ready to move from `typed: false` to `typed: true`. [Spoom](https://github.com/Shopify/spoom) can automatically bump files to `true` if doing so produces no new typing errors. -To bump all possible files to `true`, simply run `bundle exec spoom bump`. -### Things that do not need to happen +## Things that do not need to happen Here are some things that do not need to be run for the migration (or ever in some cases). @@ -135,10 +135,6 @@ Here are some things that do not need to be run for the migration (or ever in so Done! Your application should be all set and type checking should pass. -## How does tapioca compare to "srb rbi gems" ? - -[Please see the detailed answer on our wiki](https://github.com/Shopify/tapioca/wiki/How-does-tapioca-compare-to-%22srb-rbi-gems%22-%3F) - ## Tapioca commands From f4fd7857e12d77393793a5cd8eb384ef11c04255 Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Tue, 7 Sep 2021 14:26:23 +0100 Subject: [PATCH 06/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a9a500b6..2d3cae18a 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Tapioca helps simplify your setup too. Gems such as `sorbet-typed`, `sorbet-rail ## 1. Preparing an existing Sorbet-installation for Tapioca -***If you are not yet using Sorbet then skip straight to [step 2](#install_tapioca_and_generate_rbi files)*** +***If you are not yet using Sorbet then skip straight to [step 2](#install_tapioca_and_generate_rbi_files)*** The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. In order to start using Tapioca you will need to remove these gems and regenerate all of your automatically generated RBI files. From 4bbdea124167a0c65fcd1124e4ccf3e7261070e2 Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Tue, 7 Sep 2021 14:27:40 +0100 Subject: [PATCH 07/13] Update README.md fix links --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2d3cae18a..37225d71a 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Tapioca helps simplify your setup too. Gems such as `sorbet-typed`, `sorbet-rail ## 1. Preparing an existing Sorbet-installation for Tapioca -***If you are not yet using Sorbet then skip straight to [step 2](#install_tapioca_and_generate_rbi_files)*** +***If you are not yet using Sorbet then skip straight to [step 2](#2-install-tapioca-and-generate-rbi-files)*** The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. In order to start using Tapioca you will need to remove these gems and regenerate all of your automatically generated RBI files. @@ -59,7 +59,8 @@ Then run `bundle install` bundle exec tapioca init # Generate RBI files for gems -# (Generate only for specific gems using `tapioca gem [gem...]`) +# (Generate only for specific gems using `tapioca gem +gem...]`) bundle exec tapioca gem # Generate the list of all unresolved constants From ee50747d3de70e30480f1923f16796a2dd6831b3 Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 15 Sep 2021 12:29:18 +0100 Subject: [PATCH 08/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 37225d71a..fcafd364b 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Remove `sorbet-rails` or other such alternative solutions from the `Gemfile`. As If the previously used alternatives had their own configuration files, you should remove them as well. ## 2. Install Tapioca and generate RBI files -*Star there in a fresh sorbet installation.* +*Start here if you have a fresh sorbet installation.* ### Add Tapioca to your application's `Gemfile` From 4e3519aaf6817fb91bae0d7d851e86405e2367ff Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 15 Sep 2021 12:30:21 +0100 Subject: [PATCH 09/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fcafd364b..4cee0963f 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Tapioca helps simplify your setup too. Gems such as `sorbet-typed`, `sorbet-rail The RBI files that Tapioca generates **should not be added** on top of those that Sorbet has already generated for you. Tapioca needs to run afresh. Tapioca also supercedes the need for gems like `sorbet-rails` or `sorbet-typed`. In order to start using Tapioca you will need to remove these gems and regenerate all of your automatically generated RBI files. -### Remove any current RBIs +### Remove any existing RBIs The easiest way to remove existing RBI files is by removing the entire `sorbet/rbi` folder. From 6eb6063cd204a436e4bee7e7ce2ed5141854936c Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 15 Sep 2021 12:34:37 +0100 Subject: [PATCH 10/13] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rafael França --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cee0963f..96ae28157 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Then run `bundle install` ### Generate the RBI files for gems -````bash +```bash # Generate sorbet/config and sorbet/tapioca/require.rb if required # (they won't be touched if they already exist) bundle exec tapioca init From 1f2037cca884de9fb695a05b8d206d150304374c Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 15 Sep 2021 12:35:36 +0100 Subject: [PATCH 11/13] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 96ae28157..05ac482d4 100644 --- a/README.md +++ b/README.md @@ -68,13 +68,13 @@ bundle exec tapioca gem # defining all unresolved constants as empty modules bundle exec tapioca todo -```` +``` ### Iterate RBI generation to ensure all gems are covered The first step may result in some typechecking errors due to missing definitions. Let's pick them up and dela with them: -````bash +```bash # Check whether any gems are missed by running typechecking bundle exec srb tc @@ -85,7 +85,7 @@ bin/tapioca require # If this doesn't add the requisite gems, add them manually to: # sorbet/tapioca/require.rb # repeat as necessary -```` +``` Still having problems with gems not being included? Check the section on [manual gem requires](#manual-gem-requires). @@ -96,10 +96,10 @@ Methods such as Rails' `belongs_to` will dynamically generate a set of helper-me at runtime. Left to its own devices, Sorbet won't see them and will fall over. However Tapioca can figure out and generate their RBIs: -````bash +```bash # Generate runtime definitions bin/tapioca dsl -```` +``` While generating RBI files you might realize that some shims have become obsolete or incorrect. Make sure to edit or remove existing shims that are causing errors. You can read about DSL RBI generators supplied by `tapioca` in [the manual](manual/generators.md). From 30e677f3e6f9ae48689793c19ec3c6c1cf977278 Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 15 Sep 2021 12:36:13 +0100 Subject: [PATCH 12/13] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 05ac482d4..7c734d84d 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,7 @@ Then run `bundle install` bundle exec tapioca init # Generate RBI files for gems -# (Generate only for specific gems using `tapioca gem -gem...]`) +# (Generate only for specific gems using `tapioca gem gem...]`) bundle exec tapioca gem # Generate the list of all unresolved constants From 3278a909b7ef0c3bbb8575e87e596489af1af2b0 Mon Sep 17 00:00:00 2001 From: Peter Nixey Date: Wed, 15 Sep 2021 12:39:15 +0100 Subject: [PATCH 13/13] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7c734d84d..6bfbf767f 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,8 @@ bin/tapioca dsl While generating RBI files you might realize that some shims have become obsolete or incorrect. Make sure to edit or remove existing shims that are causing errors. You can read about DSL RBI generators supplied by `tapioca` in [the manual](manual/generators.md). +(Note - there are still a few rough patches around this WRT Rails - [please see this interim fix](https://github.com/Shopify/tapioca/issues/179#issuecomment-738948320)) + ### Run Tapioca todo (optional) (If there are still errors for missing definitions, you may want to try bringing back any shims you saved for later)