1 /******************************************************************************* 2 * Copyright (c) 2009, 2015 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Mads Mohr Christensen - implementation of MergeMojo 10 * 11 *******************************************************************************/ 12 package org.jacoco.maven; 13 14 import java.io.File; 15 import java.io.IOException; 16 import java.util.List; 17 18 import org.apache.maven.plugin.MojoExecutionException; 19 import org.apache.maven.plugin.MojoFailureException; 20 import org.apache.maven.shared.model.fileset.FileSet; 21 import org.apache.maven.shared.model.fileset.util.FileSetManager; 22 import org.jacoco.core.tools.ExecFileLoader; 23 24 /** 25 * Mojo for merging a set of execution data files (*.exec) into a single file 26 * 27 * @phase generate-resources 28 * @goal merge 29 * @requiresProject true 30 * @threadSafe 31 * @since 0.6.4 32 */ 33 public class MergeMojo extends AbstractJacocoMojo { 34 35 private static final String MSG_SKIPPING = "Skipping JaCoCo merge execution due to missing execution data files"; 36 37 /** 38 * Path to the output file for execution data. 39 * 40 * @parameter property="jacoco.destFile" 41 * default-value="${project.build.directory}/jacoco.exec" 42 */ 43 private File destFile; 44 45 /** 46 * This mojo accepts any number of execution data file sets. 47 * 48 * Note that you need an <tt>implementation</tt> hint on <tt>fileset</tt> 49 * with Maven 2 (not needed with Maven 3): 50 * 51 * <pre> 52 * <code> 53 * <fileSets> 54 * <fileSet implementation="org.apache.maven.shared.model.fileset.FileSet"> 55 * <directory>${project.parent.build.directory}</directory> 56 * <includes> 57 * <include>*.exec</include> 58 * </includes> 59 * </fileSet> 60 * </fileSets> 61 * </code> 62 * </pre> 63 * 64 * @parameter property="jacoco.fileSets" 65 * @required 66 */ 67 private List<FileSet> fileSets; 68 69 @Override executeMojo()70 protected void executeMojo() throws MojoExecutionException, 71 MojoFailureException { 72 if (!canMergeReports()) { 73 return; 74 } 75 executeMerge(); 76 } 77 canMergeReports()78 private boolean canMergeReports() { 79 if (fileSets == null || fileSets.isEmpty()) { 80 getLog().info(MSG_SKIPPING); 81 return false; 82 } 83 return true; 84 } 85 executeMerge()86 private void executeMerge() throws MojoExecutionException { 87 final ExecFileLoader loader = new ExecFileLoader(); 88 89 load(loader); 90 save(loader); 91 } 92 load(final ExecFileLoader loader)93 private void load(final ExecFileLoader loader) 94 throws MojoExecutionException { 95 final FileSetManager fileSetManager = new FileSetManager(getLog()); 96 for (final FileSet fileSet : fileSets) { 97 for (final String includedFilename : fileSetManager 98 .getIncludedFiles(fileSet)) { 99 final File inputFile = new File(fileSet.getDirectory(), 100 includedFilename); 101 if (inputFile.isDirectory()) { 102 continue; 103 } 104 try { 105 getLog().info( 106 "Loading execution data file " 107 + inputFile.getAbsolutePath()); 108 loader.load(inputFile); 109 } catch (final IOException e) { 110 throw new MojoExecutionException("Unable to read " 111 + inputFile.getAbsolutePath(), e); 112 } 113 } 114 } 115 } 116 save(final ExecFileLoader loader)117 private void save(final ExecFileLoader loader) 118 throws MojoExecutionException { 119 if (loader.getExecutionDataStore().getContents().isEmpty()) { 120 getLog().info(MSG_SKIPPING); 121 return; 122 } 123 getLog().info( 124 "Writing merged execution data to " 125 + destFile.getAbsolutePath()); 126 try { 127 loader.save(destFile, false); 128 } catch (final IOException e) { 129 throw new MojoExecutionException("Unable to write merged file " 130 + destFile.getAbsolutePath(), e); 131 } 132 } 133 134 } 135