Using `tapioca` with `rails`

Using `tapioca` with `rails`

Tapioca is a library used to generate RBI (Ruby interface) files for use with Sorbet.

Asuming you already have an idea of what tapioca is, and you've decided to give it a try, let's take a look into my first attempt installing it into a rails project.

Installation

The first step is adding tapioca to your project, this can be done as such:

bundle add tapioca
bundle binstub tapioca

This will actually install the sorbet gems too!

Initialization

Then we can initialize tapioca by using:

bin/tapioca init

This will create two files: sorbet/config and sorbet/tapioca/require.rb

The first one will look like this:

--dir
.

I suggest adding options to ignore common directories with autogenerated files or other non typeable files, for example:

--dir
.
--ignore=coverage/
--ignore=db/
--ignore=lib/templates/
--ignore=log/
--ignore=public/
--ignore=tmp/
--ignore=vendor/

The other one seems kinda tricky at first. It will be empty at first.

Tapioca will, by default, require all gems specified in the Gemfile, just as they are required there, either by default or with the :require option.

If you run `bin/tapioca require' it will populate the file with what looks like this default requires written explicitly. Something like:

# DO NOT EDIT MANUALLY
# This is an autogenerated file for explicit gem requires.
# Please instead update this file by running `tapioca require`.

require 'aasm/rspec'
require 'action_cable/engine'
.
.
.

You can customize this file if you need to make some custom requires, such as files or modules not required by default.

I decided to run this command and commit the file, so I can manually decide whether or not, or when to add newly installed gems to the typing system. Anyway, the file can always be recreated by rerunning the command.

Generating Gems RBIs

After having tapioca initialized we'll want to create RBI files for each of our dependencies.

Tapioca does this by creating one .rbi file for each gem, all of them versioned to current installed version of the gem, so they can be easily replaced when updated.

To create this files just run:

bin/tapioca sync

Ideally this would go smoothly and create the described files under sorbet/rbi/gems.

In my case I had some gem that was raising an error, and the sync process would crash and not continue past it.

This could be troublesome if it were an important or highly used dependency of your project.

I had to exclude it from the sync process, so it won't have an .rbi file, meaning we might have to do some work mannually eventually.

I excluded the crashing gem with:

bin/tapioca sync -x public_activity

The todo.rbi file

This is a file where every constant that couldn't be discovered by tapioca but is used anyway in the project is defined, so sorbet can recognize them.

You should look at this file every once in a while and try to figure out why this constant might be being missed by tapioca. Some of them might be fixed by required files as mentioned in the section before.

The sorbet-rails bit

After some trying and erring, I found out that ending the process of integrating with sorbet-rails wasn't really that hard at all.

I run the rails_rbi:all rake task provided and after generating the .rbi files for rails related classes and methods, as well as some other useful helpers, I run the typecheck with bin/srb tc.

Since I was installing tapioca in a project which already had sorbet installed traditionally, some files had typing sigils already.

Just as tapioca and srb-rbi work differently to create the .rbi files provided, they too might create different levels of typing coverage for your files. Then, some files might have improved or worsened their # typed: level.

Run bin/srb rbi suggest-typed to adjust each files sigil to the appropriate actually covered level.

After doing this, I had no file in the ignore level and a some bunch of files have shifted levels.

Even if I don't know if the ending result had more files typed or not, comparing to the bug I was facing that prompted me to look at tapioca, the result is pretty satisfactory.

I'll keep exploring tapioca in this project and see if it is actually better for my needs than srb-rbi and whether I'd like to use it in other sorbet typed projects.

Keeping updated

To keep your .rbi files updated the overall process would look something like this:

bin/tapioca sync
bin/tapioca todo
bin/rails rails_rbi:all
bin/srb rbi suggest-typed

Other notes

Remember to remove any # typed: ignore sigil you might have preexisting from a traditional sorbet installation prior to syncing the gem .rbi files.