Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Ruby version manager written in Rust, which is 7 seconds faster than rbenv

TaKO8Ki
September 18, 2021

A Ruby version manager written in Rust, which is 7 seconds faster than rbenv

Link to a slide on Canva

frum: https://github.com/TaKO8Ki/frum
gobang: https://github.com/TaKO8Ki/gobang
Article about frum: https://zenn.dev/tako8ki/articles/2021-09-ruby-version-manager-written-in-rust

I built a Ruby version manager with Rust, which is 7 seconds faster than rbenv. In detail, it takes about 7 seconds faster to install a particular version and set it with frum than rbenv.

Ruby has a lot of code that depends on the runtime version. Therefore, it is important to manage Ruby versions. However, it takes 2 to 3 minutes to run rbenv install, depending on the environment, and waiting for this to happen every time you install a new version is inefficient. The main bottleneck is a command-line utility called ruby-build, which makes it easy to install virtually any version of Ruby. In order to solve this problem, I created a Pure Rust Ruby version manager called frum.

In this talk, I will share my efforts to build a simple and easy to use Ruby version manager with Rust, and what I learned in the process of making frum like the following things.

- Tips on good E2E testing a CLI that manipulates files using declarative macros
- Tips for writing a CLI with multiple subcommands in Rust
- How to use the command line parser clap to implement flexible command-line completion

Q&A

frumはプロダクションでも利用できますか?例えば、今後どのくらいの期間保守が続けられる予定でしょうか?(追記)例えば、moneyforward社で利用予定はありますか?

> frumはプロダクションでも利用できますか?例えば、今後どのくらいの期間保守が続けられる予定でしょうか?

プロダクションでの利用はあまり想定していません。例えば、tempdirを利用しているので、ユーザー間でそれが競合してしまうことなどが考えられます。基本的に僕が仕事でRubyを書いている間はメンテする予定なので、少なくとも2、3年は問題ないと思います。基本的にはユーザーがいる限りメンテし続けようとは考えています。

> 例えば、moneyforward社で利用予定はありますか?

基本的に本番環境でバージョンマネージャーを用いたバージョンの切り替えなどは行ってないはずなので、本番環境での利用はしないと思われます。ローカルで使ってくださる方は、もしかしたらいるかもしれないですね。そこら辺は他のOSSと同じで個々の判断で使っていただく形になると思います。

TaKO8Ki

September 18, 2021
Tweet

More Decks by TaKO8Ki

Other Decks in Programming

Transcript

  1. A Ruby version manager written in Rust, which is 7

    seconds faster than rbenv Takayuki Maeda (@TaKO8Ki) Rust.Tokyo 2021
  2. About myself Takayuki Maeda GitHub: @TaKO8Ki Twitter: @TaKOBKi Software Engineer

    @ Money Forward, Inc. Senior at Kobe University majoring Civil Engineering
  3. $ rbenv install 2.6.5 # Install a Ruby version using

    ruby-build $ rbenv local 2.6.5 # Set or show the local application-specific Ruby version $ rbenv global 2.6.5 # Set or show the global Ruby version What is rbenv? rbenv is a tool that lets you install and run multiple versions of Ruby side-by-side.
  4. What is ruby-build? ruby-build is a command-line utility that makes

    it easy to install virtually any version of Ruby, from source.
  5. What is frum? A little bit fast and modern Ruby

    version manager written in Rust Pure Rust implementation not using ruby-build Works with .ruby-version files Faster than rbenv github.com/TaKO8Ki/frum
  6. You need to wait for 2 to 3 minutes every

    time you install new versions of Ruby
  7. Benchmark eval "$(rbenv init -)" → rbenv install → rbenv

    local vs eval "$(frum init)" → frum install → frum local
  8. What did I improve? rbenv is written in bash script

    ruby-build is also written in bash script rbenv uses shims to switch Ruby versions
  9. ・rbenv is written in bash script ・ruby-build is also written

    in bash script ・rbenv uses shims to switch Ruby versions
  10. ・rbenv is written in bash script ・ruby-build is also written

    in bash script ・rbenv uses shims to switch Ruby versions
  11. $ ./configure $ make $ sudo make install What to

    do basically is Download source and unpack a tarball, then just do this:
  12. ・rbenv is written in bash script ・ruby-build is also written

    in bash script ・rbenv uses shims to switch Ruby versions
  13. What is shim? > In computer programming, a shim is

    a small library that transparently intercepts API calls and changes the arguments passed, handles the operation itself, or redirects the operation elsewhere. https://en.wikipedia.org/wiki/Shim_(computing)
  14. In case you use Ruby 2.6.5 rbenv exec ruby -v

    turns into PATH=”~/.rbenv/versions/2.6.5/bin:$PATH” ruby -v
  15. When does rbenv create shims? So what does rbenv rehash

    do? rbenv rehash creates shims. rbenv init runs it internally.
  16. 4. Rehash iterates through all files in ~/.rbenv/versions/${version}/bin/ of all

    Ruby versions installed. Then, it copies prototype file into the shim scripts
  17. How does frum solve this problem? frum uses symlinks to

    switch Ruby versions. src/commands/init.rs
  18. Tips for good E2E testing Since frum has some subcommands,

    It is important to check if your state is as expected after running multiple commands. frum init frum install frum local ⬅︎ ⬅︎
  19. Tips for good E2E testing utils::setup does the following things:

    prepares a temp directory for each test functions sets some environment variables frum needs
  20. Tips for good E2E testing If stdout or stderr is

    not as expected, the error is displayed like the following:
  21. Tips to implement flexible Command-line completion using clap You can

    implement completion using clap::App::gen_completions However it is not useful enough
  22. In frum ⬅︎ prepare a empty vector store completions into

    buffer ⬅︎ ⬅︎ iterating over lines in completions
  23. Conclusions frum install runs a little bit faster than rbenv

    install frum init runs about 6x faster than rbenv init