Ruby用簡易コーディングルールチェッカーを作る
こんにちは、技術推進室の篠崎です。
現在、RailsのプロジェクトでRuboCopを利用してコーディングルールのチェックを行っています。
RuboCopをもっと知るために簡易版のコーディングルールチェッカー(以後簡易チェッカー)を作成してみました。
今回は簡易チェッカーのご紹介をさせて頂きたいと思います。
簡易版コーディングルールチェッカー
インスタンスメソッド名が「aaa」と「bbb」になっているかをチェックします。
こんなSampleクラスに対して実行すると
class Sample
def aaa(num)
num * 2
end
def bbb(num)
num + 2
end
end
こんな感じで行数とエラーメッセージを表示するものです。
$ ./sample_checker sample.rb 2: aaaというメソッド名を利用してはだめ! 6: bbbというメソッド名を利用してはだめ!
ソースはここ
試したバージョン
ruby- 2.1.1p76parser- 2.1.9
処理
簡易チェッカーは以下の順番で処理をします。
- ソース解析
- チェック実施
- 結果出力
※ RuboCopは「1. ソース解析」前にオプション解析を実施していますが基本は同じ順番です
ソース解析
ソースの解析にparserを利用します。
$ gem install parser
※ RuboCopもこれを利用しています
引数で指定されたソースコードをASTに変換します。
source_buffer = Parser::Source::Buffer.new('(string)')
source_buffer.source = File.read(ARGV[0])
parser = Parser::CurrentRuby.new
ast = parser.parse(source_buffer)
チェック実施
Parser::AST::Processorを継承したクラスSampleProcessorを作成します
このクラスのproccessメソッドに先ほど変換したASTを引数に渡して呼ぶとnode毎にon_xxxというメソッドを呼び出してくれるのでそこでルールチェックを行います。
processor = SampleProcessor.new processor.process(ast)
今回はインスタンスメソッド名のチェックなのでon_defを実装します。
class SampleProcessor < Parser::AST::Processor
attr_reader :errors
def initialize
@errors = []
end
def on_def(node)
method_name, _other = *node
if method_name.to_s == 'aaa'
@errors << "#{node.loc.line}: aaaというメソッド名を利用してはだめ!"
end
if method_name.to_s == 'bbb'
@errors << "#{node.loc.line}: bbbというメソッド名を利用してはだめ!"
end
end
end
結果出力
結果は@errorsに入っているのでそれを出力するだけです
processor.errors.each { |error| puts error }
最後に
本当に簡単なコーディングルール(とよんでいいのかどうかも怪しい)チェッカーができました。
が、実際に運用するとなると
- ファイルが存在しなかったらどうするの?
- 複数ファイル対応したい
- Syntax間違えたらどうするの?
- 規約毎にクラス分けたい
- 自動で修正してほしい!
とか数え切れない課題、要望が出てくることかと思いますが、RuboCopならばほとんどの要望に対応してくれています(はず)
ので大人しくRuboCopを利用しましょうw
あと、こんなお役だち情報がありますよ! > RuboCopのCustom Copを作る
以上