| # 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 <code>checkstyle:html</code> and <code>checkstyle:xml</code> tasks. |
| # Require explicitly using <code>require "buildr/checkstyle"</code>. |
| module Checkstyle |
| |
| class << self |
| |
| # The specs for requirements |
| def dependencies |
| %w( |
| com.puppycrawl.tools:checkstyle:jar:6.12.1 |
| org.antlr:antlr4-runtime:jar:4.5.1-1 |
| antlr:antlr:jar:2.7.7 |
| com.google.guava:guava:jar:18.0 org.apache.commons:commons-lang3:jar:3.4 |
| org.abego.treelayout:org.abego.treelayout.core:jar:1.0.1 |
| commons-cli:commons-cli:jar:1.3 |
| commons-beanutils:commons-beanutils-core:jar:1.8.3 |
| commons-logging:commons-logging:jar:1.1.1 |
| ) |
| end |
| |
| def checkstyle(configuration_file, format, output_file, source_paths, options = {}) |
| dependencies = self.dependencies + (options[:dependencies] || []) |
| cp = Buildr.artifacts(dependencies).each { |a| a.invoke if a.respond_to?(:invoke) }.map(&:to_s) |
| |
| args = [] |
| if options[:properties_file] |
| args << '-p' |
| args << options[:properties_file] |
| end |
| args << '-c' |
| args << configuration_file |
| args << '-f' |
| args << format |
| args << '-o' |
| args << output_file |
| args += source_paths.select { |p| File.exist?(p) } |
| |
| begin |
| Java::Commands.java 'com.puppycrawl.tools.checkstyle.Main', *(args + [{:classpath => cp, :properties => options[:properties], :java_args => options[:java_args]}]) |
| rescue Exception => e |
| raise e if options[:fail_on_error] |
| end |
| end |
| end |
| |
| class Config |
| def enabled? |
| File.exist?(self.configuration_file) |
| end |
| |
| def html_enabled? |
| File.exist?(self.style_file) |
| end |
| |
| attr_writer :config_directory |
| |
| def config_directory |
| @config_directory || project._(:source, :main, :etc, :checkstyle) |
| end |
| |
| attr_writer :report_dir |
| |
| def report_dir |
| @report_dir || project._(:reports, :checkstyle) |
| end |
| |
| attr_writer :configuration_file |
| |
| def configuration_file=(configuration_file) |
| raise 'Configuration artifact already specified' if @configuration_artifact |
| @configuration_file = configuration_file |
| end |
| |
| def configuration_file |
| if @configuration_file |
| return @configuration_file |
| elsif @configuration_artifact.nil? |
| "#{self.config_directory}/checks.xml" |
| else |
| a = Buildr.artifact(@configuration_artifact) |
| a.invoke |
| a.to_s |
| end |
| end |
| |
| def configuration_artifact=(configuration_artifact) |
| raise 'Configuration file already specified' if @configuration_file |
| @configuration_artifact = configuration_artifact |
| end |
| |
| def configuration_artifact |
| @configuration_artifact |
| end |
| |
| attr_writer :fail_on_error |
| |
| def fail_on_error? |
| @fail_on_error.nil? ? false : @fail_on_error |
| end |
| |
| attr_writer :format |
| |
| def format |
| @format || 'xml' |
| end |
| |
| attr_writer :xml_output_file |
| |
| def xml_output_file |
| @xml_output_file || "#{self.report_dir}/checkstyle.xml" |
| end |
| |
| attr_writer :html_output_file |
| |
| def html_output_file |
| @html_output_file || "#{self.report_dir}/checkstyle.html" |
| end |
| |
| attr_writer :style_file |
| |
| def style_file |
| unless @style_file |
| project_xsl = "#{self.config_directory}/checkstyle-report.xsl" |
| if File.exist?(project_xsl) |
| @style_file = project_xsl |
| else |
| @style_file = "#{File.dirname(__FILE__)}/checkstyle-report.xsl" |
| end |
| end |
| @style_file |
| end |
| |
| attr_writer :suppressions_file |
| |
| def suppressions_file |
| @suppressions_file || "#{self.config_directory}/suppressions.xml" |
| end |
| |
| attr_writer :import_control_file |
| |
| def import_control_file |
| @import_control_file || "#{self.config_directory}/import-control.xml" |
| end |
| |
| def properties |
| unless @properties |
| @properties = {:basedir => self.project.base_dir} |
| @properties['checkstyle.config.dir'] = self.config_directory if File.directory?(self.config_directory) |
| @properties['checkstyle.suppressions.file'] = self.suppressions_file if File.exist?(self.suppressions_file) |
| @properties['checkstyle.import-control.file'] = self.import_control_file if File.exist?(self.import_control_file) |
| end |
| @properties |
| end |
| |
| def source_paths |
| @source_paths ||= [self.project.compile.sources, self.project.test.compile.sources] |
| end |
| |
| def extra_dependencies |
| @extra_dependencies ||= [self.project.compile.dependencies, self.project.test.compile.dependencies].flatten |
| 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_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 checkstyle |
| @checkstyle ||= Buildr::Checkstyle::Config.new(project) |
| end |
| |
| after_define do |project| |
| if project.checkstyle.enabled? |
| desc 'Generate checkstyle xml report.' |
| project.task('checkstyle:xml') do |
| puts 'Checkstyle: Analyzing source code...' |
| mkdir_p File.dirname(project.checkstyle.xml_output_file) |
| Buildr::Checkstyle.checkstyle(project.checkstyle.configuration_file, |
| project.checkstyle.format, |
| project.checkstyle.xml_output_file, |
| project.checkstyle.complete_source_paths, |
| :properties => project.checkstyle.properties, |
| :fail_on_error => project.checkstyle.fail_on_error?, |
| :dependencies => project.checkstyle.complete_extra_dependencies) |
| end |
| |
| if project.checkstyle.html_enabled? |
| xml_task = project.task('checkstyle:xml') |
| desc 'Generate checkstyle html report.' |
| project.task('checkstyle:html' => xml_task) do |
| puts 'Checkstyle: Generating report' |
| mkdir_p File.dirname(project.checkstyle.html_output_file) |
| Buildr.ant 'checkstyle' do |ant| |
| ant.xslt :in => project.checkstyle.xml_output_file, |
| :out => project.checkstyle.html_output_file, |
| :style => project.checkstyle.style_file |
| end |
| end |
| |
| end |
| end |
| end |
| end |
| end |
| end |
| |
| class Buildr::Project |
| include Buildr::Checkstyle::ProjectExtension |
| end |