| package org.apache.maven.plugins.clean; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import org.apache.maven.execution.MavenSession; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.plugins.annotations.Mojo; |
| import org.apache.maven.plugins.annotations.Parameter; |
| |
| import java.io.File; |
| import java.io.IOException; |
| |
| /** |
| * Goal which cleans the build. |
| * <p> |
| * This attempts to clean a project's working directory of the files that were generated at build-time. By default, it |
| * discovers and deletes the directories configured in <code>project.build.directory</code>, |
| * <code>project.build.outputDirectory</code>, <code>project.build.testOutputDirectory</code>, and |
| * <code>project.reporting.outputDirectory</code>. |
| * </p> |
| * <p> |
| * Files outside the default may also be included in the deletion by configuring the <code>filesets</code> tag. |
| * </p> |
| * |
| * @author <a href="mailto:evenisse@maven.org">Emmanuel Venisse</a> |
| * @see org.apache.maven.plugins.clean.Fileset |
| * @since 2.0 |
| */ |
| @Mojo( name = "clean", threadSafe = true ) |
| public class CleanMojo |
| extends AbstractMojo |
| { |
| |
| public static final String FAST_MODE_BACKGROUND = "background"; |
| |
| public static final String FAST_MODE_AT_END = "at-end"; |
| |
| public static final String FAST_MODE_DEFER = "defer"; |
| |
| /** |
| * This is where build results go. |
| */ |
| @Parameter( defaultValue = "${project.build.directory}", readonly = true, required = true ) |
| private File directory; |
| |
| /** |
| * This is where compiled classes go. |
| */ |
| @Parameter( defaultValue = "${project.build.outputDirectory}", readonly = true, required = true ) |
| private File outputDirectory; |
| |
| /** |
| * This is where compiled test classes go. |
| */ |
| @Parameter( defaultValue = "${project.build.testOutputDirectory}", readonly = true, required = true ) |
| private File testOutputDirectory; |
| |
| /** |
| * This is where the site plugin generates its pages. |
| * |
| * @since 2.1.1 |
| */ |
| @Parameter( defaultValue = "${project.build.outputDirectory}", readonly = true, required = true ) |
| private File reportDirectory; |
| |
| /** |
| * Sets whether the plugin runs in verbose mode. As of plugin version 2.3, the default value is derived from Maven's |
| * global debug flag (compare command line switch <code>-X</code>). <br/> |
| * Starting with <b>3.0.0</b> the property has been renamed from <code>clean.verbose</code> to |
| * <code>maven.clean.verbose</code>. |
| * |
| * @since 2.1 |
| */ |
| @Parameter( property = "maven.clean.verbose" ) |
| private Boolean verbose; |
| |
| /** |
| * The list of file sets to delete, in addition to the default directories. For example: |
| * |
| * <pre> |
| * <filesets> |
| * <fileset> |
| * <directory>src/main/generated</directory> |
| * <followSymlinks>false</followSymlinks> |
| * <useDefaultExcludes>true</useDefaultExcludes> |
| * <includes> |
| * <include>*.java</include> |
| * </includes> |
| * <excludes> |
| * <exclude>Template*</exclude> |
| * </excludes> |
| * </fileset> |
| * </filesets> |
| * </pre> |
| * |
| * @since 2.1 |
| */ |
| @Parameter |
| private Fileset[] filesets; |
| |
| /** |
| * Sets whether the plugin should follow symbolic links while deleting files from the default output directories of |
| * the project. Not following symlinks requires more IO operations and heap memory, regardless whether symlinks are |
| * actually present. So projects with a huge output directory that knowingly does not contain symlinks can improve |
| * performance by setting this parameter to <code>true</code>. <br/> |
| * Starting with <code>3.0.0</code> the property has been renamed from <code>clean.followSymLinks</code> to |
| * <code>maven.clean.followSymLinks</code>. |
| * |
| * @since 2.1 |
| */ |
| @Parameter( property = "maven.clean.followSymLinks", defaultValue = "false" ) |
| private boolean followSymLinks; |
| |
| /** |
| * Disables the plugin execution. <br/> |
| * Starting with <code>3.0.0</code> the property has been renamed from <code>clean.skip</code> to |
| * <code>maven.clean.skip</code>. |
| * |
| * @since 2.2 |
| */ |
| @Parameter( property = "maven.clean.skip", defaultValue = "false" ) |
| private boolean skip; |
| |
| /** |
| * Indicates whether the build will continue even if there are clean errors. |
| * |
| * @since 2.2 |
| */ |
| @Parameter( property = "maven.clean.failOnError", defaultValue = "true" ) |
| private boolean failOnError; |
| |
| /** |
| * Indicates whether the plugin should undertake additional attempts (after a short delay) to delete a file if the |
| * first attempt failed. This is meant to help deleting files that are temporarily locked by third-party tools like |
| * virus scanners or search indexing. |
| * |
| * @since 2.4.2 |
| */ |
| @Parameter( property = "maven.clean.retryOnError", defaultValue = "true" ) |
| private boolean retryOnError; |
| |
| /** |
| * Disables the deletion of the default output directories configured for a project. If set to <code>true</code>, |
| * only the files/directories selected via the parameter {@link #filesets} will be deleted. <br/> |
| * Starting with <b>3.0.0</b> the property has been renamed from <code>clean.excludeDefaultDirectories</code> to |
| * <code>maven.clean.excludeDefaultDirectories</code>. |
| * |
| * @since 2.3 |
| */ |
| @Parameter( property = "maven.clean.excludeDefaultDirectories", defaultValue = "false" ) |
| private boolean excludeDefaultDirectories; |
| |
| /** |
| * Enables fast clean if possible. If set to <code>true</code>, when the plugin is executed, a directory to |
| * be deleted will be atomically moved inside the <code>maven.clean.fastDir</code> directory and a thread will |
| * be launched to delete the needed files in the background. When the build is completed, maven will wait |
| * until all the files have been deleted. If any problem occurs during the atomic move of the directories, |
| * the plugin will default to the traditional deletion mechanism. |
| * |
| * @since 3.2 |
| */ |
| @Parameter( property = "maven.clean.fast", defaultValue = "false" ) |
| private boolean fast; |
| |
| /** |
| * When fast clean is specified, the <code>fastDir</code> property will be used as the location where directories |
| * to be deleted will be moved prior to background deletion. If not specified, the |
| * <code>${maven.multiModuleProjectDirectory}/target/.clean</code> directory will be used. If the |
| * <code>${build.directory}</code> has been modified, you'll have to adjust this property explicitly. |
| * In order for fast clean to work correctly, this directory and the various directories that will be deleted |
| * should usually reside on the same volume. The exact conditions are system dependant though, but if an atomic |
| * move is not supported, the standard deletion mechanism will be used. |
| * |
| * @since 3.2 |
| * @see #fast |
| */ |
| @Parameter( property = "maven.clean.fastDir" ) |
| private File fastDir; |
| |
| /** |
| * Mode to use when using fast clean. Values are: <code>background</code> to start deletion immediately and |
| * waiting for all files to be deleted when the session ends, <code>at-end</code> to indicate that the actual |
| * deletion should be performed synchronously when the session ends, or <code>defer</code> to specify that |
| * the actual file deletion should be started in the background when the session ends (this should only be used |
| * when maven is embedded in a long running process). |
| * |
| * @since 3.2 |
| * @see #fast |
| */ |
| @Parameter( property = "maven.clean.fastMode", defaultValue = FAST_MODE_BACKGROUND ) |
| private String fastMode; |
| |
| @Parameter( defaultValue = "${session}", readonly = true ) |
| private MavenSession session; |
| |
| /** |
| * Deletes file-sets in the following project build directory order: (source) directory, output directory, test |
| * directory, report directory, and then the additional file-sets. |
| * |
| * @throws MojoExecutionException When a directory failed to get deleted. |
| * @see org.apache.maven.plugin.Mojo#execute() |
| */ |
| public void execute() |
| throws MojoExecutionException |
| { |
| if ( skip ) |
| { |
| getLog().info( "Clean is skipped." ); |
| return; |
| } |
| |
| String multiModuleProjectDirectory = session != null |
| ? session.getSystemProperties().getProperty( "maven.multiModuleProjectDirectory" ) : null; |
| File fastDir; |
| if ( fast && this.fastDir != null ) |
| { |
| fastDir = this.fastDir; |
| } |
| else if ( fast && multiModuleProjectDirectory != null ) |
| { |
| fastDir = new File( multiModuleProjectDirectory, "target/.clean" ); |
| } |
| else |
| { |
| fastDir = null; |
| if ( fast ) |
| { |
| getLog().warn( "Fast clean requires maven 3.3.1 or newer, " |
| + "or an explicit directory to be specified with the 'fastDir' configuration of " |
| + "this plugin, or the 'maven.clean.fastDir' user property to be set." ); |
| } |
| } |
| if ( fast && !FAST_MODE_BACKGROUND.equals( fastMode ) |
| && !FAST_MODE_AT_END.equals( fastMode ) |
| && !FAST_MODE_DEFER.equals( fastMode ) ) |
| { |
| throw new IllegalArgumentException( "Illegal value '" + fastMode + "' for fastMode. Allowed values are '" |
| + FAST_MODE_BACKGROUND + "', '" + FAST_MODE_AT_END + "' and '" + FAST_MODE_DEFER + "'." ); |
| } |
| |
| Cleaner cleaner = new Cleaner( session, getLog(), isVerbose(), fastDir, fastMode ); |
| |
| try |
| { |
| for ( File directoryItem : getDirectories() ) |
| { |
| if ( directoryItem != null ) |
| { |
| cleaner.delete( directoryItem, null, followSymLinks, failOnError, retryOnError ); |
| } |
| } |
| |
| if ( filesets != null ) |
| { |
| for ( Fileset fileset : filesets ) |
| { |
| if ( fileset.getDirectory() == null ) |
| { |
| throw new MojoExecutionException( "Missing base directory for " + fileset ); |
| } |
| GlobSelector selector = new GlobSelector( fileset.getIncludes(), fileset.getExcludes(), |
| fileset.isUseDefaultExcludes() ); |
| cleaner.delete( fileset.getDirectory(), selector, fileset.isFollowSymlinks(), failOnError, |
| retryOnError ); |
| } |
| } |
| } |
| catch ( IOException e ) |
| { |
| throw new MojoExecutionException( "Failed to clean project: " + e.getMessage(), e ); |
| } |
| } |
| |
| /** |
| * Indicates whether verbose output is enabled. |
| * |
| * @return <code>true</code> if verbose output is enabled, <code>false</code> otherwise. |
| */ |
| private boolean isVerbose() |
| { |
| return ( verbose != null ) ? verbose : getLog().isDebugEnabled(); |
| } |
| |
| /** |
| * Gets the directories to clean (if any). The returned array may contain null entries. |
| * |
| * @return The directories to clean or an empty array if none, never <code>null</code>. |
| */ |
| private File[] getDirectories() |
| { |
| File[] directories; |
| if ( excludeDefaultDirectories ) |
| { |
| directories = new File[0]; |
| } |
| else |
| { |
| directories = new File[] { directory, outputDirectory, testOutputDirectory, reportDirectory }; |
| } |
| return directories; |
| } |
| |
| } |