DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Code Reports Rake Task

03.30.2009
| 3443 views |
  • submit to reddit
        Will run various Ruby Gems for creating code quality reports, store them in public/ in your Rails app, and create public/reports.html with links to each report.  You need <a href="http://saikuro.rubyforge.org/">Saikuro</a>, <a href="http://ruby.sadi.st/Flog.html">Flog</a>, <a href="http://ruby.sadi.st/Flay.html">Flay</a>, <a href="http://github.com/kevinrutherford/reek/tree/master">Reek</a>, and <a href="http://github.com/martinjandrews/roodi/tree/master">Roodi</a>, since this Rake task uses them all.

Save this Rake task in your lib/tasks/ directory in your Rails app, and give it the extension .rake so that you can then run 'rake metrics:make_all'.

namespace :metrics do
  def get_mtime(path)
    File.mtime(path).strftime("%Y-%m-%d %I:%M %p")
  end
  
  desc 'Generates Reek report'
  task :make_reek do
    require 'find'
    require 'fileutils'
    reek_dir_name = "reek"
    reek_dir = "#{RAILS_ROOT}/public/#{reek_dir_name}"
    index_file = "#{reek_dir}/index.html"
    output_files = {}
    
    unless File.exists?(reek_dir) && File.directory?(reek_dir)
      FileUtils.mkdir(reek_dir)
    end
    
    Find.find(RAILS_ROOT) do |path|
      if (
        (path =~ /#{RAILS_ROOT}\/app\// || path =~ /#{RAILS_ROOT}\/lib\//) &&
        path =~ /\.rb$/i
      )
        output_file = "#{File.basename(path)}.txt"
        cmd = "reek #{path} > #{reek_dir}/#{output_file}"
        puts cmd
        system(cmd)
        output_files[path] = output_file
      end
    end
    
    puts "Writing index file to #{index_file}..."
    paths = output_files.keys.sort
    
    File.open(index_file, 'w') do |file|
      file.write('<html>')
      file.write('<head>')
      file.write("<title>Reek Results for #{RAILS_ROOT}</title>")
      file.write('</head>')
      file.write('<body>')
      file.write("<h1>Reek Results for #{RAILS_ROOT}</h1>")
      file.write('<ol>')

      paths.each do |path|
        name = output_files[path]
        file.write('<li>')
        link_name = File.basename(name, '.rb.txt')
        file.write('<a href="' + name + '">' + link_name + '</a>')
        file.write(' from ' + path)
        file.write("</li>\n")
      end

      file.write('</ol>')
      file.write('</body>')
      file.write('</html>')
    end
  end

  desc 'Generates public/reports.html'
  task :make_index do
    require 'find'
    require 'fileutils'
    puts "\nGenerating index of reports..."
    reports = []
    index_file = "#{RAILS_ROOT}/public/reports.html"
    
    Find.find(RAILS_ROOT + '/public') do |path|
      if (
        path =~ /flay_report\.txt$/ ||
        path =~ /flog_report\.txt$/ ||
        path =~ /roodi_report\.txt$/
      )
        reports << File.basename(path)
      end
    end
    
    File.open(index_file, 'w') do |file|
      file.write('<html>')
      file.write('<head>')
      file.write("<title>Reports for #{RAILS_ROOT}</title>")
      file.write('</head>')
      file.write('<body>')
      file.write("<h1>Reports for #{RAILS_ROOT}</h1>")
      file.write('<ol>')

      reek_file = "#{RAILS_ROOT}/public/reek/index.html"
      if File.exists?(reek_file)
        file.write('<li><a href="reek/index.html">Reek</a>')
        file.write(", last updated #{get_mtime(reek_file)}</li>")
      end

      token_file = "#{RAILS_ROOT}/public/saikuro/index_token.html"
      if File.exists?(token_file)
        file.write('<li><a href="saikuro/index_token.html">Tokens</a>')
        file.write(", last updated #{get_mtime(token_file)}</li>")
      end

      cyclo_file = "#{RAILS_ROOT}/public/saikuro/index_cyclo.html"
      if File.exists?(cyclo_file)
        file.write('<li><a href="saikuro/index_cyclo.html">Cyclomatic complexity</a>')
        file.write(", last updated #{get_mtime(cyclo_file)}</li>")
      end

      reports.each do |name|
        file.write('<li>')
        file.write('<a href="' + name + '">' + name + '</a>')
        file.write(", last updated #{get_mtime(RAILS_ROOT + '/public/' + name)}")
        file.write('</li>')
      end

      file.write('</ol>')
      file.write('</body>')
      file.write('</html>')
    end
  end

  desc 'Generates Roodi report'
  task :make_roodi do 
    puts "\nGenerating Roodi report..."
    cmd = "roodi \"#{RAILS_ROOT}/**/*.rb\" > #{RAILS_ROOT}/public/roodi_report.txt"
    puts cmd
    system(cmd)
  end

  desc 'Generates Flay report'
  task :make_flay do
    puts "\nGenerating Flay report..."
    cmd = "flay #{RAILS_ROOT}/app/ > #{RAILS_ROOT}/public/flay_report.txt"
    puts cmd
    system(cmd)
  end

  desc 'Generates Saikuro report'
  task :make_saikuro do
    saikuro_dir = "#{RAILS_ROOT}/public/saikuro/"
    unless File.exists?(saikuro_dir) && File.directory?(saikuro_dir)
      FileUtils.mkdir(saikuro_dir)
    end
    
    puts "\nGenerating Saikuro report..."
    cmd = "saikuro -c -t -i #{RAILS_ROOT}/app/ -y 0 -w 11 -e 16 -o #{saikuro_dir}"
    puts cmd
    system(cmd)
  end

  desc 'Generates Flog report'
  task :make_flog do
    puts "\nGenerating Flog report..."
    cmd = "flog #{RAILS_ROOT}/app/ > #{RAILS_ROOT}/public/flog_report.txt"
    puts cmd
    system(cmd)
  end

  desc 'Generates all reports.'
  task :make_all do
    system('rake metrics:make_reek')
    system('rake metrics:make_roodi')
    system('rake metrics:make_flay')
    system('rake metrics:make_saikuro')
    system('rake metrics:make_flog')
    system('rake metrics:make_index')
  end
end