# 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
%w(
com.google.code.findbugs:findbugs:jar:3.0.0
com.google.code.findbugs:jFormatString:jar:3.0.0
com.google.code.findbugs:bcel-findbugs:jar:6.0
com.google.code.findbugs:annotations:jar:3.0.0
org.ow2.asm:asm-debug-all:jar:5.0.2
commons-lang:commons-lang:jar:2.6
dom4j:dom4j:jar:1.6.1
jaxen:jaxen:jar:1.1.6
)
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 => options[:output] || 'xml',
:outputFile => output_file,
:effort => 'max',
:pluginList => '',
:classpath => cp,
:reportLevel => options[:report_level] || 'medium',
: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]
mkdir_p File.dirname(output_file)
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
attr_writer :config_directory
def config_directory
@config_directory || project._(:source, :main, :etc, :findbugs)
end
attr_writer :report_level
def report_level
@report_level || 'medium'
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 :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].flatten.compact
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].flatten.compact
end
# An array of additional projects to scan for main and test sources
attr_writer :additional_project_names
def additional_project_names
@additional_project_names ||= []
end
def complete_source_paths
paths = self.source_paths.dup
self.additional_project_names.each do |project_name|
p = self.project.project(project_name)
paths << [p.compile.sources, p.test.compile.sources].flatten.compact
end
paths.flatten.compact
end
def complete_analyze_paths
paths = self.analyze_paths.dup
self.additional_project_names.each do |project_name|
paths << self.project.project(project_name).compile.target
end
paths.flatten.compact
end
def complete_extra_dependencies
deps = self.extra_dependencies.dup
self.additional_project_names.each do |project_name|
p = self.project.project(project_name)
deps << [p.compile.dependencies, p.test.compile.dependencies].flatten.compact
end
deps.flatten.compact
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...'
options =
{
:properties => project.findbugs.properties,
:fail_on_error => project.findbugs.fail_on_error?,
:extra_dependencies => project.findbugs.complete_extra_dependencies
}
options[:exclude_filter] = project.findbugs.filter_file if File.exist?(project.findbugs.filter_file)
options[:output] = 'xml:withMessages'
options[:report_level] = project.findbugs.report_level
Buildr::Findbugs.findbugs(project.findbugs.xml_output_file,
project.findbugs.complete_source_paths,
project.findbugs.complete_analyze_paths,
options)
end
desc 'Generate findbugs html report.'
project.task('findbugs:html') do
puts 'Findbugs: Analyzing source code...'
options =
{
:properties => project.findbugs.properties,
:fail_on_error => project.findbugs.fail_on_error?,
:extra_dependencies => project.findbugs.complete_extra_dependencies
}
options[:exclude_filter] = project.findbugs.filter_file if File.exist?(project.findbugs.filter_file)
options[:output] = 'html'
options[:report_level] = project.findbugs.report_level
Buildr::Findbugs.findbugs(project.findbugs.html_output_file,
project.findbugs.complete_source_paths,
project.findbugs.complete_analyze_paths,
options)
end
end
end
end
end
end
class Buildr::Project
include Buildr::Findbugs::ProjectExtension
end