RuboCop Faker を作った

以前の日記に書いた Faker 2 での破壊的変更となる positional arguments から keyword arguments への移行をサポートする Gem を作った。

github.com

RuboCop の 3rd party gem として作っているので、gem i rubocop-faker などして以下のように使う。

非推奨な引数の形式を使っている場所を検出するには以下のコマンドを実行する。

% rubocop --require rubocop-faker --only Faker/DeprecatedArguments

非推奨な引数の形式を Faker 2 の引数の形式に自動修正するには以下のコマンドを実行する。

% rubocop --require rubocop-faker --only Faker/DeprecatedArguments --auto-correct

以下のように keyword arguments を使うスタイルに自動修正される。

-Faker::Avatar.image(slug, size, format, set, bgset)
+Faker::Avatar.image(slug: slug, size: size, format: format, set: set, bgset: bgset)

Faker 2 での破壊的変更については以前の日記を参照のこと。

koic.hatenablog.com

おまけ

今回の移行ツールとして影響されたのは以下。

基本的に一回実行するだけのコマンドとなると思うので、あまり手を掛けずに作る方向で進めた。gem の名前でいろいろと悩んでいたが AST の変換には RuboCop を使うのが一番手が早そうだったので、そのまま素直に RuboCop Faker とした。他の命名案についても Ginza.rb の懇親会で話していたが無難に落ち着けた感じ。

RuboCop Minitest 0.1.0 をリリースした

最初の cop 実装としてもらっていた PR のレビューが終わったのでマージして、RuboCop Minitest 0.1.0 をリリースした。

rubygems.org

現在導入されている Minitest/AssertNil cop は assert_equal(nil, actual) に対して assert_nil(actual) を使うよう Minitest が非推奨警告するものを静的解析段階で伝えるもの。Minitest/AssertNil cop による offense のサンプルは以下。

% bundle exec rubocop --require rubocop-minitest
Inspecting 1 file
C

Offenses:

test/foo_test.rb:1:1: C: Minitest/AssertNil: Prefer using assert_nil(actual) over assert_equal(nil, actual).
assert_equal(nil, actual)
^^^^^^^^^^^^^^^^^^^^^^^^^

bad, good は以下で auto-correct あり。

# bad
assert_equal(nil, actual)

# good
assert_nil(actual)

RuboCop Minitest について、今後は RuboCop HQ でメンテナンスされている The Minitest Style Guide をもとに cop が足されていくと思う。

github.com

Faker 2.0の破壊的変更とその緩和施策

TL;DR: Faker 2 系を使うなら Faker 2.2 に bundle update すると破壊的変更が緩和される。

Faker 2.0 で以下の破壊的変更が入っていた。

% cat example.rb
Faker::Address.zip_code('NY')

% bundle exec ruby example.rb
Traceback (most recent call last):
        1: from example.rb:3:in `<main>'
/Users/koic/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/faker-2.1.2/lib/faker/default/address.rb:32:in
`zip_code': wrong number of arguments (given 1, expected 0) (ArgumentError)

これは以下のように Faker 2.0 で置き換えられたキーワード引数を使うように更新すれば解決する。

-Faker::Address.zip_code('NY')
+Faker::Address.zip_code(state_abbreviation: 'NY')

github.com

というのは自分が踏んだ問題で、この時点ではどんなキーワードを使えば解決するのか突然の ArgumentError から変更履歴を辿って見るまで分からなかった。これを踏まえたパッチを送って Faker 2.2 ではそれが反映されている。

Faker 2.2 ではいきなり ArgumentError になるのではなく、使うべきキーワードを含んだ非推奨警告を出すようにアップグレードへの痛みを緩和した。

github.com

% bundle exec ruby example.rb
example.rb:3: Passing `state_abbreviation` with the 1st argument of
`Address.zip_code` is deprecated. Use keyword argument like
`Address.zip_code(state_abbreviation: ...)` instead.

ただ、引数ひとつの場合にもキーワード引数を使うのは冗長で使いづらいという声もあり、Faker 3 ではもう少しインタフェースが変わるかもしれない。このあたりは faker-ruby/faker#1692 あたりの議論としていくのかなと思っている。

このあたりのインタフェース変更について RSpec 2 から RSpec 3 への移行ほどではないが、Transpec 的な移行ツールを用意してみようと思い手元で WIP となっている。そのうちリリースするかもしれない。

JRuby 9.2.8.0 がリリースされた

RubyConf Taiwan 2019 で soon と言われていた JRuby 9.2.8.0 がリリースされた。

www.jruby.org

TokyuRuby会議13で話した以下のイシュー解決が含まれているので、自分としては待ち望んでいたリリースだった。

rbenv と RVM には PR を開いてマージされているので master を使えばビルドできると思う。

github.com

github.com

CircleCI で使っている Docker イメージも更新したいところで、その過程で見かけたリポジトリにも PR を開いている。

github.com

本命となる CircleCI で使っている Docker イメージも更新したいところだが、まだ追えていない。

RuboCop Rails 2.3.0 をリリースした

RuboCop Rails 2.3.0 をリリースした。

github.com

New features

#78: Add new Rails/EnumHash cop. (@fedeagripa, @brunvez, @santib)

pocke さんによる提案を Rootstrap 社のオープンソースハッカソンで実装された cop となる。

bad と good は以下で、例えば中間の要素を削除した場合にデータベースへの値がずれることを予防するため Hash 記法を推奨するもの。

# bad
enum status: [:active, :archived]

# good
enum status: { active: 0, archived: 1 }

auto-correct 付き。

Bug fixes

#53: Fix a false positive for Rails/SaveBang when implicitly return using finder method and creation method connected by ||. (@koic)

Rails/SaveBang cop でデフォルトとなっている AllowImplicitReturn: true で暗黙的な戻り値となる find(**opts) || #{method}(**opts) のような || 演算子による戻り値のケースでの false positive を修正している。

#97: Fix two false negatives for Rails/EnumUniqueness. 1. When enum name is not a literal. 2. When enum has multiple definitions. (@santib)

Rails/EnumHash cop のレビューの過程で pocke さんが指摘した既存の Rails/EnumUniqueness cop にある false negative を修正している。

Changes

#98: Mark Rails/ActiveRecordAliases as SafeAutoCorrect false and disable autocorrect by default. (@prathamesh-sonpatki)

Rails/ActiveRecordAliases cop が自分で定義した update_attributesupdate に auto-correct するということで、Rails イシューチームメンバーより SafeAutoCorrect: false と変更している。

SafeAutoCorrect については以下のエントリを参照のこと。

koic.hatenablog.com

#101: Mark Rails/SaveBang as SafeAutoCorrect false and disable autocorrect by default. (@prathamesh-sonpatki)

同上で Rails/SaveBang cop を SafeAutoCorrect: false と変更している。

#102: Include create_or_find_by in Rails/SaveBang cop. (@MaximeLaurenty)

Rails/SaveBang cop に対して、Rails 6.0 で導入される create_or_find_by への対応を含めている。

Asakusa.rb 第524回

カラボメンバーが会場係をしてくれたおかげで勤務先が会場だったので 20:30 頃まで参加していた。翌日の銀座Rails #11 の登壇準備をしていた @yahonda さんrsim/oracle-enhanced#1900rails/rails#36471Oracle 対応について、現在の Oracle (19c) だと NoDatabaseError を検知することはできないということで、rsim/oracle-enhanced#1900 のクローズと以下の PR をオープンする実装方針についての相談をしていたりした。

github.com

平成.rb #6

@mtkasimaに招待を頂いて平成.rb #6 でゲスト LT をしてきた。

heiseirb.connpass.com

RubyConf 2018 の際に LT の順番がまわって来ずにお蔵入りになっていたスライドをカスタマイズして発表した。当日のスライドは以下。

平成と掛けて何をトークするか悩んでいたところ、勤務先の永和と新元号の令和を掛けて「"I come from /eiwa/" ということである意味で令和から来ました」から正規表現を使ったバグ事例に繋げていたりしている。

スライドについて英文の添削などは受けていないので所々間違っていたりもすると思うけれど、自身の PR のやりとりではだいたいこんな英文で行なっている。

LT 応募枠のトークでは JIT の紹介からコードフォーマット、Open API などどれも興味深いテックトークだったことに加えて、スポンサートークでもアジャイルソフトウェア開発の話を聞けたりして幅広いテーマで楽しかったです。ありがとうございました。