haml-lint 0.15.0における Style/Next の誤検知

Misoca開発チームのmzpです。 iPhone 6sはゴールドを予約しました。

Misocaでは先日からHAMLの書き方を統一するために、haml-lintを導入しました。 そこで Style/Next ルールによって誤った警告が出力されて困ったので、そのときの話について書きたいと思います。

要約

haml-lint 0.15.1 以降を使いましょう。

haml-lint とは

haml-lint とは、HAMLのlintツールです。HAML自体の検査はもちろんのこと、Rubocopと連携し、HAML内にあるRubyコードについても検査します。

Misoca開発チームでは、レビュー効率を上げるためと、メンテナンス性を向上するために、積極的にlintツールを導入しています。 現在もhaml-lintを通らないコードはCIを通過できない設定になっています。

遭遇した誤検知

haml-lint 0.15.0 は以下のコードに対して、next を用いて書き直すよう指示する警告を出力します。(Rubocopの Sytle/Next ルールによるもの)

  - [1, 2, 3].each do |value|
    %div
      - if value == 0
        %div
        %div
        %div

-# 出力:
-# <div></div>
-# <div></div>
-# <div></div>
foo.haml:1 [W] RuboCop: Use `next` to skip iteration.

しかし、この警告に従って書き直すと、以下のように出力が変化してしまいます。

  - [1, 2, 3].each do |value|
    %div
      - next unless value == 0
      %div
      %div
      %div

-# 出力:
-# <div>
-# <div>
-# <div>

そのため、haml-lintに従ってコードを書き直した結果、いくつかの画面で表示くずれが発生するようになってしまいました。

原因

haml-lint はRubyコードの検査するために、HAMLからRubyコードを抽出してRubocopに渡します。

上記のHAMLから抽出されるRubyコードは以下のようになっていました。(0.15.0時点)

[1, 2, 3].each do
  puts # <div> の出力に対応するダミーのputs
  if value == 0
    puts # 同上
    puts # 同上
    puts # 同上
  end
end

しかし、これは一つ目の div タグの閉じタグの出力が省略されてしまっており、不正確なRubyコードです。 この不正確性が元で誤った警告が出力されていました。

解決方法

HAMLからRubyコードを抽出する箇所を修正すれば上記の問題は解決できます。 そこで、該当箇所を修正し、Pull requestを送りました。( brigade/haml-lint #92) これを適用すると、上記のHAMLから抽出されるRubyコードは以下のようになります。

[1, 2, 3].each do
  puts # <div> の出力に対応するダミーのputs
  if value == 0
    puts # <div>の出力に対応するダミーのputs
    puts # </div> の出力に対応するダミーのputs
    puts # 同上
    puts # 同上
    puts # 同上
    puts # 同上
  end
  puts # </div> の出力に対応するダミーのputs
end

すでにマージされているため、 0.15.1 以降でこの問題は修正されています。

まとめ

  • lintツールを積極的に導入していきたい
  • haml-lint 0.15.0 には Style/Next の誤検知する不具合がある
  • haml-lint 0.15.1 では直りました