今日作ろうと考えていた Cop の実装はまた後日。
明日だと思っていた飲み会が今日ということが先ほど判明しましたので、本日の活動は終了です。
— Koichi ITO (@koic) 2017年10月4日
今日作ろうと考えていた Cop の実装はまた後日。
明日だと思っていた飲み会が今日ということが先ほど判明しましたので、本日の活動は終了です。
— Koichi ITO (@koic) 2017年10月4日
Rails で bin/rails g migration create_articles
といったようにマイグレーションファイルをジェネレータで作る機会が多いと思う。
% bin/rails g migration create_articles title:string invoke active_record create db/migrate/20171003150532_create_articles.rb % cat db/migrate/20171003150532_create_articles.rb class CreateArticles < ActiveRecord::Migration[5.1] def change create_table :articles do |t| t.string :title end end end
先日 Rails 本体は frozen string literal の対応がされたが、ジェネレーターで作られる Rails アプリケーションコードには frozen string literal マジックコメントは入らないため、各自入れることになる (マイグレーションに限らずジェネレータ全般の話) 。
根拠としては以下の PR でジェネレータのテンプレートにそのマジックコメントを入れる対応を送ったが、コアチームによって Close されている。詳しくはリンク先。
なので現実線として、upstream のジェネレータに頼ることなく frozen string literal マジックコメントを Rails アプリケーションコードに入れるには、エディタに設定するなり、RuboCop の Style/FrozenStringLiteralComment
cop で autocorrect するなりの手段を講じることになる。
あとはコアチームを説得できる材料を持って Issue を立てるなども考えられるので、そちらの線で本気で対応しようと考える場合は考慮してみてもよいかもしれない (個人的に難易度高い気がしていますが) 。
RubyKaigi 2017 のときに、Rails コントリビューター勢での雑談でこのあたり少し話題に挙ったのを思い出したので、話題に挙った内容で記していない点や異なる点はあるが記しておいた。
自分が見回っているリポジトリの中で、世の中でよく使われているであろう Bundler と RuboCop の今後の Ruby のサポートバージョンについて書いておく。
bundler/bundler の master ブランチは Bundler 2 になっていて、Ruby 2.3 以上のみがサポートとなった。
https://github.com/bundler/bundler/blob/0747989a9bf47fc0404248d20628ab64ce09d3be/.travis.yml#L28-L30
PR としては1ヶ月経たないくらい前にマージされたこちら。
Bundler 1 系は Ruby 1.8 系からサポートしていて、Bundler の実装としても Ruby 1.8 で動く必要があったのと、Travis CI のマトリックスが多く CI にとても時間が掛かっていたという開発視点でだいぶ良い判断だと思う。個人的に見ている中で rails/rails (というかそのほとんどは railties) より長い CI のリポジトリは bundler/bundler だけだったので、その点でも良くなりそう。
RuboCop も Ruby 2.0 のサポートが切られた。
このまま Ruby 2.1 のサポートも切る流れになると思うので、EOL の Ruby に気を払わなくて良くなるのはこちらも良いこと。
Rails に関しては表立った情報がないけれど、Rails 5 で Ruby のサポートバージョンを変えたように、今後の Rails 6 でどうして行くのか関心のあるところ。
RuboCop で cop を作るときに、Parser gem の S 式を知るために使っている自作 gem となる。
もともとプレゼンテーション用に AST の画像を作るために作ったものだったが、すっかり cop 作成時の S 式のテキスト表現を得るためのものになったため、画像出力が不要な場面が多くなった。
ということで以下のような -n
(--no-image
) オプションを追加した。
% ruby_ast_visualizer -n -e 'puts("hello")' (send nil :puts (str "hello"))
これで不要な a.png ファイルが作成されなくなった。デフォルト --no-image
も考えたが、もともとの gem の方針から外れるのでそれは控えた。
今日作っていた cop で調べたログ。
グローバル変数 $stderr
を Parser gem による S 式で表現すると以下のようになる。S 式の比較のため、引数が複数あるパターンと引数のないパターンを挙げておく。ちなみに ruby_ast_visualizer は自作の gem で Parser gem の出力表示を得ることができるラッパーコマンドとして使っている。
% ruby_ast_visualizer -e "$stderr.puts('foo', 'bar')" (send (gvar :$stderr) :puts (str "foo") (str "bar"))
% ruby_ast_visualizer -e "$stderr.puts" (send (gvar :$stderr) :puts)
このグローバル変数 $stderr
を RuboCop の def_node_matcher
に渡す S 式で表現する場合、$
という記号はマッチした値をキャプチャする意味で使われているためそのまま使えない。代わりに #
でメソッド呼び出しにする。
def_node_matcher :stderr_puts?, <<-PATTERN (send (gvar #stderr_gvar?) :puts ...) PATTERN
対応するメソッドの方でマッチするか判定させる。
def stderr_gvar?(sym) sym == :$stderr end
他の cop 実装がサンプルコードになっているので、このあたり gvar
で grep して他に類似のケースでどうしているかを調べてみていた。
追記 pocke さんから Twitter でコメントを頂く。
https://t.co/skN7kfZrlV
— Pocke(ぽっけ) (@p_ck_) 2017年10月1日
これでテスト全部通ってるし、動くんじゃないだろうか(たぶん)
以前、ぎんざRuby会議01 での Bundler 2 のプレゼンで取り挙げたように bundle
コマンドの挙動が Bundler 2 で変わる予定。
現在の Bundler 1.15 系と異なり、Bundler 2 での bundle
コマンドは以下のようにコマンドの一覧表示になる。
% bundle Bundler version 2.0.0.dev (2017-09-29 commit 5e9c40aa1) Bundler commands: Primary commands: bundle install [OPTIONS] # Install the current environment to the system bundle update [OPTIONS] # Update the current environment bundle cache [OPTIONS] # Locks and then caches all of the gems into vendor/cache bundle exec [OPTIONS] # Run the command in context of the bundle bundle config NAME [VALUE] # Retrieve or set a configuration value bundle help [COMMAND] # Describe available commands or one specific command (snip)
この変更がどういうことかというと、bundle gem
で作った gem の README.md テンプレートに記されたインストール手順をそのまま README に使っている gem が問題になる (慣れた人であれば、インストールドキュメントを見ながら bundle
コマンドを打つ人は少ないと思うが) 。端的にいうと bundle
コマンドではインストールできなくなるので、bundle install
に書き直す必要がある。bundle install
であれば1系、2系両方に対応するので、それが正解だと思っている。
Bundler 2 は未だリリースされていないため、もう少し様子見をした方が良いかなと思っているけれど、この変更が実現したら OSS Gate ワークショップあたりで README どおりの手順で行なったけれどインストールできないといった PR が多数出るのかなとも予測していたりする。
bundle gem
を利用する gem 職人向けには Bundler にパッチを出しておいたので、このパッチ以降は問題がそのはなくなるけれど、現在世にある gem でも相当数のインストール手順が bundle
になっているものがあるので、振る舞いとしては良くなったと思う一方で、既存ドキュメントへの非互換として知っておいて良いと思う。