1 package org.apache.maven.plugin.clean; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import org.apache.maven.plugin.AbstractMojo; 23 import org.apache.maven.plugin.MojoExecutionException; 24 25 import java.io.File; 26 import java.io.IOException; 27 28 /** 29 * Goal which cleans the build. 30 * 31 * <P>This attempts to clean a project's working directory of the files that 32 * were generated at build-time. By default, it discovers and deletes the 33 * directories configured in <code>project.build.directory</code>, 34 * <code>project.build.outputDirectory</code>, 35 * <code>project.build.testOutputDirectory</code>, and 36 * <code>project.reporting.outputDirectory</code>. </P> 37 * 38 * <P>Files outside the default may also be included in the deletion by 39 * configuring the <code>filesets</code> tag.</P> 40 * 41 * @author <a href="mailto:evenisse@maven.org">Emmanuel Venisse</a> 42 * @version $Id: CleanMojo.html 828303 2012-08-07 22:10:04Z hboutemy $ 43 * @goal clean 44 * @threadSafe 45 * @since 2.0 46 * @see org.apache.maven.plugin.clean.Fileset 47 */ 48 public class CleanMojo 49 extends AbstractMojo 50 { 51 52 /** 53 * This is where build results go. 54 * 55 * @parameter default-value="${project.build.directory}" 56 * @required 57 * @readonly 58 */ 59 private File directory; 60 61 /** 62 * This is where compiled classes go. 63 * 64 * @parameter default-value="${project.build.outputDirectory}" 65 * @required 66 * @readonly 67 */ 68 private File outputDirectory; 69 70 /** 71 * This is where compiled test classes go. 72 * 73 * @parameter default-value="${project.build.testOutputDirectory}" 74 * @required 75 * @readonly 76 */ 77 private File testOutputDirectory; 78 79 /** 80 * This is where the site plugin generates its pages. 81 * 82 * @parameter default-value="${project.reporting.outputDirectory}" 83 * @required 84 * @readonly 85 * @since 2.1.1 86 */ 87 private File reportDirectory; 88 89 /** 90 * Sets whether the plugin runs in verbose mode. As of plugin version 2.3, the default value is derived from Maven's 91 * global debug flag (compare command line switch <code>-X</code>). 92 * 93 * @parameter expression="${clean.verbose}" 94 * @since 2.1 95 */ 96 private Boolean verbose; 97 98 /** 99 * The list of file sets to delete, in addition to the default directories. For example: 100 * <pre> 101 * <filesets> 102 * <fileset> 103 * <directory>src/main/generated</directory> 104 * <followSymlinks>false</followSymlinks> 105 * <useDefaultExcludes>true</useDefaultExcludes> 106 * <includes> 107 * <include>*.java</include> 108 * </includes> 109 * <excludes> 110 * <exclude>Template*</exclude> 111 * </excludes> 112 * </fileset> 113 * </filesets> 114 * </pre> 115 * 116 * @parameter 117 * @since 2.1 118 */ 119 private Fileset[] filesets; 120 121 /** 122 * Sets whether the plugin should follow symbolic links while deleting files from the default output directories of 123 * the project. Not following symlinks requires more IO operations and heap memory, regardless whether symlinks are 124 * actually present. So projects with a huge output directory that knowingly does not contain symlinks can improve 125 * performance by setting this parameter to <code>true</code>. 126 * 127 * @parameter expression="${clean.followSymLinks}" default-value="false" 128 * @since 2.1 129 */ 130 private boolean followSymLinks; 131 132 /** 133 * Disables the plugin execution. 134 * 135 * @parameter expression="${clean.skip}" default-value="false" 136 * @since 2.2 137 */ 138 private boolean skip; 139 140 /** 141 * Indicates whether the build will continue even if there are clean errors. 142 * 143 * @parameter expression="${maven.clean.failOnError}" default-value="true" 144 * @since 2.2 145 */ 146 private boolean failOnError; 147 148 /** 149 * Indicates whether the plugin should undertake additional attempts (after a short delay) to delete a file if the 150 * first attempt failed. This is meant to help deleting files that are temporarily locked by third-party tools like 151 * virus scanners or search indexing. 152 * 153 * @parameter expression="${maven.clean.retryOnError}" default-value="true" 154 * @since 2.4.2 155 */ 156 private boolean retryOnError; 157 158 /** 159 * Disables the deletion of the default output directories configured for a project. If set to <code>true</code>, 160 * only the files/directories selected via the parameter {@link #filesets} will be deleted. 161 * 162 * @parameter expression="${clean.excludeDefaultDirectories}" default-value="false" 163 * @since 2.3 164 */ 165 private boolean excludeDefaultDirectories; 166 167 /** 168 * Deletes file-sets in the following project build directory order: (source) directory, output directory, test 169 * directory, report directory, and then the additional file-sets. 170 * 171 * @see org.apache.maven.plugin.Mojo#execute() 172 * @throws MojoExecutionException When a directory failed to get deleted. 173 */ 174 public void execute() 175 throws MojoExecutionException 176 { 177 if ( skip ) 178 { 179 getLog().info( "Clean is skipped." ); 180 return; 181 } 182 183 Cleaner cleaner = new Cleaner( getLog(), isVerbose() ); 184 185 try 186 { 187 File[] directories = getDirectories(); 188 for ( int i = 0; i < directories.length; i++ ) 189 { 190 File directory = directories[i]; 191 if ( directory != null ) 192 { 193 cleaner.delete( directory, null, followSymLinks, failOnError, retryOnError ); 194 } 195 } 196 197 if ( filesets != null ) 198 { 199 for ( int i = 0; i < filesets.length; i++ ) 200 { 201 Fileset fileset = filesets[i]; 202 if ( fileset.getDirectory() == null ) 203 { 204 throw new MojoExecutionException( "Missing base directory for " + fileset ); 205 } 206 GlobSelector selector = 207 new GlobSelector( fileset.getIncludes(), fileset.getExcludes(), fileset.isUseDefaultExcludes() ); 208 cleaner.delete( fileset.getDirectory(), selector, fileset.isFollowSymlinks(), failOnError, 209 retryOnError ); 210 } 211 } 212 } 213 catch ( IOException e ) 214 { 215 throw new MojoExecutionException( "Failed to clean project: " + e.getMessage(), e ); 216 } 217 } 218 219 /** 220 * Indicates whether verbose output is enabled. 221 * 222 * @return <code>true</code> if verbose output is enabled, <code>false</code> otherwise. 223 */ 224 private boolean isVerbose() 225 { 226 return ( verbose != null ) ? verbose.booleanValue() : getLog().isDebugEnabled(); 227 } 228 229 /** 230 * Gets the directories to clean (if any). The returned array may contain null entries. 231 * 232 * @return The directories to clean or an empty array if none, never <code>null</code>. 233 */ 234 private File[] getDirectories() 235 { 236 File[] directories; 237 if ( excludeDefaultDirectories ) 238 { 239 directories = new File[0]; 240 } 241 else 242 { 243 directories = new File[] { directory, outputDirectory, testOutputDirectory, reportDirectory }; 244 } 245 return directories; 246 } 247 248 }