Recently I discussed the future of rbs collection in ruby-jp, the Japanese online Ruby community. The discussion was exciting, so I'd like to share it.
By the way, if you don't know rbs collection, see https://dev.to/pocke/rbs-collection-was-released-4nmm . This article introduces rbs collection with a motivating example.
I'm planning the following idea to scale rbs collection to grown ruby/gem_rbs_collection.
- rbs collection will migrate to use RubyGems' scoped packages in a few years, like
- But RubyGems doesn't have the feature, so we need to develop it.
@ybiquitous asked me did I consider providing ruby/gem_rbs_collection's RBS as a gem, like
@types/** of TypeScript. I had the idea but I didn't adopt it for the first release of
rbs collection. And I realized I didn't describe the reason publicly. I summarized the answer to the question in this article.
rbs collection downloads RBSs with
git clone from ruby/gem_rbs_collection GitHub repository.
It works well for now, but probably it will introduce many problems in a few years because the repository will grow as DefinitelyTyped.
- It will be slow!
- As you know, cloning a large repository is slow.
- The repository will have many gem's RBSs.
- It will be expensive for GitHub's server.
- CocoaPods used (or still uses?) shallow clone, and it was too expensive.
Partial clone reduces the impact, but it just procrastinates the problems.
git clone is slow, but it is the simplest way.
At first I created a PoC with GitHub API v4 (GraphQL) because it could keep less API calls. However it was not a good idea. GitHub API requires an API token, so the user needs to prepare a Personal Access Token to use it for the local environment and CI.
GitHub API v4 has another problem; It truncates large file contents. Therefore I needed combining GitHub API v4 and another API.
git clone will introduce performance issues. I'll describe a solution idea in the next section.
The solution idea is using RubyGems' scoped packages. It is the same way of
@types/* of TypeScript.
For example, imagine a Gemfile:
# Gemfile source "https://rubygems.org" # I use the following gems gem "rails" gem "sidekiq" gem "parallel" # So, I need the following RBSs! gem "@types/rails" gem "@types/sidekiq" gem "@types/parallel"
Gemfile, then execute
bundle install. That's all! Steep and so on load RBSs from
It looks useful, but I need to solve many things to realize the idea.
Just off the top of my head I can imagine we need many tasks to implement it, adding organization, adding UI of rubygems.org, the authentication and authorization, updating gemspec/Gemfile.lock/installed package's path, and so on.
We still have another issue; It needs automatically published
It is easier than implementing scoped packages, of cause. I guess we just need to set-up a workflow of GItHub Actions.
Nothing has been decided yet, but I think it is the best way. I'll investigate it.
@znz told another idea; Using RubyGems'
source instead of scoped packages. For example:
# Gemfile source "https://rubygems.org" # It is the same gem "rails" gem "sidekiq" gem "parallel" source "https://rbs.rubygems.org" do gem "rbs-rails" gem "rbs-sidekiq" gem "rbs-parallel" end
Realizing the solution is easier than the scoped packages solution. It doesn't need to modify RubyGems, we can realize it with existing assets!
However this solution has problems:
- We need a server to host
- I don't want to maintain the server.
- The package name can conflict with a gem from
- If both
rbs-railsgem, user cannot use both gems together.
- We can solve the problem with more unique prefix like
rbs-types-*, but I think it is not smart.
- If both
source is not the best way, but maybe we can use the solution as a temporary solution.
git clone will be slow with grown ruby/gem_rbs_collection. Therefore I'm planning to migrate rbs collection to use RubyGems' scoped package, but it has difficulty.
I think scoped package is the best solution to manage third party RBSs in the long term. I work on improving RBS management. 🚀💎