This is an automated email from the ASF dual-hosted git repository. adangel pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-pmd-plugin.git
commit a4ec98393cf1a8db3dcfffc9cfa623481fd7ba83 Author: Andreas Dangel <adan...@apache.org> AuthorDate: Fri Dec 15 19:57:35 2017 +0100 [MPMD-246] Output details of processing errors Render processing errors in HTML report --- .../org/apache/maven/plugins/pmd/PmdReport.java | 1 + .../maven/plugins/pmd/PmdReportGenerator.java | 168 ++++++++++++++++----- src/main/resources/pmd-report.properties | 3 + src/main/resources/pmd-report_de.properties | 3 + .../apache/maven/plugins/pmd/PmdReportTest.java | 23 ++- 5 files changed, 151 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/pmd/PmdReport.java b/src/main/java/org/apache/maven/plugins/pmd/PmdReport.java index 9b63b9d..bfc149c 100644 --- a/src/main/java/org/apache/maven/plugins/pmd/PmdReport.java +++ b/src/main/java/org/apache/maven/plugins/pmd/PmdReport.java @@ -507,6 +507,7 @@ public class PmdReport PmdReportGenerator doxiaRenderer = new PmdReportGenerator( getLog(), sink, getBundle( locale ), aggregate ); doxiaRenderer.setFiles( filesToProcess ); doxiaRenderer.setViolations( renderer.getViolations() ); + doxiaRenderer.setProcessingErrors( renderer.getErrors() ); try { diff --git a/src/main/java/org/apache/maven/plugins/pmd/PmdReportGenerator.java b/src/main/java/org/apache/maven/plugins/pmd/PmdReportGenerator.java index 54fa04f..152064a 100644 --- a/src/main/java/org/apache/maven/plugins/pmd/PmdReportGenerator.java +++ b/src/main/java/org/apache/maven/plugins/pmd/PmdReportGenerator.java @@ -29,13 +29,15 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.ResourceBundle; - -import net.sourceforge.pmd.RuleViolation; +import java.util.Set; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.plugin.logging.Log; import org.codehaus.plexus.util.StringUtils; +import net.sourceforge.pmd.Report.ProcessingError; +import net.sourceforge.pmd.RuleViolation; + /** * Render the PMD violations into Doxia events. * @@ -52,7 +54,9 @@ public class PmdReportGenerator private ResourceBundle bundle; - private HashSet<RuleViolation> violations = new HashSet<>(); + private Set<RuleViolation> violations = new HashSet<>(); + + private List<ProcessingError> processingErrors = new ArrayList<>(); private boolean aggregate; @@ -86,6 +90,16 @@ public class PmdReportGenerator return new ArrayList<>( violations ); } + public void setProcessingErrors( Collection<ProcessingError> errors ) + { + this.processingErrors = new ArrayList<>( errors ); + } + + public List<ProcessingError> getProcessingErrors() + { + return processingErrors; + } + // public List<Metric> getMetrics() // { // return metrics; @@ -96,26 +110,46 @@ public class PmdReportGenerator // this.metrics = metrics; // } - private void startFileSection( String currentFilename, PmdFileInfo fileInfo ) + private String shortenFilename( String filename, PmdFileInfo fileInfo ) { - sink.section2(); - sink.sectionTitle2(); - - // prepare the filename - this.currentFilename = currentFilename; + String result = filename; if ( fileInfo != null && fileInfo.getSourceDirectory() != null ) { - this.currentFilename = - StringUtils.substring( currentFilename, fileInfo.getSourceDirectory().getAbsolutePath().length() + 1 ); + result = + StringUtils.substring( result, fileInfo.getSourceDirectory().getAbsolutePath().length() + 1 ); } - this.currentFilename = StringUtils.replace( this.currentFilename, "\\", "/" ); + result = StringUtils.replace( result, "\\", "/" ); - String title = this.currentFilename; if ( aggregate && fileInfo != null && fileInfo.getProject() != null ) { - title = fileInfo.getProject().getName() + " - " + this.currentFilename; + result = fileInfo.getProject().getName() + " - " + result; } - sink.text( title ); + + return result; + } + + private PmdFileInfo determineFileInfo( String filename ) throws IOException + { + File canonicalFilename = new File( filename ).getCanonicalFile(); + PmdFileInfo fileInfo = files.get( canonicalFilename ); + if ( fileInfo == null ) + { + log.warn( "Couldn't determine PmdFileInfo for file " + filename + " (canonical: " + canonicalFilename + + "). XRef links won't be available." ); + } + + return fileInfo; + } + + private void startFileSection( String currentFilename, PmdFileInfo fileInfo ) + { + sink.section2(); + sink.sectionTitle2(); + + // prepare the filename + this.currentFilename = shortenFilename( currentFilename, fileInfo ); + + sink.text( this.currentFilename ); sink.sectionTitle2_(); sink.table(); @@ -162,8 +196,15 @@ public class PmdReportGenerator private void processViolations() throws IOException { + sink.section1(); + sink.sectionTitle1(); + sink.text( bundle.getString( "report.pmd.files" ) ); + sink.sectionTitle1_(); + + // TODO files summary + fileCount = files.size(); - ArrayList<RuleViolation> violations2 = new ArrayList<>( violations ); + List<RuleViolation> violations2 = new ArrayList<>( violations ); Collections.sort( violations2, new Comparator<RuleViolation>() { /** {@inheritDoc} */ @@ -186,13 +227,7 @@ public class PmdReportGenerator for ( RuleViolation ruleViolation : violations2 ) { String currentFn = ruleViolation.getFilename(); - File canonicalFilename = new File( currentFn ).getCanonicalFile(); - PmdFileInfo fileInfo = files.get( canonicalFilename ); - if ( fileInfo == null ) - { - log.warn( "Couldn't determine PmdFileInfo for file " + currentFn + " (canonical: " + canonicalFilename - + "). XRef links won't be available." ); - } + PmdFileInfo fileInfo = determineFileInfo( currentFn ); if ( !currentFn.equalsIgnoreCase( previousFilename ) && fileSectionStarted ) { @@ -214,6 +249,15 @@ public class PmdReportGenerator { endFileSection(); } + + if ( fileCount == 0 ) + { + sink.paragraph(); + sink.text( bundle.getString( "report.pmd.noProblems" ) ); + sink.paragraph_(); + } + + sink.section1_(); } private void outputLineLink( int line, PmdFileInfo fileInfo ) @@ -235,6 +279,63 @@ public class PmdReportGenerator } } + private void processProcessingErrors() throws IOException + { + // sort the problem by filename first, since PMD is executed multi-threaded + // and might reports the results unsorted + Collections.sort( processingErrors, new Comparator<ProcessingError>() + { + @Override + public int compare( ProcessingError e1, ProcessingError e2 ) + { + return e1.getFile().compareTo( e2.getFile() ); + } + } ); + + sink.section1(); + sink.sectionTitle1(); + sink.text( bundle.getString( "report.pmd.processingErrors.title" ) ); + sink.sectionTitle1_(); + + sink.table(); + sink.tableRow(); + sink.tableHeaderCell(); + sink.text( bundle.getString( "report.pmd.processingErrors.column.filename" ) ); + sink.tableHeaderCell_(); + sink.tableHeaderCell(); + sink.text( bundle.getString( "report.pmd.processingErrors.column.problem" ) ); + sink.tableHeaderCell_(); + sink.tableRow_(); + + for ( ProcessingError error : processingErrors ) + { + processSingleProcessingError( error ); + } + + sink.table_(); + + sink.section1_(); + } + + private void processSingleProcessingError( ProcessingError error ) throws IOException + { + String filename = error.getFile(); + PmdFileInfo fileInfo = determineFileInfo( filename ); + filename = shortenFilename( filename, fileInfo ); + + sink.tableRow(); + sink.tableCell(); + sink.text( filename ); + sink.tableCell_(); + sink.tableCell(); + sink.text( error.getMsg() ); + sink.verbatim( null ); + sink.rawText( error.getDetail() ); + sink.verbatim_(); + sink.tableCell_(); + sink.tableRow_(); + } + public void beginDocument() { sink.head(); @@ -261,13 +362,6 @@ public class PmdReportGenerator sink.section1_(); // TODO overall summary - - sink.section1(); - sink.sectionTitle1(); - sink.text( bundle.getString( "report.pmd.files" ) ); - sink.sectionTitle1_(); - - // TODO files summary } /* @@ -288,20 +382,16 @@ public class PmdReportGenerator throws IOException { processViolations(); + + if ( !processingErrors.isEmpty() ) + { + processProcessingErrors(); + } } public void endDocument() throws IOException { - if ( fileCount == 0 ) - { - sink.paragraph(); - sink.text( bundle.getString( "report.pmd.noProblems" ) ); - sink.paragraph_(); - } - - sink.section1_(); - // The Metrics report useless with the current PMD metrics impl. // For instance, run the coupling ruleset and you will get a boatload // of excessive imports metrics, none of which is really any use. diff --git a/src/main/resources/pmd-report.properties b/src/main/resources/pmd-report.properties index 798c806..031ceef 100644 --- a/src/main/resources/pmd-report.properties +++ b/src/main/resources/pmd-report.properties @@ -23,3 +23,6 @@ report.pmd.column.line=Line report.pmd.pmdlink=The following document contains the results of report.pmd.files=Files report.pmd.noProblems=PMD found no problems in your source code. +report.pmd.processingErrors.title=Processing Errors +report.pmd.processingErrors.column.filename=Filename +report.pmd.processingErrors.column.problem=Problem diff --git a/src/main/resources/pmd-report_de.properties b/src/main/resources/pmd-report_de.properties index 71bb460..36a7cd7 100644 --- a/src/main/resources/pmd-report_de.properties +++ b/src/main/resources/pmd-report_de.properties @@ -23,3 +23,6 @@ report.pmd.column.line=Zeile report.pmd.pmdlink=Dieses Dokument enth\u00e4lt die Ergebnisse von report.pmd.files=Dateien report.pmd.noProblems=PMD hat keine Probleme in dem Quellcode gefunden. +report.pmd.processingErrors.title=Verarbeitungsprobleme +report.pmd.processingErrors.column.filename=Datei +report.pmd.processingErrors.column.problem=Problem diff --git a/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java b/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java index ee3bd1e..614c58f 100644 --- a/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java +++ b/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java @@ -81,7 +81,7 @@ public class PmdReportTest assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) ); // check if there's a link to the JXR files - String str = readFile( new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" ) ); + String str = readFile( generatedFile ); assertTrue( str.contains( "/xref/def/configuration/App.html#L31" ) ); @@ -202,7 +202,7 @@ public class PmdReportTest assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) ); // check if there's a link to the JXR files - String str = readFile( new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" ) ); + String str = readFile( generatedFile ); assertTrue( str.contains( "/xref/def/configuration/App.html#L31" ) ); @@ -244,11 +244,10 @@ public class PmdReportTest generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/site/pmd.html" ); renderer( mojo, generatedFile ); - renderer( mojo, generatedFile ); assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) ); // check if custom ruleset was applied - String str = readFile( new File( getBasedir(), "target/test/unit/custom-configuration/target/site/pmd.html" ) ); + String str = readFile( generatedFile ); assertTrue( lowerCaseContains( str, "Avoid using if statements without curly braces" ) ); // Must be false as IfElseStmtsMustUseBraces is excluded! @@ -309,7 +308,7 @@ public class PmdReportTest // verify the generated files do exist, even if there are no violations File generatedFile = new File( getBasedir(), "target/test/unit/empty-report/target/site/pmd.html" ); assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) ); - String str = readFile( new File( getBasedir(), "target/test/unit/empty-report/target/site/pmd.html" ) ); + String str = readFile( generatedFile ); assertFalse( lowerCaseContains( str, "Hello.java" ) ); } @@ -368,6 +367,7 @@ public class PmdReportTest { str.append( ' ' ); str.append( line ); + str.append( '\n' ); } return str.toString(); } @@ -411,7 +411,7 @@ public class PmdReportTest File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" ); assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) ); - String str = readFile( new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" ) ); + String str = readFile( generatedFile ); // check that there is no violation reported for "unusedVar2" - as it is suppressed assertFalse( str.contains( "Avoid unused private fields such as 'unusedVar2'." ) ); @@ -487,9 +487,16 @@ public class PmdReportTest File generatedFile = new File( getBasedir(), "target/test/unit/parse-error/target/pmd.xml" ); assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) ); - String str = readFile( new File( getBasedir(), "target/test/unit/parse-error/target/pmd.xml" ) ); - + String str = readFile( generatedFile ); assertTrue( str.contains( "Error while parsing" ) ); + // The parse exception must be in the XML report + assertTrue( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) ); + + generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" ); + renderer( mojo, generatedFile ); + assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) ); + str = readFile( generatedFile ); + // The parse exception must also be in the HTML report assertTrue( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) ); } finally { -- To stop receiving notification emails like this one, please contact "commits@maven.apache.org" <commits@maven.apache.org>.