これはなに
RuboCop Rakeは、Rake関連のファイルに対してのCopを集めたRuboCopプラグインです。
実はリリースは少し前からしていたのですが、晴れてRuboCop HQ下に移動した1のでリリース記事を書いてみました。
Cops
現在、RuboCop Rakeは3つのCopを持っています。
Rake/Desc
Rake/Desc
はdesc
のないタスク定義を検出するCopです。
Rakeはdesc
のないタスクをrake -T
コマンドで表示しません。
# Rakefile desc 'Task with description' task :task_with_desc task :task_without_desc
$ rake -T rake task_with_desc # Task with description
これはrake -T
の出力する一覧からタスク定義を探したい場合にとても不便です。
また、単にドキュメンテーションとしても有用でしょう。
Rake/MethodDefinitionInTask, Rake/ClassDefinitionInTask
Rake/MethodDefinitionInTask
は、タスク定義/ネームスペース定義内のメソッド定義を検出します。またRake/ClassDefinitionInTask
はそれのクラス/モジュール版です。
Rakeでは、ネームスペース定義内でもスコープはトップレベルです。つまり、ネームスペース定義内でメソッドを定義したとしても、それはトップレベルに定義されます。
# Rakefile namespace :foo do class C end end p C # Cはトップレベルに定義されているので、ここでもアクセスできる。
これは分かって書いているならまだ良いのですが、namespace
がモジュールの名前空間も作成していると誤解して書いてしまうと事故の元となります。
トップレベルに定義されないと思って定義したクラスが、他のトップレベルのクラスを意図せず上書きしてしまうかもしれません。
このCopはそのようなコードを検出します。
ネームスペース内でクラスを定義したい場合はClass.new
などを使って衝突を回避するか、衝突の可能性があることを理解した上でこのCopをdisabledにすると良いでしょう。
Future
RuboCop RakeにはまだCopが3つしかありません。 ですが実装していないだけでCopのアイディアはいくつかあります。
重複したタスク/ネームスペースの定義
- https://github.com/rubocop-hq/rubocop-rake/issues/13
- https://github.com/rubocop-hq/rubocop-rake/issues/14
Rakeでは、重複したタスク/ネームスペースの定義があると、それらはマージされるようになっています。
# Rakefile task :foo do p 'foo 1' end task :foo do p 'foo 2' end
$ rake foo "foo 1" "foo 2"
おそらくこれらを2つに分けて書く必要はないでしょう。 タスクが2つに分かれて定義されることには、私は次のようないくつかの問題があると思います。
- 挙動が自明ではない
- メソッド定義のように片方がもう片方に隠されるとも想像できる。
- 2つ定義していることに気が付かないかもしれない
- この2つの定義が離れた位置にあったら、どちらか片方しか目に入らないために片方に気が付きづらくなる。
- 単に無駄
- 意味もなく分ける必要はない
このCopの実装は一見簡単そうですが、ネームスペースを考えると少し面倒そうです。
# Rakefile # 次の2つは同じタスク task :'foo:bar' namespace :foo do task :bar end
実装としてはon_xxx
のパターンを使わず、investigation
メソッドでファイル内すべてのタスク定義の名前を取り出して、その中の重複を調べる形になるのではないかなと思っています。
タスク名に:
を使っているものを警告する
# bad task :'foo:bar' # good namespace :foo do task :bar end
やるだけですね。goodとbadが逆のパターンも簡単に実装できそうですが、需要があるのかわかりません。 そもそもこのCopに需要があるかも微妙ですね。タスク名にコロンを書きたくなることもあると思うし混在していて良いと思うので、デフォルトではdisabledでも良いかなと思っています。
まとめ
簡単にRuboCop Rakeの紹介をしました。 ぜひ使ってみてください。
また、Pull Request, Issueをお待ちしています。 RuboCopで検出できるRakeで書きがちな問題はまだまだあると思うので、そういうアイディアをIssueにもらえるだけでも助かります。