Ruby Code Quality and Metric_Fu

I’ve been putting together a continuous integration framework for my Ruby projects and was very pleased to find the great work by Jake Scruggs (http://metric-fu.rubyforge.org/ ) by the name of Metric_Fu. On the whole this aggregation of tools covers all the key ‘quality’ bases and generates some elegant graphical reports that can be simply published alongside other build artifacts in CruiseControl.rb for example. On the whole the installation is very simple, but I hit some issues with the code and had to apply some class method overrides to get it to work.

Inspector

My base environment is OSX 10.5.7, Ruby 1.8.6, Gem 1.3.3. I installed the gems jscruggs-metric_fu (1.1.1), rcov (0.8.1.2.0), flog (2.1.2), flay (1.3.0), reek (1.1.3), roodi (1.4.0) and Saikuro (1.1.0). Following the instructions at http://metric-fu.rubyforge.org/ I was complete in short order, and ran the rake task as per the example.

The first problem I hit was a method naming issue where the a Flog#flog_files method was being called which didn’t exist in the versions I was using. I ended up with a quick-n-dirty fix which involved amending the /gems/flog-2.1.2/bin/flog script to remove the call to flog_files, replacing it with the correct method name flog:

...
flogger = Flog.new options
flogger.flog ARGV
flogger.report
...

Second problem I hit was some floating point and divide-by-zero issue in the MetricFu::Generator#round_to_tenths method. I don’t profess to understand the core issue here, but the value of ‘NaN’ was appearing in the calculation – so I added a ‘very’ primitve override to filter this condition (elegance is not my middle name I you hadn’t realised already):

module MetricFu
  class Generator
    def round_to_tenths(decimal)
      decimal=0.0 if decimal.to_s.eql?('NaN')
      (decimal.to_i * 10).round / 10.0
    end
  end
end

Next I hit an issue with rcov not returning any results into the dashboard? I checked this out and located an error in the rcov.txt file generated as part of the execution. This simply informed me that the rcov commandline generated within the metric_fu rcov generator class was incorrect. After a little experimentation I worked out that the –include-file parameter was the issue…so I again redefined the problematic class method in my Rakefile to remove this issue:

Module MetricFu
  class Rcov
    def emit
      begin
        FileUtils.rm_rf(MetricFu::Rcov.metric_directory, :verbose => false)
        Dir.mkdir(MetricFu::Rcov.metric_directory)
        test_files = FileList[*MetricFu.rcov[:test_files]].join(' ')
        rcov_opts = MetricFu.rcov[:rcov_opts].join(' ')
        output = ">> #{MetricFu::Rcov.metric_directory}/rcov.txt"
        #PROBLEM: `rcov --include-file #{test_files}  #{rcov_opts} #{output}`
        `rcov #{test_files}  #{rcov_opts} #{output}`
      rescue LoadError
        if RUBY_PLATFORM =~ /java/
          puts 'running in jruby - rcov tasks not available'
        else
          puts 'sudo gem install rcov # if you want the rcov tasks'
        end
      end
    end
  end
end

Next I hit a problem when modifying my declared MetricFu::Configuration object to change the location of the outputs of the analysis, to reduce the pollution in my project folder hierarchy (yep…I probably do have some deeper issues). I had added the following lines to the sample provide by Jake:

MetricFu::Configuration.run do |config|
  config.base_directory = ENV['CC_BUILD_ARTIFACTS'] || 'quality'
  config.scratch_directory = File.join(config.base_directory, 'scratch')
  config.output_directory = File.join(config.base_directory, 'output')
  config.data_directory = File.join(config.base_directory, '_data')
  etc

With this new folder structure I also had to add a tweek to the Saikuro configuration entry in the same sample, to make sure the Saikuro outputs are picked up by the report aggregator. Without this tweek I was just getting a blank Saikuro template page offered by Metric_Fu:

(Ignore the space between the colon and the ‘o’ – it’s giving me smilies for some reason)

config.saikuro  = { : output_directory => 
                              File.join(config.scratch_directory, 'saikuro'), 

This change caused a failure in the MetricFu::Graph#generate method – which on closer inspection appeared to be hardwired in expecting a depth of 3 folders in the locations specified for these outputs? So again I re-declared this class in my Rakefile to make the specific change necessary to support any level of nesting. This fixed the problem and my folder feng-shui returned to equilibrium…mmmmmmm.

Module MetricFu
  class Graph
    def generate
      puts "Generating graphs"
      Dir[File.join(MetricFu.data_directory, '*.yml')].sort.each do |metric_file|
        puts "Generating graphs for #{metric_file}"
        #PROBLEM: date = metric_file.split('/')[3].split('.')[0]
        date = metric_file.split('/').last.split('.')[0]
        metrics = YAML::load(File.open(metric_file))
        self.clazz.each do |grapher|
          grapher.get_metrics(metrics, date)
        end
      end
      self.clazz.each do |grapher|
        grapher.graph!
      end
    end
  end
end

So my installation of metric_fu works perfectly now and I’m very impressed with the output it’s providing so long as I don’t dwell too much on the fact that it’s telling me my code quality is somewhere between criminal and insane !!!

I hope these notes may help others experiencing similar frustration in trying to get the install working…and again my thanks to Jake Scruggs for this piece of goodness.

Cheers all !

About these ads

5 Responses to Ruby Code Quality and Metric_Fu

  1. Jake Scruggs says:

    Thanks for the write up and pointing out some problems. I pulled in your fix for rcov and released a new version of metric_fu (1.1.2) a few minutes ago. As to Flog, I recommend using 2.1.0 until the problems with 2.1.2 get worked out. Can you get me a failing test that produces the ‘NaN’ you reference above. I can’t figure out how that happens.

    thanks again,
    -Jake

  2. [...] Ruby Code Quality and Metric_Fu – Some notes on getting the current metric_fu to run properly. [...]

  3. [...] complete you’re now ready to play with Metric_Fu. For more information on next steps refer to this article about some more version specific fixes or Jakes Metric_fu [...]

  4. [...] Scratch that, it doesn’t entirely fix the issue. I’ve also implemented Stew Welbourne’s hack for round_to_tenths(decimal) in MetricFu but that too does not seem to be a complete solution. The [...]

  5. I’ve been searching for this precise info on this subject for a while.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: