rake notes で TODO が増え過ぎたら CI で検知できるように拡張する

Rails アプリから機能を gem 化する方法の実例を1つ公開してみる。

sinsoku.hatenablog.com

rake notes を拡張する

rake notesRails アプリ内の "OPTIMIZE|FIXME|TODO" を一覧表示できるが、これを拡張する。

ソースコードの探し方

  1. rails/railsリポジトリをローカルに git clone して、 git grep :notes する
  2. annotations.rake が見つかる
  3. git grep "class SourceAnnotationExtractor" する
  4. source_annotation_extractor.rb が見つかる

パッチを書く

lib/rails_notes_validation/lib/rails_notes_validation.rb

# frozen_string_literal: true
class SourceAnnotationExtractor
  module MaxSizeValidation
    def display(results, options = {})
      super

      annotations = results.values.flatten
      display_annotations(annotations)
      display_failed_if_exceed(annotations)
    end

    private

    def display_annotations(annotations)
      puts 'Result'
      tag_and_size = annotations.group_by(&:tag).map { |tag, arr| [tag, arr.size] }
      tag_and_size.sort_by(&:last).reverse_each do |e|
        tag, size = e
        puts "  * [#{tag}] #{size}"
      end
      puts
      puts "Total"
      puts "  * [#{tag}] #{annotations.size}"
    end

    def display_failed_if_exceed(annotations)
      max_size = ENV['SOURCE_ANNOTATION_MAX_SIZE'].to_i
      exceed_size = annotations.size - max_size
      if exceed_size.positive?
        puts
        puts "Failed: #{exceed_size} notes exceed. [#{annotations.size}/#{max_size}]"
        exit 1
      end
    end
  end
  SourceAnnotationExtractor.prepend(MaxSizeValidation)
end

動かしてみる

$ rake notes
app/models/user.rb
  * [10] [TODO] Fix me

Result
  * [TODO] 1

Total
  * [OPTIMIZE|FIXME|TODO] 1

Failed: 1 notes exceed. [1/0]
$ echo $?
1

これで終了コードが 1 になるので、 CI で実行させれば fail になる。

おわり

gem にするまでもないコードとか、公開前の動作確認とか、そういうので便利ですよ。