View Javadoc
1   package org.apache.maven.plugin.cxx;
2   
3   /*
4    * Copyright (C) 2011-2016, Neticoa SAS France - Tous droits réservés.
5    * Author(s) : Franck Bonin, Neticoa SAS France
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   *
19   */
20  
21  import java.io.File;
22  import java.io.FileOutputStream;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.OutputStream;
26  import java.util.Arrays;
27  import java.util.Properties;
28  
29  import org.apache.commons.exec.CommandLine;
30  import org.apache.commons.exec.DefaultExecutor;
31  import org.apache.commons.exec.ExecuteException;
32  import org.apache.commons.exec.Executor;
33  
34  import org.apache.maven.plugin.MojoExecutionException;
35  
36  /* Use FileSet and the FileManager provided in this project*/
37  import org.apache.maven.model.FileSet;
38  
39  import org.apache.maven.plugins.annotations.LifecyclePhase;
40  import org.apache.maven.plugins.annotations.Mojo;
41  import org.apache.maven.plugins.annotations.Parameter;
42  
43  import org.apache.maven.plugin.cxx.utils.ExecutorService;
44  import org.apache.maven.plugin.cxx.utils.FileSetManager;
45  
46  /**
47   * Goal which gcovr execution.
48   *
49   * @author Franck Bonin 
50   */
51  @Mojo( name = "coverage", defaultPhase = LifecyclePhase.TEST )
52  public class CoverageMojo extends LaunchMojo
53  {  
54      /**
55       * The Report OutputFile Location.
56       * 
57       * @since 0.0.4
58       */
59      @Parameter( property = "coverage.reportsfilePath", defaultValue = "${project.build.directory}/gcovr-reports" )
60      private File reportsfileDir;
61      
62      /**
63       * The Report OutputFile name identifier.
64       * 
65       * @since 0.0.4
66       */
67      @Parameter( property = "coverage.reportIdentifier", defaultValue = "" )
68      private String reportIdentifier;
69      
70      private String getReportFileName()
71      {
72          return "gcovr-result-" + reportIdentifier + ".xml";
73      }
74      
75      /**
76       * Arguments to clean preexisting gcda report under workingDir
77       * 
78       * @since 0.0.4
79       */
80      @Parameter( property = "coverage.preclean", defaultValue = "true" )
81      private boolean preclean;
82      
83      @Override
84      protected void preExecute( Executor exec, CommandLine commandLine, Properties enviro ) throws MojoExecutionException
85      {
86          if ( preclean )
87          {
88              FileSet afileSet = new FileSet();
89              afileSet.setDirectory( getWorkingDir().getAbsolutePath() );
90              
91              getLog().debug( "Search for **/*.gcda from " + afileSet.getDirectory() );
92              afileSet.setIncludes( Arrays.asList( new String[]{"**/*.gcda"} ) );
93              //afileSet.setExcludes( Arrays.asList(excludes) );
94              
95              FileSetManager aFileSetManager = new FileSetManager();
96              String[] found = aFileSetManager.getIncludedFiles( afileSet );
97  
98              for ( int i = 0; i < found.length; i++ )
99              {
100                 File target = new File( getWorkingDir() + "/" + found[i] );
101                 getLog().debug( "Found file " + target.getAbsolutePath() );
102                 if ( target.exists() )
103                 {
104                     try
105                     {
106                         if ( target.delete() )
107                         {
108                             getLog().debug( "Succesfully delete " + target.getAbsolutePath() );
109                         }
110                         else
111                         {
112                             getLog().warn( "Failed to delete " + target.getAbsolutePath() );
113                         }
114                     }
115                     catch ( SecurityException e )
116                     {
117                         getLog().warn( "SecurityException, unable to delete " + target.getAbsolutePath() );
118                     } 
119                 }
120                 else
121                 {
122                     getLog().debug( "But file " + target.getAbsolutePath() + " not exist" );
123                 }
124             }
125         }
126     }
127     
128     /**
129      * Arguments for the gcovr program. Shall be -x -d
130      * ex: -x -d to produce Xml reports and clean gcda execution reports after reading
131      * 
132      */
133     @Parameter( property = "coverage.args", defaultValue = "-x -d" )
134     private String gcovrArgs;
135     
136     @Override
137     protected void postExecute( int resultCode ) throws MojoExecutionException
138     {
139         String outputReportName = new String();
140         if ( reportsfileDir.isAbsolute() )
141         {
142             outputReportName = reportsfileDir.getAbsolutePath() + "/" + getReportFileName();
143         }
144         else
145         {
146             outputReportName = basedir.getAbsolutePath() + "/" + reportsfileDir.getPath() + "/" + getReportFileName();
147         }
148         getLog().info( "Coverage report location " + outputReportName );
149          
150         OutputStream outStream = System.out;
151         File file = new File( outputReportName );
152         try
153         {
154             new File( file.getParent() ).mkdirs();
155             file.createNewFile();
156             outStream = new FileOutputStream( file );
157         }
158         catch ( IOException e )
159         {
160             getLog().error( "Coverage report redirected to stdout since " + outputReportName + " can't be opened" );
161         }
162         
163         InputStream pyScript = getClass().getResourceAsStream( "/gcovr.py" );
164         
165         CommandLine commandLine = new CommandLine( "python" );
166         Executor exec = new DefaultExecutor();
167         String[] args = parseCommandlineArgs( "-" );
168         commandLine.addArguments( args, false );
169         args = parseCommandlineArgs( gcovrArgs );
170         commandLine.addArguments( args, false );
171         exec.setWorkingDirectory( getWorkingDir() );
172         try
173         {
174             getLog().info( "Executing command line: " + commandLine );
175 
176             int res = ExecutorService.executeCommandLine( exec, commandLine, getEnvs(),
177                 outStream/*getOutputStreamOut()*/, getOutputStreamErr(), pyScript/*getInputStream()*/ );
178             // this is a hugly workaround against a random bugs from hudson cobertura plugin.
179             // hudson cobertura plugin randomly truncat coverage reports file to a 1024 size multiple
180             // while it copy reports from slave to master node
181             for ( int j = 0 ; j < 200 ; j++ )
182             {
183                 for ( int i = 0 ; i < 80 ; i++ )
184                 {
185                     outStream.write( ' ' );
186                 }
187                 outStream.write( '\n' );
188             }
189             outStream.flush();
190             
191             if ( isResultCodeAFailure( res ) )
192             {
193                 throw new MojoExecutionException( "Result of command line execution is: '" + res + "'." );
194             }
195         }
196         catch ( ExecuteException e )
197         {
198             throw new MojoExecutionException( "Command execution failed.", e );
199         }
200         catch ( IOException e )
201         {
202             throw new MojoExecutionException( "Command execution failed.", e );
203         }
204     }
205     
206     /**
207      * Set this to "true" to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite
208      * convenient on occasion.
209      *
210      * @since 0.0.5
211      */
212     @Parameter( property = "skipTests", defaultValue = "false" )
213     protected boolean skipTests;
214     
215     /**
216      * Set this to "true" to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you enable
217      * it using the "maven.test.skip" property, because maven.test.skip shall disables both running the tests
218      * and compiling the tests. Consider using the <code>skipTests</code> parameter instead.
219      *
220      * @since 0.0.5
221      */
222     @Parameter( property = "maven.test.skip", defaultValue = "false" )
223     protected boolean skip;
224     
225     @Override
226     protected boolean isSkip()
227     {
228         return super.isSkip() || skipTests || skip;
229     }
230 }