pockestrap

Programmer's memo

RuboCopのカスタムCop gemを作るためのジェネレータを作った

github.com

これはなに

RuboCopのカスタムCop gemを作るためのジェネレータです。 rubocop-rspecなどのgemを作る時のひな型を生成します。

使い方

まず、gem installします。

$ gem install custom_cops_generator

そして、custom_cops_generatorコマンドを実行します。

$ custom_cops_generator rubocop-hello_world
Creating gem 'rubocop-hello_world'...
      create  rubocop-hello_world/Gemfile
      create  rubocop-hello_world/lib/rubocop/hello_world.rb
      create  rubocop-hello_world/lib/rubocop/hello_world/version.rb
      create  rubocop-hello_world/rubocop-hello_world.gemspec
      create  rubocop-hello_world/Rakefile
      create  rubocop-hello_world/README.md
      create  rubocop-hello_world/bin/console
      create  rubocop-hello_world/bin/setup
      create  rubocop-hello_world/.gitignore
Initializing git repo in /tmp/tmp.Gu7G94wX00/rubocop-hello_world
Gem 'rubocop-hello_world' was successfully created. For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html
create rubocop-hello_world/lib/rubocop-hello_world.rb
create rubocop-hello_world/lib/rubocop/hello_world/inject.rb
create rubocop-hello_world/lib/rubocop/cop/hello_world_cops.rb
create rubocop-hello_world/config/default.yml
create rubocop-hello_world/spec/spec_helper.rb
create rubocop-hello_world/.rspec
update lib/rubocop/hello_world.rb
update lib/rubocop/hello_world.rb
update lib/rubocop/hello_world/version.rb
update rubocop-hello_world.gemspec
update rubocop-hello_world.gemspec
update Rakefile
update Gemfile

It's done! You can start developing a new extension of RuboCop in rubocop-hello_world.
For the next step, you can use the cop generator.

  $ bundle exec rake 'new_cop[HelloWorld/SuperCoolCopName]'

今回はrubocop-hello_worldを作ってみました。 上のようにコマンドを実行するとrubocop-hello_worldディレクトリが作成され、その中にgemのひな型が作成されます。

ここに新しいCopを追加していくのは、上のコマンドの出力にも出ている通りbundle exec rake 'new_cop[HelloWorld/SuperCoolCopName]'を実行するだけです。 これを実行すると新規Copのテンプレートが生成されるので、それを編集するだけです。1

$ bundle exec rake new_cop[HelloWorld/SuperCoolCopName]
[create] lib/rubocop/cop/hello_world/super_cool_cop_name.rb
[create] spec/rubocop/cop/hello_world/super_cool_cop_name_spec.rb
[modify] A configuration for the cop is added into config/default.yml.
         If you want to disable the cop by default, set `Enabled` option to false.
Do 3 steps:
  1. Add an entry to the "New features" section in CHANGELOG.md,
     e.g. "Add new `HelloWorld/SuperCoolCopName` cop. ([@pocke][])"
  2. Modify the description of HelloWorld/SuperCoolCopName in config/default.yml
  3. Implement your new cop in the generated file!

実装方法

まずbundle gemコマンドでgemのひな型を生成しています。 その後にbundle gemが生成したひな型を更新したり、足りないファイルを追加したりしてひな型を作っています。

主な実装は次のファイルにあります。 https://github.com/pocke/custom_cops_generator/blob/e320a46c8b268508d2ca6ae0fdd1016c6b94e41a/lib/custom_cops_generator/generator.rb


RuboCopの拡張を簡単に作れるようになるcustom_cops_generator gemの紹介でした。


  1. 既知のバグとして、new_cop rake taskがlib/rubocop/cop/NAME_cops.rbrequire_relativeを追加しない、という物があります。そのため、new_cop taskの後に手動でこのファイルを編集し、require_relative './DEPARTMENT/NAME'などを追加する必要があります。これはおそらくRuboCop本体のバグではないかと予想しています。