You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ad...@apache.org on 2017/12/18 19:14:41 UTC

[maven-pmd-plugin] 03/05: [MPMD-246] Output details of processing errors

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 <ad...@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" <co...@maven.apache.org>.