RubyKaigi 2023参戦のためにRuby 3.2にバージョンアップしました
はじめに
Leaner 購買開発チームの RKTM と cobachie です。
いよいよ RubyKaigi 2023 の開催が迫ってきましたね!
Rubyist との交流が楽しみですが、そのためには我々にとって超えないといけない壁がありました。
Leaner 購買では Ruby がまだ 3.0 系だったのです(最新はご存知の通り 3.2 系)。
せっかくの RubyKaigi なので、3.2 系のいろいろな話を吸収して、帰ったらすぐにプロダクトで試したい。
ということで急遽 Ruby を最新化する活動を始めました。
Ruby 3.1へ上げる
Ruby 3.1 に上げたところ何箇所かエラーや警告が出ました。その原因と解決方法について記載します。
NameError: uninitialized class variable @@schemes in URI Did you mean? scheme_list
rake aborted!
NameError: uninitialized class variable @@schemes in URI
Did you mean? scheme_list
/usr/local/bundle/gems/data_uri-0.1.0/lib/data_uri/uri.rb:64:in '<module:URI>'
/usr/local/bundle/gems/data_uri-0.1.0/lib/data_uri/uri.rb:1:in '<main>'
data_uri gem が Ruby 3.1 の変更に対応していなかったため発生したエラーでした。
既存コードを確認すると、利用していた機能は data_uri gem のごく一部(content
data
の参照のみ)でした。
# 既存コードの利用例
uri = URI::Data.new(base64_data)
filename = "#{uri.content_type.split('/').last}"
do_something(io: StringIO.new(uri.data, 'rb'), filename:)
この機会に data_uri への依存をやめ、下記のようにインターフェースを保ちつつ、独自に実装を書き換えました。(Stack Overflow の実装を参考にしました。)
module URI
class Data
REGEXP = %r{\Adata:([-\w]+/[-\w+.]+)?;base64,(.*)}m
def initialize(uri)
data_uri_parts = uri.match(REGEXP) || []
@content_type = data_uri_parts[1]
@data = Base64.decode64(data_uri_parts[2])
end
end
end
LoadError: libruby.so.3.0: cannot open shared object file: No such file or directory - xxx
開発環境を Docker 化していると起こりがちな問題のようです。
コンテナ内で gem pristine --all
すると解決できました。
docker compose run {コンテナ名} sh -c "gem pristine --all"
今回初めて gem pristine
コマンドを知ったのですが、コマンドリファレンス によると、「キャッシュされた gem とインストールされた gem を比較し、差分があればキャッシュされた gem に戻す(pristine=手つかずの状態にする)」コマンドとのこと。
Calling DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call DidYouMean.correct_error(error_name, spell_checker) instead.
最後は下記の警告の解消です。
Calling 'DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call 'DidYouMean.correct_error(error_name, spell_checker)' instead.
RubyGems の下記 issue の通り、bundle update --bundler
で解消できました。
あとは動作確認して、CI が通ることを確認して、リリース!
ハマるところが多かったのですが、無事 Ruby 3.1 へ上げることができました。
Ruby 3.2へ上げる
続いて Ruby 3.2(2023 年 4 月時点の最新バージョン v3.2.2)に上げていきます。
Ruby 3.2.2 にバージョンを切り替えて RSpec を実行すると、数箇所で以下のエラーが発生しました。
ArgumentError:
wrong number of arguments (given 2, expected 1)
調査したところ、以下の issue に記載されている rspec-mocks の問題でした。
Ruby 3.2 でキーワード引数の仕様が変わったことにより、モックの with
などのメソッドでキーワード引数がうまく渡せなくなったという不具合でした。
rspec-mocks v3.12.2 でこの問題が修正されていたので、rspec-mocks を含む rspec 関連 gem のバージョンをアップデートすることで解決しました。
$ bundle update rspec
こちらも動作確認と CI チェックを経て、無事に本番環境へリリースしました。
Leaner 購買はローンチしたばかりの新しいサービスで、RSpec などの自動テストを意識して開発しています。
そのおかげで、Ruby のバージョンアップに伴って発生した問題をすぐに検出でき、スムーズにバージョンを上げることができました。
テストは大切ですね。
最後に
Leaner 購買では、RubyKaigi 2023 に向けて Ruby 3.2 へのバージョンアップを行い、自信を持って Ruby の最新情報にアクセスできる環境を整えることができました。
これによってさらに RubyKaigi 2023 への期待が高まっています。
Leaner Technologies は RubyKaigi 2023 に Ruby Sponsor として協賛しています。
- Day 1 (5/11)
- スポンサーPR トークで代表の大平が登壇
- Lightning Talksで黒曜が登壇
- Day 2 (5/12)
- Leaner Drinkup を開催
また、多くのエンジニアがオフライン・オンラインで参加予定です。世界中の Rubyists と松本でお会いできるのを楽しみにしています。
Discussion