# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with this # work for additional information regarding copyright ownership. The ASF # licenses this file to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. module Buildr # Provides the findbugs:html and findbugs:xml tasks. # Require explicitly using require "buildr/findbugs". module Findbugs class << self # The specs for requirements def dependencies [ 'com.google.code.findbugs:findbugs-ant:jar:1.3.9', 'com.google.code.findbugs:findbugs:jar:1.3.9', 'com.google.code.findbugs:bcel:jar:1.3.9', 'com.google.code.findbugs:jsr305:jar:1.3.9', 'com.google.code.findbugs:jFormatString:jar:1.3.9', 'com.google.code.findbugs:annotations:jar:1.3.9', 'dom4j:dom4j:jar:1.6.1', 'jaxen:jaxen:jar:1.1.1', 'jdom:jdom:jar:1.0', 'xom:xom:jar:1.0', 'com.ibm.icu:icu4j:jar:2.6.1', 'asm:asm:jar:3.1', 'asm:asm-analysis:jar:3.1', 'asm:asm-tree:jar:3.1', 'asm:asm-commons:jar:3.1', 'asm:asm-util:jar:3.1', 'asm:asm-xml:jar:3.1', 'commons-lang:commons-lang:jar:2.4' ] end def findbugs(output_file, source_paths, analyze_paths, options = { }) dependencies = (options[:dependencies] || []) + self.dependencies cp = Buildr.artifacts(dependencies).each { |a| a.invoke() if a.respond_to?(:invoke) }.map(&:to_s).join(File::PATH_SEPARATOR) args = { :output => "xml:withMessages", :outputFile => output_file, :effort => 'max', :pluginList => '', :classpath => cp, :timeout => "90000000", :debug => "false" } args[:failOnError] = true if options[:fail_on_error] args[:excludeFilter] = options[:exclude_filter] if options[:exclude_filter] args[:jvmargs] = options[:java_args] if options[:java_args] Buildr.ant('findBugs') do |ant| ant.taskdef :name =>'findBugs', :classname =>'edu.umd.cs.findbugs.anttask.FindBugsTask', :classpath => cp ant.findBugs args do source_paths.each do |source_path| ant.sourcePath :path => source_path.to_s end Buildr.artifacts(analyze_paths).each(&:invoke).each do |analyze_path| ant.auxAnalyzePath :path => analyze_path.to_s end if options[:properties] options[:properties].each_pair do |k, v| ant.systemProperty :name => k, :value => v end end if options[:extra_dependencies] ant.auxClasspath do |aux| Buildr.artifacts(options[:extra_dependencies]).each { |a| a.invoke() if a.respond_to?(:invoke) }.each do |dep| aux.pathelement :location => dep.to_s end end end end end end end class Config attr_accessor :enabled def enabled? !!@enabled end def html_enabled? File.exist?(self.style_file) end attr_writer :config_directory def config_directory @config_directory || project._(:source, :main, :etc, :findbugs) end attr_writer :report_dir def report_dir @report_dir || project._(:reports, :findbugs) end attr_writer :fail_on_error def fail_on_error? @fail_on_error.nil? ? false : @fail_on_error end attr_writer :xml_output_file def xml_output_file @xml_output_file || "#{self.report_dir}/findbugs.xml" end attr_writer :html_output_file def html_output_file @html_output_file || "#{self.report_dir}/findbugs.html" end attr_writer :style_file def style_file @style_file || "#{self.config_directory}/findbugs-report.xsl" end attr_writer :filter_file def filter_file @filter_file || "#{self.config_directory}/filter.xml" end def properties @properties ||= { } end attr_writer :java_args def java_args @java_args || "-server -Xss1m -Xmx800m -Duser.language=en -Duser.region=EN " end def source_paths @source_paths ||= [self.project.compile.sources, self.project.test.compile.sources] end def analyze_paths @analyze_path ||= [self.project.compile.target] end def extra_dependencies @extra_dependencies ||= [self.project.compile.dependencies, self.project.test.compile.dependencies] end protected def initialize(project) @project = project end attr_reader :project end module ProjectExtension include Extension def findbugs @findbugs ||= Buildr::Findbugs::Config.new(project) end after_define do |project| if project.findbugs.enabled? desc "Generate findbugs xml report." project.task("findbugs:xml") do puts "Findbugs: Analyzing source code..." mkdir_p File.dirname(project.findbugs.xml_output_file) options = { :properties => project.findbugs.properties, :fail_on_error => project.findbugs.fail_on_error?, :extra_dependencies => project.findbugs.extra_dependencies } options[:exclude_filter] = project.findbugs.filter_file if File.exist?(project.findbugs.filter_file) Buildr::Findbugs.findbugs(project.findbugs.xml_output_file, project.findbugs.source_paths.flatten.compact, project.findbugs.analyze_paths.flatten.compact, options) end if project.findbugs.html_enabled? xml_task = project.task("findbugs:xml") desc "Generate findbugs html report." project.task("findbugs:html" => xml_task) do puts "Findbugs: Generating report" mkdir_p File.dirname(project.findbugs.html_output_file) Buildr.ant "findbugs" do |ant| ant.style :in => project.findbugs.xml_output_file, :out => project.findbugs.html_output_file, :style => project.findbugs.style_file end end end end end end end end class Buildr::Project include Buildr::Findbugs::ProjectExtension end