This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-clean-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new 2da1474 [MCLEAN-123] Switch to Maven 4 and the new api (#20)
2da1474 is described below
commit 2da147458800dfe9ecc24865aef0e718ac56df57
Author: Guillaume Nodet <[email protected]>
AuthorDate: Mon Jun 24 17:05:32 2024 +0200
[MCLEAN-123] Switch to Maven 4 and the new api (#20)
---
.github/workflows/maven-verify.yml | 4 +-
pom.xml | 62 ++--
src/it/settings.xml | 4 +
.../org/apache/maven/plugins/clean/CleanMojo.java | 70 +++--
.../org/apache/maven/plugins/clean/Cleaner.java | 334 +++++++++++----------
.../org/apache/maven/plugins/clean/Fileset.java | 6 +-
.../apt/examples/delete_additional_files.apt.vm | 2 +-
.../apache/maven/plugins/clean/CleanMojoTest.java | 170 ++++++-----
.../resources/unit/basic-clean-test/plugin-pom.xml | 35 ---
.../plugin-pom.xml => basic-clean-test/pom.xml} | 4 +-
.../empty-clean-test/{plugin-pom.xml => pom.xml} | 0
.../fileset-clean-test/{plugin-pom.xml => pom.xml} | 5 +-
.../pom.xml} | 2 +-
.../plugin-pom.xml => locked-file-test/pom.xml} | 2 +-
.../pom.xml} | 2 +-
.../unit/nested-clean-test/plugin-pom.xml | 35 ---
.../plugin-pom.xml => nested-clean-test/pom.xml} | 4 +-
17 files changed, 379 insertions(+), 362 deletions(-)
diff --git a/.github/workflows/maven-verify.yml
b/.github/workflows/maven-verify.yml
index ce4b500..56062b5 100644
--- a/.github/workflows/maven-verify.yml
+++ b/.github/workflows/maven-verify.yml
@@ -26,4 +26,6 @@ jobs:
name: Verify
uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v4
with:
- maven4-enabled: true
+ ff-maven: "4.0.0-beta-3" # Maven version for
fail-fast-build
+ maven-matrix: '[ "4.0.0-beta-3" ]'
+ jdk-matrix: '[ "17", "21" ]'
diff --git a/pom.xml b/pom.xml
index 73c3c72..a7ef0bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@ under the License.
</parent>
<artifactId>maven-clean-plugin</artifactId>
- <version>3.4.1-SNAPSHOT</version>
+ <version>4.0.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>Apache Maven Clean Plugin</name>
@@ -61,46 +61,44 @@ under the License.
</distributionManagement>
<properties>
- <mavenVersion>3.6.3</mavenVersion>
+ <mavenVersion>4.0.0-beta-3</mavenVersion>
+ <javaVersion>17</javaVersion>
+ <version.maven-invoker-plugin>3.7.0</version.maven-invoker-plugin>
+
<version.maven-plugin-testing>4.0.0-alpha-3-SNAPSHOT</version.maven-plugin-testing>
+ <version.maven-plugin-tools>4.0.0-SNAPSHOT</version.maven-plugin-tools>
<project.build.outputTimestamp>2024-06-16T10:25:11Z</project.build.outputTimestamp>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
- <artifactId>maven-plugin-api</artifactId>
+ <artifactId>maven-api-core</artifactId>
<version>${mavenVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
- <artifactId>maven-core</artifactId>
+ <artifactId>maven-api-di</artifactId>
<version>${mavenVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.apache.maven.resolver</groupId>
- <artifactId>maven-resolver-api</artifactId>
- <version>1.1.1</version>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-api-meta</artifactId>
+ <version>${mavenVersion}</version>
<scope>provided</scope>
</dependency>
+
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</dependency>
- <!-- dependencies to annotations -->
- <dependency>
- <groupId>org.apache.maven.plugin-tools</groupId>
- <artifactId>maven-plugin-annotations</artifactId>
- <scope>provided</scope>
- </dependency>
-
<!-- Test -->
<dependency>
<groupId>org.apache.maven.plugin-testing</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
- <version>4.0.0-alpha-2</version>
+ <version>${version.maven-plugin-testing}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -109,18 +107,42 @@ under the License.
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-testing</artifactId>
- <version>1.3.0</version>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${mavenVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-xml</artifactId>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ <version>6.0.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>2.0.13</version>
<scope>test</scope>
</dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>${version.maven-plugin-tools}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
<profiles>
<profile>
<id>run-its</id>
diff --git a/src/it/settings.xml b/src/it/settings.xml
index c8f77f0..5617e4e 100644
--- a/src/it/settings.xml
+++ b/src/it/settings.xml
@@ -32,9 +32,11 @@ under the License.
<url>@localRepositoryUrl@</url>
<releases>
<enabled>true</enabled>
+ <checksumPolicy>ignore</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
+ <checksumPolicy>ignore</checksumPolicy>
</snapshots>
</repository>
</repositories>
@@ -44,9 +46,11 @@ under the License.
<url>@localRepositoryUrl@</url>
<releases>
<enabled>true</enabled>
+ <checksumPolicy>ignore</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
+ <checksumPolicy>ignore</checksumPolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
diff --git a/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java
b/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java
index 4f77c00..44ceb48 100644
--- a/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java
+++ b/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java
@@ -18,14 +18,16 @@
*/
package org.apache.maven.plugins.clean;
-import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
-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 org.apache.maven.api.Session;
+import org.apache.maven.api.di.Inject;
+import org.apache.maven.api.plugin.Log;
+import org.apache.maven.api.plugin.MojoException;
+import org.apache.maven.api.plugin.annotations.Mojo;
+import org.apache.maven.api.plugin.annotations.Parameter;
/**
* Goal which cleans the build.
@@ -43,8 +45,8 @@ import org.apache.maven.plugins.annotations.Parameter;
* @see org.apache.maven.plugins.clean.Fileset
* @since 2.0
*/
-@Mojo(name = "clean", threadSafe = true)
-public class CleanMojo extends AbstractMojo {
+@Mojo(name = "clean")
+public class CleanMojo implements org.apache.maven.api.plugin.Mojo {
public static final String FAST_MODE_BACKGROUND = "background";
@@ -52,23 +54,26 @@ public class CleanMojo extends AbstractMojo {
public static final String FAST_MODE_DEFER = "defer";
+ @Inject
+ private Log logger;
+
/**
* This is where build results go.
*/
@Parameter(defaultValue = "${project.build.directory}", readonly = true,
required = true)
- private File directory;
+ private Path directory;
/**
* This is where compiled classes go.
*/
@Parameter(defaultValue = "${project.build.outputDirectory}", readonly =
true, required = true)
- private File outputDirectory;
+ private Path outputDirectory;
/**
* This is where compiled test classes go.
*/
@Parameter(defaultValue = "${project.build.testOutputDirectory}", readonly
= true, required = true)
- private File testOutputDirectory;
+ private Path testOutputDirectory;
/**
* This is where the site plugin generates its pages.
@@ -76,7 +81,7 @@ public class CleanMojo extends AbstractMojo {
* @since 2.1.1
*/
@Parameter(defaultValue = "${project.build.outputDirectory}", readonly =
true, required = true)
- private File reportDirectory;
+ private Path reportDirectory;
/**
* Sets whether the plugin runs in verbose mode. As of plugin version 2.3,
the default value is derived from Maven's
@@ -186,11 +191,11 @@ public class CleanMojo extends AbstractMojo {
* 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.
*
- * @see #fast
* @since 3.2
+ * @see #fast
*/
@Parameter(property = "maven.clean.fastDir")
- private File fastDir;
+ private Path fastDir;
/**
* Mode to use when using fast clean. Values are: <code>background</code>
to start deletion immediately and
@@ -199,35 +204,35 @@ public class CleanMojo extends AbstractMojo {
* 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).
*
- * @see #fast
* @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;
+ @Inject
+ private Session 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()
+ * @throws MojoException When a directory failed to get deleted.
+ * @see org.apache.maven.api.plugin.Mojo#execute()
*/
- public void execute() throws MojoExecutionException {
+ public void execute() {
if (skip) {
getLog().info("Clean is skipped.");
return;
}
String multiModuleProjectDirectory =
- session != null ?
session.getSystemProperties().getProperty("maven.multiModuleProjectDirectory")
: null;
- File fastDir;
+ session != null ?
session.getSystemProperties().get("maven.multiModuleProjectDirectory") : null;
+ Path fastDir;
if (fast && this.fastDir != null) {
fastDir = this.fastDir;
} else if (fast && multiModuleProjectDirectory != null) {
- fastDir = new File(multiModuleProjectDirectory, "target/.clean");
+ fastDir = Paths.get(multiModuleProjectDirectory, "target/.clean");
} else {
fastDir = null;
if (fast) {
@@ -247,7 +252,7 @@ public class CleanMojo extends AbstractMojo {
Cleaner cleaner = new Cleaner(session, getLog(), isVerbose(), fastDir,
fastMode);
try {
- for (File directoryItem : getDirectories()) {
+ for (Path directoryItem : getDirectories()) {
if (directoryItem != null) {
cleaner.delete(directoryItem, null, followSymLinks,
failOnError, retryOnError);
}
@@ -256,7 +261,7 @@ public class CleanMojo extends AbstractMojo {
if (filesets != null) {
for (Fileset fileset : filesets) {
if (fileset.getDirectory() == null) {
- throw new MojoExecutionException("Missing base
directory for " + fileset);
+ throw new MojoException("Missing base directory for "
+ fileset);
}
final String[] includes = fileset.getIncludes();
final String[] excludes = fileset.getExcludes();
@@ -273,8 +278,9 @@ public class CleanMojo extends AbstractMojo {
fileset.getDirectory(), selector,
fileset.isFollowSymlinks(), failOnError, retryOnError);
}
}
+
} catch (IOException e) {
- throw new MojoExecutionException("Failed to clean project: " +
e.getMessage(), e);
+ throw new MojoException("Failed to clean project: " +
e.getMessage(), e);
}
}
@@ -292,13 +298,17 @@ public class CleanMojo extends AbstractMojo {
*
* @return The directories to clean or an empty array if none, never
<code>null</code>.
*/
- private File[] getDirectories() {
- File[] directories;
+ private Path[] getDirectories() {
+ Path[] directories;
if (excludeDefaultDirectories) {
- directories = new File[0];
+ directories = new Path[0];
} else {
- directories = new File[] {directory, outputDirectory,
testOutputDirectory, reportDirectory};
+ directories = new Path[] {directory, outputDirectory,
testOutputDirectory, reportDirectory};
}
return directories;
}
+
+ private Log getLog() {
+ return logger;
+ }
}
diff --git a/src/main/java/org/apache/maven/plugins/clean/Cleaner.java
b/src/main/java/org/apache/maven/plugins/clean/Cleaner.java
index f5c25d2..533a224 100644
--- a/src/main/java/org/apache/maven/plugins/clean/Cleaner.java
+++ b/src/main/java/org/apache/maven/plugins/clean/Cleaner.java
@@ -20,9 +20,6 @@ package org.apache.maven.plugins.clean;
import java.io.File;
import java.io.IOException;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
@@ -30,12 +27,17 @@ import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayDeque;
import java.util.Deque;
-
-import org.apache.maven.execution.ExecutionListener;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.logging.Log;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import org.apache.maven.api.Event;
+import org.apache.maven.api.EventType;
+import org.apache.maven.api.Listener;
+import org.apache.maven.api.Session;
+import org.apache.maven.api.SessionData;
+import org.apache.maven.api.plugin.Log;
import org.codehaus.plexus.util.Os;
-import org.eclipse.aether.SessionData;
import static org.apache.maven.plugins.clean.CleanMojo.FAST_MODE_BACKGROUND;
import static org.apache.maven.plugins.clean.CleanMojo.FAST_MODE_DEFER;
@@ -49,70 +51,93 @@ class Cleaner {
private static final boolean ON_WINDOWS = Os.isFamily(Os.FAMILY_WINDOWS);
- private static final String LAST_DIRECTORY_TO_DELETE =
Cleaner.class.getName() + ".lastDirectoryToDelete";
+ private static final SessionData.Key<Path> LAST_DIRECTORY_TO_DELETE =
+ SessionData.key(Path.class, Cleaner.class.getName() +
".lastDirectoryToDelete");
/**
* The maven session. This is typically non-null in a real run, but it
can be during unit tests.
*/
- private final MavenSession session;
+ private final Session session;
- private final File fastDir;
+ private final Logger logDebug;
- private final String fastMode;
+ private final Logger logInfo;
+
+ private final Logger logVerbose;
- private final boolean verbose;
+ private final Logger logWarn;
- private Log log;
+ private final Path fastDir;
+
+ private final String fastMode;
/**
* Creates a new cleaner.
*
* @param session The Maven session to be used.
- * @param log The logger to use.
+ * @param log The logger to use, may be <code>null</code> to disable
logging.
* @param verbose Whether to perform verbose logging.
* @param fastDir The explicit configured directory or to be deleted in
fast mode.
* @param fastMode The fast deletion mode.
*/
- Cleaner(MavenSession session, final Log log, boolean verbose, File
fastDir, String fastMode) {
+ Cleaner(Session session, Log log, boolean verbose, Path fastDir, String
fastMode) {
+ logDebug = (log == null || !log.isDebugEnabled()) ? null :
logger(log::debug, log::debug);
+
+ logInfo = (log == null || !log.isInfoEnabled()) ? null :
logger(log::info, log::info);
+
+ logWarn = (log == null || !log.isWarnEnabled()) ? null :
logger(log::warn, log::warn);
+
+ logVerbose = verbose ? logInfo : logDebug;
+
this.session = session;
- // This can't be null as the Cleaner gets it from the CleanMojo which
gets it from AbstractMojo class, where it
- // is never null.
- this.log = log;
this.fastDir = fastDir;
this.fastMode = fastMode;
- this.verbose = verbose;
+ }
+
+ private Logger logger(Consumer<CharSequence> l1, BiConsumer<CharSequence,
Throwable> l2) {
+ return new Logger() {
+ @Override
+ public void log(CharSequence message) {
+ l1.accept(message);
+ }
+
+ @Override
+ public void log(CharSequence message, Throwable t) {
+ l2.accept(message, t);
+ }
+ };
}
/**
* Deletes the specified directories and its contents.
*
- * @param basedir The directory to delete, must not be
<code>null</code>. Non-existing directories will be silently
- * ignored.
- * @param selector The selector used to determine what contents to
delete, may be <code>null</code> to delete
- * everything.
+ * @param basedir The directory to delete, must not be <code>null</code>.
Non-existing directories will be silently
+ * ignored.
+ * @param selector The selector used to determine what contents to delete,
may be <code>null</code> to delete
+ * everything.
* @param followSymlinks Whether to follow symlinks.
- * @param failOnError Whether to abort with an exception in case a
selected file/directory could not be deleted.
- * @param retryOnError Whether to undertake additional delete attempts
in case the first attempt failed.
+ * @param failOnError Whether to abort with an exception in case a
selected file/directory could not be deleted.
+ * @param retryOnError Whether to undertake additional delete attempts in
case the first attempt failed.
* @throws IOException If a file/directory could not be deleted and
<code>failOnError</code> is <code>true</code>.
*/
public void delete(
- File basedir, Selector selector, boolean followSymlinks, boolean
failOnError, boolean retryOnError)
+ Path basedir, Selector selector, boolean followSymlinks, boolean
failOnError, boolean retryOnError)
throws IOException {
- if (!basedir.isDirectory()) {
- if (!basedir.exists()) {
- if (log.isDebugEnabled()) {
- log.debug("Skipping non-existing directory " + basedir);
+ if (!Files.isDirectory(basedir)) {
+ if (!Files.exists(basedir)) {
+ if (logDebug != null) {
+ logDebug.log("Skipping non-existing directory " + basedir);
}
return;
}
throw new IOException("Invalid base directory " + basedir);
}
- if (log.isInfoEnabled()) {
- log.info("Deleting " + basedir + (selector != null ? " (" +
selector + ")" : ""));
+ if (logInfo != null) {
+ logInfo.log("Deleting " + basedir + (selector != null ? " (" +
selector + ")" : ""));
}
- File file = followSymlinks ? basedir : basedir.getCanonicalFile();
+ Path file = followSymlinks ? basedir : getCanonicalPath(basedir);
if (selector == null && !followSymlinks && fastDir != null && session
!= null) {
// If anything wrong happens, we'll just use the usual deletion
mechanism
@@ -124,9 +149,8 @@ class Cleaner {
delete(file, "", selector, followSymlinks, failOnError, retryOnError);
}
- private boolean fastDelete(File baseDirFile) {
- Path baseDir = baseDirFile.toPath();
- Path fastDir = this.fastDir.toPath();
+ private boolean fastDelete(Path baseDir) {
+ Path fastDir = this.fastDir;
// Handle the case where we use
${maven.multiModuleProjectDirectory}/target/.clean for example
if (fastDir.toAbsolutePath().startsWith(baseDir.toAbsolutePath())) {
try {
@@ -135,7 +159,7 @@ class Cleaner {
try {
Files.move(baseDir, tmpDir,
StandardCopyOption.REPLACE_EXISTING);
if (session != null) {
-
session.getRepositorySession().getData().set(LAST_DIRECTORY_TO_DELETE,
baseDir.toFile());
+ session.getData().set(LAST_DIRECTORY_TO_DELETE,
baseDir);
}
baseDir = tmpDir;
} catch (IOException e) {
@@ -143,8 +167,8 @@ class Cleaner {
throw e;
}
} catch (IOException e) {
- if (log.isDebugEnabled()) {
- log.debug("Unable to fast delete directory: ", e);
+ if (logDebug != null) {
+ logDebug.log("Unable to fast delete directory", e);
}
return false;
}
@@ -155,10 +179,10 @@ class Cleaner {
Files.createDirectories(fastDir);
}
} catch (IOException e) {
- if (log.isDebugEnabled()) {
- log.debug(
+ if (logDebug != null) {
+ logDebug.log(
"Unable to fast delete directory as the path " +
fastDir
- + " does not point to a directory or cannot be
created: ",
+ + " does not point to a directory or cannot be
created",
e);
}
return false;
@@ -172,11 +196,11 @@ class Cleaner {
// or any other exception occurs, an exception will be thrown in
which case
// the method will return false and the usual deletion will be
performed.
Files.move(baseDir, dstDir, StandardCopyOption.ATOMIC_MOVE);
- BackgroundCleaner.delete(this, tmpDir.toFile(), fastMode);
+ BackgroundCleaner.delete(this, tmpDir, fastMode);
return true;
} catch (IOException e) {
- if (log.isDebugEnabled()) {
- log.debug("Unable to fast delete directory: ", e);
+ if (logDebug != null) {
+ logDebug.log("Unable to fast delete directory", e);
}
return false;
}
@@ -185,20 +209,20 @@ class Cleaner {
/**
* Deletes the specified file or directory.
*
- * @param file The file/directory to delete, must not be
<code>null</code>. If <code>followSymlinks</code> is
- * <code>false</code>, it is assumed that the parent
file is canonical.
- * @param pathname The relative pathname of the file, using {@link
File#separatorChar}, must not be
- * <code>null</code>.
- * @param selector The selector used to determine what contents to
delete, may be <code>null</code> to delete
- * everything.
+ * @param file The file/directory to delete, must not be
<code>null</code>. If <code>followSymlinks</code> is
+ * <code>false</code>, it is assumed that the parent file is
canonical.
+ * @param pathname The relative pathname of the file, using {@link
File#separatorChar}, must not be
+ * <code>null</code>.
+ * @param selector The selector used to determine what contents to delete,
may be <code>null</code> to delete
+ * everything.
* @param followSymlinks Whether to follow symlinks.
- * @param failOnError Whether to abort with an exception in case a
selected file/directory could not be deleted.
- * @param retryOnError Whether to undertake additional delete attempts
in case the first attempt failed.
+ * @param failOnError Whether to abort with an exception in case a
selected file/directory could not be deleted.
+ * @param retryOnError Whether to undertake additional delete attempts in
case the first attempt failed.
* @return The result of the cleaning, never <code>null</code>.
* @throws IOException If a file/directory could not be deleted and
<code>failOnError</code> is <code>true</code>.
*/
private Result delete(
- File file,
+ Path file,
String pathname,
Selector selector,
boolean followSymlinks,
@@ -207,46 +231,43 @@ class Cleaner {
throws IOException {
Result result = new Result();
- boolean isDirectory = file.isDirectory();
+ boolean isDirectory = Files.isDirectory(file);
if (isDirectory) {
if (selector == null || selector.couldHoldSelected(pathname)) {
- if (followSymlinks || !isSymbolicLink(file.toPath())) {
- File canonical = followSymlinks ? file :
file.getCanonicalFile();
- String[] filenames = canonical.list();
- if (filenames != null) {
- String prefix = pathname.length() > 0 ? pathname +
File.separatorChar : "";
- for (int i = filenames.length - 1; i >= 0; i--) {
- String filename = filenames[i];
- File child = new File(canonical, filename);
+ final boolean isSymlink = isSymbolicLink(file);
+ Path canonical = followSymlinks ? file :
getCanonicalPath(file);
+ if (followSymlinks || !isSymlink) {
+ String prefix = !pathname.isEmpty() ? pathname +
File.separatorChar : "";
+ try (Stream<Path> children = Files.list(canonical)) {
+ for (Path child : children.toList()) {
result.update(delete(
- child, prefix + filename, selector,
followSymlinks, failOnError, retryOnError));
+ child,
+ prefix + child.getFileName(),
+ selector,
+ followSymlinks,
+ failOnError,
+ retryOnError));
}
}
- } else if (log.isDebugEnabled()) {
- log.debug("Not recursing into symlink " + file);
+ } else if (logDebug != null) {
+ logDebug.log("Not recursing into symlink " + file);
}
- } else if (log.isDebugEnabled()) {
- log.debug("Not recursing into directory without included files
" + file);
+ } else if (logDebug != null) {
+ logDebug.log("Not recursing into directory without included
files " + file);
}
}
if (!result.excluded && (selector == null ||
selector.isSelected(pathname))) {
- String logmessage;
- if (isDirectory) {
- logmessage = "Deleting directory " + file;
- } else if (file.exists()) {
- logmessage = "Deleting file " + file;
- } else {
- logmessage = "Deleting dangling symlink " + file;
- }
-
- if (verbose && log.isInfoEnabled()) {
- log.info(logmessage);
- } else if (log.isDebugEnabled()) {
- log.debug(logmessage);
+ if (logVerbose != null) {
+ if (isDirectory) {
+ logVerbose.log("Deleting directory " + file);
+ } else if (Files.exists(file)) {
+ logVerbose.log("Deleting file " + file);
+ } else {
+ logVerbose.log("Deleting dangling symlink " + file);
+ }
}
-
result.failures += delete(file, failOnError, retryOnError);
} else {
result.excluded = true;
@@ -255,6 +276,14 @@ class Cleaner {
return result;
}
+ private static Path getCanonicalPath(Path path) {
+ try {
+ return path.toRealPath();
+ } catch (IOException e) {
+ return
getCanonicalPath(path.getParent()).resolve(path.getFileName());
+ }
+ }
+
private boolean isSymbolicLink(Path path) throws IOException {
BasicFileAttributes attrs = Files.readAttributes(path,
BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
return attrs.isSymbolicLink()
@@ -262,19 +291,13 @@ class Cleaner {
|| (attrs.isDirectory() && attrs.isOther());
}
- /**
- * Deletes the specified file, directory. If the path denotes a symlink,
only the link is removed, its target is
- * left untouched.
- *
- * @param file The file/directory to delete, must not be
<code>null</code>.
- * @param failOnError Whether to abort with an exception in case the
file/directory could not be deleted.
- * @param retryOnError Whether to undertake additional delete attempts in
case the first attempt failed.
- * @return <code>0</code> if the file was deleted, <code>1</code>
otherwise.
- * @throws IOException If a file/directory could not be deleted and
<code>failOnError</code> is <code>true</code>.
- */
- private int delete(File file, boolean failOnError, boolean retryOnError)
throws IOException {
- if (!file.delete()) {
- boolean deleted = false;
+ private int delete(Path file, boolean failOnError, boolean retryOnError)
throws IOException {
+ try {
+ Files.deleteIfExists(file);
+ return 0;
+ } catch (IOException e) {
+ IOException exception = new IOException("Failed to delete " +
file);
+ exception.addSuppressed(e);
if (retryOnError) {
if (ON_WINDOWS) {
@@ -283,24 +306,27 @@ class Cleaner {
}
final int[] delays = {50, 250, 750};
- for (int i = 0; !deleted && i < delays.length; i++) {
+ for (int delay : delays) {
try {
- Thread.sleep(delays[i]);
- } catch (InterruptedException e) {
- // ignore
+ Thread.sleep(delay);
+ } catch (InterruptedException e2) {
+ exception.addSuppressed(e2);
+ }
+ try {
+ Files.deleteIfExists(file);
+ return 0;
+ } catch (IOException e2) {
+ exception.addSuppressed(e2);
}
- deleted = file.delete() || !file.exists();
}
- } else {
- deleted = !file.exists();
}
- if (!deleted) {
+ if (Files.exists(file)) {
if (failOnError) {
- throw new IOException("Failed to delete " + file);
+ throw new IOException("Failed to delete " + file,
exception);
} else {
- if (log.isWarnEnabled()) {
- log.warn("Failed to delete " + file);
+ if (logWarn != null) {
+ logWarn.log("Failed to delete " + file, exception);
}
return 1;
}
@@ -322,25 +348,30 @@ class Cleaner {
}
}
+ private interface Logger {
+
+ void log(CharSequence message);
+
+ void log(CharSequence message, Throwable t);
+ }
+
private static class BackgroundCleaner extends Thread {
- private static final int NEW = 0;
- private static final int RUNNING = 1;
- private static final int STOPPED = 2;
private static BackgroundCleaner instance;
- private final Deque<File> filesToDelete = new ArrayDeque<>();
+
+ private final Deque<Path> filesToDelete = new ArrayDeque<>();
+
private final Cleaner cleaner;
+
private final String fastMode;
- private int status = NEW;
- private BackgroundCleaner(Cleaner cleaner, File dir, String fastMode) {
- super("mvn-background-cleaner");
- this.cleaner = cleaner;
- this.fastMode = fastMode;
- init(cleaner.fastDir, dir);
- }
+ private static final int NEW = 0;
+ private static final int RUNNING = 1;
+ private static final int STOPPED = 2;
- public static void delete(Cleaner cleaner, File dir, String fastMode) {
+ private int status = NEW;
+
+ public static void delete(Cleaner cleaner, Path dir, String fastMode) {
synchronized (BackgroundCleaner.class) {
if (instance == null || !instance.doDelete(dir)) {
instance = new BackgroundCleaner(cleaner, dir, fastMode);
@@ -356,9 +387,16 @@ class Cleaner {
}
}
+ private BackgroundCleaner(Cleaner cleaner, Path dir, String fastMode) {
+ super("mvn-background-cleaner");
+ this.cleaner = cleaner;
+ this.fastMode = fastMode;
+ init(cleaner.fastDir, dir);
+ }
+
public void run() {
while (true) {
- File basedir = pollNext();
+ Path basedir = pollNext();
if (basedir == null) {
break;
}
@@ -370,24 +408,25 @@ class Cleaner {
}
}
- synchronized void init(File fastDir, File dir) {
- if (fastDir.isDirectory()) {
- File[] children = fastDir.listFiles();
- if (children != null && children.length > 0) {
- for (File child : children) {
- doDelete(child);
+ synchronized void init(Path fastDir, Path dir) {
+ if (Files.isDirectory(fastDir)) {
+ try {
+ try (Stream<Path> children = Files.list(fastDir)) {
+ children.forEach(this::doDelete);
}
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
}
doDelete(dir);
}
- synchronized File pollNext() {
- File basedir = filesToDelete.poll();
+ synchronized Path pollNext() {
+ Path basedir = filesToDelete.poll();
if (basedir == null) {
if (cleaner.session != null) {
- SessionData data =
cleaner.session.getRepositorySession().getData();
- File lastDir = (File) data.get(LAST_DIRECTORY_TO_DELETE);
+ SessionData data = cleaner.session.getData();
+ Path lastDir = (Path) data.get(LAST_DIRECTORY_TO_DELETE);
if (lastDir != null) {
data.set(LAST_DIRECTORY_TO_DELETE, null);
return lastDir;
@@ -399,7 +438,7 @@ class Cleaner {
return basedir;
}
- synchronized boolean doDelete(File dir) {
+ synchronized boolean doDelete(Path dir) {
if (status == STOPPED) {
return false;
}
@@ -421,15 +460,10 @@ class Cleaner {
* to outlive its main execution.
*/
private void wrapExecutionListener() {
- ExecutionListener executionListener =
cleaner.session.getRequest().getExecutionListener();
- if (executionListener == null
- || !Proxy.isProxyClass(executionListener.getClass())
- || !(Proxy.getInvocationHandler(executionListener)
instanceof SpyInvocationHandler)) {
- ExecutionListener listener = (ExecutionListener)
Proxy.newProxyInstance(
- ExecutionListener.class.getClassLoader(),
- new Class[] {ExecutionListener.class},
- new SpyInvocationHandler(executionListener));
- cleaner.session.getRequest().setExecutionListener(listener);
+ synchronized (CleanerListener.class) {
+ if (cleaner.session.getListeners().stream().noneMatch(l -> l
instanceof CleanerListener)) {
+ cleaner.session.registerListener(new CleanerListener());
+ }
}
}
@@ -440,8 +474,8 @@ class Cleaner {
}
if (!FAST_MODE_DEFER.equals(fastMode)) {
try {
- if (cleaner.log.isInfoEnabled()) {
- cleaner.log.info("Waiting for background file
deletion");
+ if (cleaner.logInfo != null) {
+ cleaner.logInfo.log("Waiting for background file
deletion");
}
while (status != STOPPED) {
wait();
@@ -454,22 +488,12 @@ class Cleaner {
}
}
- static class SpyInvocationHandler implements InvocationHandler {
- private final ExecutionListener delegate;
-
- SpyInvocationHandler(ExecutionListener delegate) {
- this.delegate = delegate;
- }
-
+ static class CleanerListener implements Listener {
@Override
- public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
- if ("sessionEnded".equals(method.getName())) {
+ public void onEvent(Event event) {
+ if (event.getType() == EventType.SESSION_ENDED) {
BackgroundCleaner.sessionEnd();
}
- if (delegate != null) {
- return method.invoke(delegate, args);
- }
- return null;
}
}
}
diff --git a/src/main/java/org/apache/maven/plugins/clean/Fileset.java
b/src/main/java/org/apache/maven/plugins/clean/Fileset.java
index ecd88b0..7508411 100644
--- a/src/main/java/org/apache/maven/plugins/clean/Fileset.java
+++ b/src/main/java/org/apache/maven/plugins/clean/Fileset.java
@@ -18,7 +18,7 @@
*/
package org.apache.maven.plugins.clean;
-import java.io.File;
+import java.nio.file.Path;
import java.util.Arrays;
/**
@@ -32,7 +32,7 @@ import java.util.Arrays;
*/
public class Fileset {
- private File directory;
+ private Path directory;
private String[] includes;
@@ -45,7 +45,7 @@ public class Fileset {
/**
* @return {@link #directory}
*/
- public File getDirectory() {
+ public Path getDirectory() {
return directory;
}
diff --git a/src/site/apt/examples/delete_additional_files.apt.vm
b/src/site/apt/examples/delete_additional_files.apt.vm
index 0fa768c..84ed079 100644
--- a/src/site/apt/examples/delete_additional_files.apt.vm
+++ b/src/site/apt/examples/delete_additional_files.apt.vm
@@ -68,7 +68,7 @@ Delete Additional Files Not Exposed to Maven
is equivalent to:
+--------
- <directory>${project.basedir}/some/relative/path</directory>
+ <directory>${basedir}/some/relative/path</directory>
+--------
You could also define file set rules in a parent POM. In this case, the clean
plugin adds the subproject
diff --git a/src/test/java/org/apache/maven/plugins/clean/CleanMojoTest.java
b/src/test/java/org/apache/maven/plugins/clean/CleanMojoTest.java
index 22287d7..5a5d0d4 100644
--- a/src/test/java/org/apache/maven/plugins/clean/CleanMojoTest.java
+++ b/src/test/java/org/apache/maven/plugins/clean/CleanMojoTest.java
@@ -29,17 +29,17 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.logging.SystemStreamLog;
-import org.apache.maven.plugin.testing.junit5.InjectMojo;
-import org.apache.maven.plugin.testing.junit5.MojoTest;
+import org.apache.maven.api.plugin.MojoException;
+import org.apache.maven.api.plugin.testing.Basedir;
+import org.apache.maven.api.plugin.testing.InjectMojo;
+import org.apache.maven.api.plugin.testing.MojoTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
-import static
org.apache.maven.plugin.testing.junit5.MojoExtension.setVariableValueToObject;
-import static org.codehaus.plexus.testing.PlexusExtension.getBasedir;
+import static org.apache.maven.api.plugin.testing.MojoExtension.getBasedir;
+import static
org.apache.maven.api.plugin.testing.MojoExtension.setVariableValueToObject;
import static org.codehaus.plexus.util.IOUtil.copy;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -49,30 +49,25 @@ import static org.junit.jupiter.api.Assertions.fail;
/**
* Test the clean mojo.
- *
- * @author <a href="mailto:[email protected]">Vincent Siveton</a>
*/
@MojoTest
-class CleanMojoTest {
+public class CleanMojoTest {
+ private static final String LOCAL_REPO = "target/local-repo/";
+
/**
* Tests the simple removal of directories
*
* @throws Exception in case of an error.
*/
@Test
- @InjectMojo(goal = "clean", pom =
"classpath:/unit/basic-clean-test/plugin-pom.xml")
- void testBasicClean(CleanMojo mojo) throws Exception {
+ @Basedir("${basedir}/target/test-classes/unit/basic-clean-test")
+ @InjectMojo(goal = "clean")
+ public void testBasicClean(CleanMojo mojo) throws Exception {
mojo.execute();
- assertFalse(
- checkExists(getBasedir() + "/target/test-classes/unit/" +
"basic-clean-test/buildDirectory"),
- "Directory exists");
- assertFalse(
- checkExists(getBasedir() +
"/target/test-classes/unit/basic-clean-test/" + "buildOutputDirectory"),
- "Directory exists");
- assertFalse(
- checkExists(getBasedir() +
"/target/test-classes/unit/basic-clean-test/" + "buildTestDirectory"),
- "Directory exists");
+ assertFalse(checkExists(getBasedir() + "/buildDirectory"), "Directory
exists");
+ assertFalse(checkExists(getBasedir() + "/buildOutputDirectory"),
"Directory exists");
+ assertFalse(checkExists(getBasedir() + "/buildTestDirectory"),
"Directory exists");
}
/**
@@ -81,13 +76,14 @@ class CleanMojoTest {
* @throws Exception in case of an error.
*/
@Test
- @InjectMojo(goal = "clean", pom =
"classpath:/unit/nested-clean-test/plugin-pom.xml")
- void testCleanNestedStructure(CleanMojo mojo) throws Exception {
+ @Basedir("${basedir}/target/test-classes/unit/nested-clean-test")
+ @InjectMojo(goal = "clean")
+ public void testCleanNestedStructure(CleanMojo mojo) throws Exception {
mojo.execute();
- assertFalse(checkExists(getBasedir() +
"/target/test-classes/unit/nested-clean-test/target"));
- assertFalse(checkExists(getBasedir() +
"/target/test-classes/unit/nested-clean-test/target/classes"));
- assertFalse(checkExists(getBasedir() +
"/target/test-classes/unit/nested-clean-test/target/test-classes"));
+ assertFalse(checkExists(getBasedir() + "/target"));
+ assertFalse(checkExists(getBasedir() + "/target/classes"));
+ assertFalse(checkExists(getBasedir() + "/target/test-classes"));
}
/**
@@ -97,17 +93,15 @@ class CleanMojoTest {
* @throws Exception in case of an error.
*/
@Test
- @InjectMojo(goal = "clean", pom =
"classpath:/unit/empty-clean-test/plugin-pom.xml")
- void testCleanEmptyDirectories(CleanMojo mojo) throws Exception {
+ @Basedir("${basedir}/target/test-classes/unit/empty-clean-test")
+ @InjectMojo(goal = "clean")
+ public void testCleanEmptyDirectories(CleanMojo mojo) throws Exception {
mojo.execute();
- assertTrue(checkExists(getBasedir() +
"/target/test-classes/unit/empty-clean-test/testDirectoryStructure"));
- assertTrue(checkExists(
- getBasedir() + "/target/test-classes/unit/empty-clean-test/" +
"testDirectoryStructure/file.txt"));
- assertTrue(checkExists(getBasedir() +
"/target/test-classes/unit/empty-clean-test/"
- + "testDirectoryStructure/outputDirectory"));
- assertTrue(checkExists(getBasedir() +
"/target/test-classes/unit/empty-clean-test/"
- + "testDirectoryStructure/outputDirectory/file.txt"));
+ assertTrue(checkExists(getBasedir() + "/testDirectoryStructure"));
+ assertTrue(checkExists(getBasedir() +
"/testDirectoryStructure/file.txt"));
+ assertTrue(checkExists(getBasedir() +
"/testDirectoryStructure/outputDirectory"));
+ assertTrue(checkExists(getBasedir() +
"/testDirectoryStructure/outputDirectory/file.txt"));
}
/**
@@ -116,25 +110,24 @@ class CleanMojoTest {
* @throws Exception in case of an error.
*/
@Test
- @InjectMojo(goal = "clean", pom =
"classpath:/unit/fileset-clean-test/plugin-pom.xml")
- void testFilesetsClean(CleanMojo mojo) throws Exception {
+ @Basedir("${basedir}/target/test-classes/unit/fileset-clean-test")
+ @InjectMojo(goal = "clean")
+ public void testFilesetsClean(CleanMojo mojo) throws Exception {
mojo.execute();
// fileset 1
- assertTrue(checkExists(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/target"));
- assertTrue(checkExists(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/target/classes"));
- assertFalse(checkExists(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/target/test-classes"));
- assertTrue(checkExists(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/target/subdir"));
- assertFalse(checkExists(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/target/classes/file.txt"));
- assertTrue(checkEmpty(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/target/classes"));
- assertFalse(checkEmpty(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/target/subdir"));
- assertTrue(checkExists(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/target/subdir/file.txt"));
+ assertTrue(checkExists(getBasedir() + "/target"));
+ assertTrue(checkExists(getBasedir() + "/target/classes"));
+ assertFalse(checkExists(getBasedir() + "/target/test-classes"));
+ assertTrue(checkExists(getBasedir() + "/target/subdir"));
+ assertFalse(checkExists(getBasedir() + "/target/classes/file.txt"));
+ assertTrue(checkEmpty(getBasedir() + "/target/classes"));
+ assertFalse(checkEmpty(getBasedir() + "/target/subdir"));
+ assertTrue(checkExists(getBasedir() + "/target/subdir/file.txt"));
// fileset 2
- assertTrue(
- checkExists(getBasedir() +
"/target/test-classes/unit/fileset-clean-test/" + "buildOutputDirectory"));
- assertFalse(checkExists(
- getBasedir() + "/target/test-classes/unit/fileset-clean-test/"
+ "buildOutputDirectory/file.txt"));
+ assertTrue(checkExists(getBasedir() + "/" + "buildOutputDirectory"));
+ assertFalse(checkExists(getBasedir() + "/" +
"buildOutputDirectory/file.txt"));
}
/**
@@ -143,9 +136,10 @@ class CleanMojoTest {
* @throws Exception in case of an error.
*/
@Test
- @InjectMojo(goal = "clean", pom =
"classpath:/unit/invalid-directory-test/plugin-pom.xml")
- void testCleanInvalidDirectory(CleanMojo mojo) throws Exception {
- assertThrows(MojoExecutionException.class, mojo::execute);
+ @Basedir("${basedir}/target/test-classes/unit/invalid-directory-test")
+ @InjectMojo(goal = "clean")
+ public void testCleanInvalidDirectory(CleanMojo mojo) throws Exception {
+ assertThrows(MojoException.class, mojo::execute, "Should fail to
delete a file treated as a directory");
}
/**
@@ -154,11 +148,12 @@ class CleanMojoTest {
* @throws Exception in case of an error.
*/
@Test
- @InjectMojo(goal = "clean", pom =
"classpath:/unit/missing-directory-test/plugin-pom.xml")
- void testMissingDirectory(CleanMojo mojo) throws Exception {
+ @Basedir("${basedir}/target/test-classes/unit/missing-directory-test")
+ @InjectMojo(goal = "clean")
+ public void testMissingDirectory(CleanMojo mojo) throws Exception {
mojo.execute();
- assertFalse(checkExists(getBasedir() +
"/target/test-classes/unit/missing-directory-test/does-not-exist"));
+ assertFalse(checkExists(getBasedir() + "/does-not-exist"));
}
/**
@@ -171,14 +166,15 @@ class CleanMojoTest {
*/
@Test
@EnabledOnOs(OS.WINDOWS)
- @InjectMojo(goal = "clean", pom =
"classpath:/unit/locked-file-test/plugin-pom.xml")
- void testCleanLockedFile(CleanMojo mojo) throws Exception {
- File f = new File(getBasedir(),
"target/test-classes/unit/locked-file-test/buildDirectory/file.txt");
+ @Basedir("${basedir}/target/test-classes/unit/locked-file-test")
+ @InjectMojo(goal = "clean")
+ public void testCleanLockedFile(CleanMojo mojo) throws Exception {
+ File f = new File(getBasedir(), "buildDirectory/file.txt");
try (FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
FileLock ignored = channel.lock()) {
mojo.execute();
fail("Should fail to delete a file that is locked");
- } catch (MojoExecutionException expected) {
+ } catch (MojoException expected) {
assertTrue(true);
}
}
@@ -193,29 +189,29 @@ class CleanMojoTest {
*/
@Test
@EnabledOnOs(OS.WINDOWS)
- @InjectMojo(goal = "clean", pom =
"classpath:/unit/locked-file-test/plugin-pom.xml")
- void testCleanLockedFileWithNoError(CleanMojo mojo) throws Exception {
+ @Basedir("${basedir}/target/test-classes/unit/locked-file-test")
+ @InjectMojo(goal = "clean")
+ public void testCleanLockedFileWithNoError(CleanMojo mojo) throws
Exception {
setVariableValueToObject(mojo, "failOnError", Boolean.FALSE);
assertNotNull(mojo);
- File f = new File(getBasedir(),
"target/test-classes/unit/locked-file-test/buildDirectory/file.txt");
+ File f = new File(getBasedir(), "buildDirectory/file.txt");
try (FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
FileLock ignored = channel.lock()) {
mojo.execute();
assertTrue(true);
- } catch (MojoExecutionException expected) {
+ } catch (MojoException expected) {
fail("Should display a warning when deleting a file that is
locked");
}
}
/**
* Test the followLink option with windows junctions
- *
* @throws Exception
*/
@Test
@EnabledOnOs(OS.WINDOWS)
- void testFollowLinksWithWindowsJunction() throws Exception {
+ public void testFollowLinksWithWindowsJunction() throws Exception {
testSymlink((link, target) -> {
Process process = new ProcessBuilder()
.directory(link.getParent().toFile())
@@ -233,12 +229,11 @@ class CleanMojoTest {
/**
* Test the followLink option with sym link
- *
* @throws Exception
*/
@Test
@DisabledOnOs(OS.WINDOWS)
- void testFollowLinksWithSymLinkOnPosix() throws Exception {
+ public void testFollowLinksWithSymLinkOnPosix() throws Exception {
testSymlink((link, target) -> {
try {
Files.createSymbolicLink(link, target);
@@ -248,9 +243,13 @@ class CleanMojoTest {
});
}
+ @FunctionalInterface
+ interface LinkCreator {
+ void createLink(Path link, Path target) throws Exception;
+ }
+
private void testSymlink(LinkCreator linkCreator) throws Exception {
- // We use the SystemStreamLog() as the AbstractMojo class, because
from there the Log is always provided
- Cleaner cleaner = new Cleaner(null, new SystemStreamLog(), false,
null, null);
+ Cleaner cleaner = new Cleaner(null, null, false, null, null);
Path testDir =
Paths.get("target/test-classes/unit/test-dir").toAbsolutePath();
Path dirWithLnk = testDir.resolve("dir");
Path orgDir = testDir.resolve("org-dir");
@@ -263,7 +262,7 @@ class CleanMojoTest {
Files.write(file, Collections.singleton("Hello world"));
linkCreator.createLink(jctDir, orgDir);
// delete
- cleaner.delete(dirWithLnk.toFile(), null, false, true, false);
+ cleaner.delete(dirWithLnk, null, false, true, false);
// verify
assertTrue(Files.exists(file));
assertFalse(Files.exists(jctDir));
@@ -276,7 +275,7 @@ class CleanMojoTest {
Files.write(file, Collections.singleton("Hello world"));
linkCreator.createLink(jctDir, orgDir);
// delete
- cleaner.delete(dirWithLnk.toFile(), null, true, true, false);
+ cleaner.delete(dirWithLnk, null, true, true, false);
// verify
assertFalse(Files.exists(file));
assertFalse(Files.exists(jctDir));
@@ -284,6 +283,32 @@ class CleanMojoTest {
assertFalse(Files.exists(dirWithLnk));
}
+ // @Provides
+ // @Singleton
+ // private Project createProject() {
+ // ProjectStub project = new ProjectStub();
+ // project.setGroupId("myGroupId");
+ // return project;
+ // }
+
+ // @Provides
+ // @Singleton
+ // @SuppressWarnings("unused")
+ // private InternalSession createSession() {
+ // InternalSession session = SessionStub.getMockSession(LOCAL_REPO);
+ // Properties props = new Properties();
+ // props.put("basedir", MojoExtension.getBasedir());
+ // doReturn(props).when(session).getSystemProperties();
+ // return session;
+ // }
+
+ // @Provides
+ // @Singleton
+ // @SuppressWarnings("unused")
+ // private MojoExecution createMojoExecution() {
+ // return new MojoExecutionStub("default-clean", "clean");
+ // }
+
/**
* @param dir a dir or a file
* @return true if a file/dir exists, false otherwise
@@ -300,9 +325,4 @@ class CleanMojoTest {
File[] files = new File(dir).listFiles();
return files == null || files.length == 0;
}
-
- @FunctionalInterface
- interface LinkCreator {
- void createLink(Path link, Path target) throws Exception;
- }
}
diff --git a/src/test/resources/unit/basic-clean-test/plugin-pom.xml
b/src/test/resources/unit/basic-clean-test/plugin-pom.xml
deleted file mode 100644
index 38a6000..0000000
--- a/src/test/resources/unit/basic-clean-test/plugin-pom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
- 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.
--->
-
-<project>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <configuration>
-
<directory>${basedir}/target/test-classes/unit/basic-clean-test/buildDirectory</directory>
-
<outputDirectory>${basedir}/target/test-classes/unit/basic-clean-test/buildOutputDirectory</outputDirectory>
-
<testOutputDirectory>${basedir}/target/test-classes/unit/basic-clean-test/buildTestDirectory</testOutputDirectory>
- <verbose>true</verbose>
- <failOnError>true</failOnError>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/src/test/resources/unit/locked-file-test/plugin-pom.xml
b/src/test/resources/unit/basic-clean-test/pom.xml
similarity index 81%
copy from src/test/resources/unit/locked-file-test/plugin-pom.xml
copy to src/test/resources/unit/basic-clean-test/pom.xml
index 4101091..ba901f0 100644
--- a/src/test/resources/unit/locked-file-test/plugin-pom.xml
+++ b/src/test/resources/unit/basic-clean-test/pom.xml
@@ -23,7 +23,9 @@
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
-
<directory>${basedir}/target/test-classes/unit/locked-file-test/buildDirectory</directory>
+ <directory>${project.basedir}/buildDirectory</directory>
+
<outputDirectory>${project.basedir}/buildOutputDirectory</outputDirectory>
+
<testOutputDirectory>${project.basedir}/buildTestDirectory</testOutputDirectory>
<verbose>true</verbose>
<failOnError>true</failOnError>
</configuration>
diff --git a/src/test/resources/unit/empty-clean-test/plugin-pom.xml
b/src/test/resources/unit/empty-clean-test/pom.xml
similarity index 100%
rename from src/test/resources/unit/empty-clean-test/plugin-pom.xml
rename to src/test/resources/unit/empty-clean-test/pom.xml
diff --git a/src/test/resources/unit/fileset-clean-test/plugin-pom.xml
b/src/test/resources/unit/fileset-clean-test/pom.xml
similarity index 88%
rename from src/test/resources/unit/fileset-clean-test/plugin-pom.xml
rename to src/test/resources/unit/fileset-clean-test/pom.xml
index 5cd3ab3..2457c4e 100644
--- a/src/test/resources/unit/fileset-clean-test/plugin-pom.xml
+++ b/src/test/resources/unit/fileset-clean-test/pom.xml
@@ -23,9 +23,10 @@
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
+ <excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
-
<directory>${basedir}/target/test-classes/unit/fileset-clean-test/target</directory>
+ <directory>${project.basedir}/target</directory>
<includes>
<include>**/file.txt</include>
<include>**/test-classes/**</include>
@@ -35,7 +36,7 @@
</excludes>
</fileset>
<fileset>
-
<directory>${basedir}/target/test-classes/unit/fileset-clean-test/buildOutputDirectory</directory>
+ <directory>${project.basedir}/buildOutputDirectory</directory>
<includes>
<include>**</include>
</includes>
diff --git a/src/test/resources/unit/locked-file-test/plugin-pom.xml
b/src/test/resources/unit/invalid-directory-test/pom.xml
similarity index 91%
copy from src/test/resources/unit/locked-file-test/plugin-pom.xml
copy to src/test/resources/unit/invalid-directory-test/pom.xml
index 4101091..5d35e78 100644
--- a/src/test/resources/unit/locked-file-test/plugin-pom.xml
+++ b/src/test/resources/unit/invalid-directory-test/pom.xml
@@ -23,7 +23,7 @@
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
-
<directory>${basedir}/target/test-classes/unit/locked-file-test/buildDirectory</directory>
+ <directory>${project.basedir}/this-is-a-file</directory>
<verbose>true</verbose>
<failOnError>true</failOnError>
</configuration>
diff --git a/src/test/resources/unit/missing-directory-test/plugin-pom.xml
b/src/test/resources/unit/locked-file-test/pom.xml
similarity index 91%
rename from src/test/resources/unit/missing-directory-test/plugin-pom.xml
rename to src/test/resources/unit/locked-file-test/pom.xml
index 15b3923..1f2f429 100644
--- a/src/test/resources/unit/missing-directory-test/plugin-pom.xml
+++ b/src/test/resources/unit/locked-file-test/pom.xml
@@ -23,7 +23,7 @@
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
-
<directory>${basedir}/target/test-classes/unit/missing-clean-test/does-not-exist</directory>
+ <directory>${project.basedir}/buildDirectory</directory>
<verbose>true</verbose>
<failOnError>true</failOnError>
</configuration>
diff --git a/src/test/resources/unit/invalid-directory-test/plugin-pom.xml
b/src/test/resources/unit/missing-directory-test/pom.xml
similarity index 91%
rename from src/test/resources/unit/invalid-directory-test/plugin-pom.xml
rename to src/test/resources/unit/missing-directory-test/pom.xml
index b562122..ec695d1 100644
--- a/src/test/resources/unit/invalid-directory-test/plugin-pom.xml
+++ b/src/test/resources/unit/missing-directory-test/pom.xml
@@ -23,7 +23,7 @@
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
-
<directory>${basedir}/target/test-classes/unit/invalid-directory-test/this-is-a-file</directory>
+ <directory>${project.basedir}/does-not-exist</directory>
<verbose>true</verbose>
<failOnError>true</failOnError>
</configuration>
diff --git a/src/test/resources/unit/nested-clean-test/plugin-pom.xml
b/src/test/resources/unit/nested-clean-test/plugin-pom.xml
deleted file mode 100644
index 790d14d..0000000
--- a/src/test/resources/unit/nested-clean-test/plugin-pom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
- 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.
--->
-
-<project>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <configuration>
-
<directory>${basedir}/target/test-classes/unit/nested-clean-test/target</directory>
-
<outputDirectory>${basedir}/target/test-classes/unit/nested-clean-test/target/classes</outputDirectory>
-
<testOutputDirectory>${basedir}/target/test-classes/unit/nested-clean-test/target/test-classes</testOutputDirectory>
- <verbose>true</verbose>
- <failOnError>true</failOnError>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/src/test/resources/unit/locked-file-test/plugin-pom.xml
b/src/test/resources/unit/nested-clean-test/pom.xml
similarity index 82%
rename from src/test/resources/unit/locked-file-test/plugin-pom.xml
rename to src/test/resources/unit/nested-clean-test/pom.xml
index 4101091..5f9e755 100644
--- a/src/test/resources/unit/locked-file-test/plugin-pom.xml
+++ b/src/test/resources/unit/nested-clean-test/pom.xml
@@ -23,7 +23,9 @@
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
-
<directory>${basedir}/target/test-classes/unit/locked-file-test/buildDirectory</directory>
+ <directory>${project.basedir}/target</directory>
+ <outputDirectory>${project.basedir}/target/classes</outputDirectory>
+
<testOutputDirectory>${project.basedir}/target/test-classes</testOutputDirectory>
<verbose>true</verbose>
<failOnError>true</failOnError>
</configuration>