Edited at

simplecovで生成されるhtmlレポートからcsvを作る開発用rake taskの作成

More than 3 years have passed since last update.


経緯

coverage率を追って、どれだけの変化があったか等を記録していくのに、htmlではやりづらさがかなりあった。

csvに出力したりする方法を探してみたものの、思うようなものが発見できなかったので自分で実装してみた。

コードは汚いし、本当ならgemのメソッドのどこかにhookして、htmlでなく、ちゃんとデータからcsvを作成できるようにすべきだが、時間がなかったので、このようなコーディングをした。

誰かもっといい方法を知っていたら教えて欲しい!!


使い方

1. $> bundle exec rake dev:make_csv_from_coverage_html:create

2. コマンド入力を要求されるので、生成元になるhtmlのpathを入力

3. 保存先と保存ファイル名をコマンド入力

4. DONE


ソースコード


make_csv.rb

namespace :dev do

namespace :make_csv_from_coverage_html do
desc "make csv from coverage html file"
task :create => :environment do

# 元になるhtmlファイルをpathで指定
# コマンド入力で取ってこれるようにしてある
print("Input coverage html file path : ")
open_file_path = STDIN.gets
open_file_path = open_file_path.chomp
coverage_file = open("#{open_file_path}")

header = []
row_data = []
coverage_file.each do |line|
if line.include?("table class=\"file_list\"")
while l = coverage_file.gets
if l.include?('<th>')
header << l.strip.delete('<th>').delete('</th>')
elsif l.include?('</tr>')
break
end
end
end

if line.include?('<tr>')
row = []
while l = coverage_file.gets
if l.include?('<td')
l = l.strip

if l.include?('href')
# file名
match_str = l.match('title')
post_str = match_str.post_match
match_str2 = post_str.match("\">")
post_str2 = match_str2.post_match
match_str3 = post_str2.match('</a></td>')
row << match_str3.pre_match
elsif l.include?("\">")
# coverage %
match_str = l.match("\">")
post_str = match_str.post_match
row << post_str.delete('</td>')
else
# others
row << l.strip.delete('<td>').delete('</td>')
end
end

if l.include?('</tr>')
break
end
end
row_data << row
end

if line.include?('</table>')
break
end
end

csv_data = CSV.generate do |csv|
csv << header
row_data.each do |row|
csv << row
end
end

# 保存先もコマンド入力で自分で指定できるようにした
print("\n Input coverage csv file path after saving\n For Example coverage/csv/coverage_#{Date.today}.csv \n")
save_file_path = STDIN.gets
save_file_path = save_file_path.chomp
File.open("#{save_file_path}", "w") do |file|
file.write(csv_data)
end
end
end
end