lib/pmd/plugin.rb in danger-pmd-0.0.5 vs lib/pmd/plugin.rb in danger-pmd-0.1.0

- old
+ new

@@ -13,10 +13,15 @@ # # pmd.gradle_task = 'app:pmd' #defalut: pmd # pmd.report_file = "app/build/reports/pmd/pmd.xml" # pmd.report # + # @example Running PMD with an array of report files + # + # pmd.report_files = ["modules/**/build/reports/pmd/pmd.xml", "app/build/reports/pmd/pmd.xml"] + # pmd.report + # # @example Running PMD without running a Gradle task # # pmd.skip_gradle_task = true # pmd.report # @@ -24,125 +29,141 @@ # @tags java, android, pmd class DangerPmd < Plugin require_relative "./pmd_file" - # Custom Gradle module to run. - # This is useful when your project has different flavors. - # Defaults to "app". - # @return [String] - attr_writer :gradle_module - # Custom Gradle task to run. # This is useful when your project has different flavors. # Defaults to "pmd". # @return [String] attr_writer :gradle_task - # Location of report file - # If your pmd task outputs to a different location, you can specify it here. - # Defaults to "build/reports/pmd/pmd.xml". + # A getter for `gradle_task`, returning "pmd" if value is nil. # @return [String] - attr_writer :report_file + def gradle_task + @gradle_task ||= "pmd" + end - # Skip Gradle task + # Skip Gradle task. # If you skip Gradle task, for example project does not manage Gradle. + # Defaults to `false`. # @return [Bool] attr_writer :skip_gradle_task - GRADLEW_NOT_FOUND = "Could not find `gradlew` inside current directory" - REPORT_FILE_NOT_FOUND = "PMD report not found" + # A getter for `skip_gradle_task`, returning false if value is nil. + # @return [Boolean] + def skip_gradle_task + @skip_gradle_task ||= false + end + # Location of report file. + # If your pmd task outputs to a different location, you can specify it here. + # Defaults to "app/build/reports/pmd/pmd.xml". + # @return [String] + attr_writer :report_file + + # A getter for `report_file`, returning "app/build/reports/pmd/pmd.xml" if value is nil. + # @return [String] + def report_file + @report_file ||= "app/build/reports/pmd/pmd.xml" + end + + # Location of report files. + # If your pmd task outputs to a different location, you can specify it here. + # Defaults to "app/build/reports/pmd/pmd.xml". + # @return [Array[String]] + attr_writer :report_files + + # A getter for `report_files`, returning ["app/build/reports/pmd/pmd.xml"] if value is nil. + # @return [Array[String]] + def report_files + @report_files ||= [report_file] + end + # Calls PMD task of your Gradle project. # It fails if `gradlew` cannot be found inside current directory. # It fails if `report_file` cannot be found inside current directory. - # @return [void] + # It fails if `report_files` is empty. + # @return [Array[PmdFile]] def report(inline_mode = true) unless skip_gradle_task - return fail(GRADLEW_NOT_FOUND) unless gradlew_exists? + return fail("Could not find `gradlew` inside current directory") unless gradlew_exists? exec_gradle_task end - return fail(REPORT_FILE_NOT_FOUND) unless report_file_exist? + report_files_flatten = [] + report_files.each do |report_file| + Dir.glob(report_file).sort.each do |report_file_glob| + return fail("PMD report file not found #{report_file_glob}") unless report_file_exist?(report_file_glob) - if inline_mode - send_inline_comment + report_files_flatten.push(report_file_glob) + end end - end - # A getter for `gradle_module`, returning "app" if value is nil. - # @return [String] - def gradle_module - @gradle_module ||= "app" + report_and_send_inline_comment(report_files_flatten, inline_mode) end - # A getter for `gradle_task`, returning "pmd" if value is nil. - # @return [String] - def gradle_task - @gradle_task ||= "pmd" - end + private - # A getter for `skip_gradle_task`, returning false if value is nil. - # @return [Boolean] - def skip_gradle_task - @skip_gradle_task ||= false + # Check gradlew file exists in current directory. + # @return [Bool] + def gradlew_exists? + !`ls gradlew`.strip.empty? end - # A getter for `report_file`, returning "app/build/reports/pmd/pmd.xml" if value is nil. - # @return [String] - def report_file - @report_file ||= "app/build/reports/pmd/pmd.xml" - end - - # A getter for current updated files - # @return [Array[String]] - def target_files - @target_files ||= (git.modified_files - git.deleted_files) + git.added_files - end - - # Run Gradle task + # Run Gradle task. # @return [void] def exec_gradle_task system "./gradlew #{gradle_task}" end - # Check gradlew file exists in current directory + # Check report_file exists in current directory. # @return [Bool] - def gradlew_exists? - !`ls gradlew`.strip.empty? - end - - # Check report_file exists in current directory - # @return [Bool] - def report_file_exist? + def report_file_exist?(report_file) File.exist?(report_file) end # A getter for `pmd_report`, returning PMD report. # @return [Oga::XML::Document] - def pmd_report + def pmd_report(report_file) require "oga" - @pmd_report ||= Oga.parse_xml(File.open(report_file)) + Oga.parse_xml(File.open(report_file)) end # A getter for PMD issues, returning PMD issues. # @return [Array[PmdFile]] - def pmd_issues - @pmd_issues ||= pmd_report.xpath("//file").map do |pmd_file| - PmdFile.new(gradle_module, pmd_file) + def pmd_issues(report_file) + pmd_report(report_file).xpath("//file").map do |pmd_file| + PmdFile.new(pmd_file) end end - # Send inline comment with Danger's warn or fail method - # @return [void] - def send_inline_comment - pmd_issues.each do |pmd_file| - next unless target_files.include? pmd_file.absolute_path + # A getter for current updated files. + # @return [Array[String]] + def target_files + @target_files ||= (git.modified_files - git.deleted_files) + git.added_files + end - pmd_file.violations.each do |pmd_violation| - send(pmd_violation.type, pmd_violation.description, file: pmd_file.absolute_path, line: pmd_violation.line) + # Generate report and send inline comment with Danger's warn or fail method. + # @return [Array[PmdFile]] + def report_and_send_inline_comment(report_files, inline_mode = true) + pmd_issues = [] + + report_files.each do |report_file| + pmd_issues(report_file).each do |pmd_file| + next unless target_files.include? pmd_file.absolute_path + + pmd_issues.push(pmd_file) + + next if inline_mode + + pmd_file.violations.each do |pmd_violation| + send(pmd_violation.type, pmd_violation.description, file: pmd_file.absolute_path, line: pmd_violation.line) + end end end + + pmd_issues end end end