Skip to content

Instantly share code, notes, and snippets.

@r10r
Created July 29, 2013 21:01
Show Gist options
  • Select an option

  • Save r10r/6107794 to your computer and use it in GitHub Desktop.

Select an option

Save r10r/6107794 to your computer and use it in GitHub Desktop.

Revisions

  1. r10r revised this gist Jul 29, 2013. 1 changed file with 15 additions and 0 deletions.
    15 changes: 15 additions & 0 deletions reek.rake
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    require 'reek/rake/task'
    require 'syspect/rspec/reek_checkstyle_formatter'

    Reek::Rake::Task.new do |t|
    t.fail_on_error = false
    t.reek_opts = '-y -n'
    end

    namespace :reek do
    desc 'Generate checkstyle report for code smells analyzed by reek.'
    task :checkstyle do
    # see https://github.com/troessner/reek/wiki/Basic-Smell-Options
    ReekCheckstyleFormatter.new.run
    end
    end
  2. r10r created this gist Jul 29, 2013.
    91 changes: 91 additions & 0 deletions reek_checkstyle_formatter.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,91 @@
    require 'reek/source/source_locator'
    require 'reek/examiner'
    require 'rexml/document'
    require 'pathname'

    class ReekCheckstyleFormatter
    REXML_PRETTY_PRINT_INDENT = 0

    class << self
    attr_accessor :glob_pattern, :output, :smell_doc_url, :skip_disabled, :project_dir
    end

    @glob_pattern = 'lib/**/*.rb'
    @output = 'spec/reports/reek_checkstyle.xml'
    @smell_doc_url = 'https://github.com/troessner/reek/wiki'
    @skip_disabled = true
    @project_dir = Dir.pwd

    def initialize(options = {})
    @glob_pattern = options[:glob_pattern] || self.class.glob_pattern
    @output = options[:output] || self.class.output
    @smell_doc_url = options[:smell_doc_url] || self.class.smell_doc_url
    @skip_disabled = options[:skip_disabled] || self.class.skip_disabled
    @project_dir = options[:project_dir] || self.class.project_dir
    end

    def run
    files = Dir.glob(@glob_pattern)
    sources = Reek::Source::SourceLocator.new(files).all_sources
    examined_files = sources.map {|src| Reek::Examiner.new(src, []) }
    document = to_checkstyle(examined_files)
    Pathname.new(@output).dirname.mkpath
    File.open(@output, 'w+') do |file|
    document.write(file, REXML_PRETTY_PRINT_INDENT)
    end
    end

    def to_checkstyle(examined_files)
    REXML::Document.new.tap do |document_node|
    document_node << REXML::XMLDecl.new
    REXML::Element.new('checkstyle', document_node).tap do |checkstyle_node|
    examined_files.each do |examined_file|
    add_file(checkstyle_node, examined_file)
    end
    end
    end
    end

    def add_file(checkstyle_node, examined_file)
    if examined_file.smells.length > 0
    REXML::Element.new('file', checkstyle_node).tap do |file_node|
    file_node.attributes['name'] = File.join(@project_dir, examined_file.description)
    examined_file.smells.each do |smell|
    if smell.status['is_active']
    [*smell.location['lines']].each do |line|
    add_smell(file_node, smell, line)
    end
    end
    end
    end
    end
    end

    def add_smell(file_node, smell, line)
    REXML::Element.new('error', file_node).tap do |error|
    error.attributes['line'] = line
    error.attributes['column'] = 0
    error.attributes['severity'] = smell_severity(smell)
    error.attributes['message'] = smell_message(smell)
    #error.attributes['source'] = File.join(@project_dir, smell.source)
    end
    end

    def smell_message(smell)
    "<em>#{smell_anchor(smell)}</em> - #{smell.message}"
    end

    def smell_anchor(smell)
    url = smell_url(smell)
    "<a href='#{url}'>#{smell.smell['subclass']}</a>"
    end

    def smell_url(smell)
    smell_page_name = (smell.smell['subclass']).scan(/[A-Z][^A-Z]*/).join('-')
    [@smell_doc_url, smell_page_name].join("/")
    end

    def smell_severity(smell)
    'warning'
    end
    end