New Upstream Release - maven-clean-plugin
Ready changes
Summary
Merged new upstream version: 3.3.1 (was: 3.2.0).
Diff
diff --git a/.asf.yaml b/.asf.yaml
index 9709dda..853ac71 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -24,3 +24,14 @@ github:
- maven-plugins
- maven-clean-plugin
- maven
+ enabled_merge_buttons:
+ squash: true
+ merge: false
+ rebase: true
+ autolink_jira:
+ - MCLEAN
+notifications:
+ commits: commits@maven.apache.org
+ issues: issues@maven.apache.org
+ pullrequests: issues@maven.apache.org
+ jira_options: link label comment
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 0000000..b5ce43a
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+# Change maven code style
+7b053970f4b9443651fa5dffe42c8b025c596dff
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index f0138ad..d5588b4 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -20,6 +20,9 @@ updates:
directory: "/"
schedule:
interval: "daily"
+ ignore:
+ # Ignore Maven Core updates
+ - dependency-name: "org.apache.maven:*"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml
index bbd7786..4d67fdc 100644
--- a/.github/workflows/maven-verify.yml
+++ b/.github/workflows/maven-verify.yml
@@ -24,4 +24,4 @@ on:
jobs:
build:
name: Verify
- uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v2
+ uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v3
diff --git a/README.md b/README.md
index ec63879..5e3a867 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ Contributing to [Apache Maven Clean Plugin](https://maven.apache.org/plugins/mav
[![ASF Jira](https://img.shields.io/endpoint?url=https%3A%2F%2Fmaven.apache.org%2Fbadges%2Fasf_jira-MCLEAN.json)][jira]
[![Apache License, Version 2.0, January 2004](https://img.shields.io/github/license/apache/maven.svg?label=License)][license]
[![Maven Central](https://img.shields.io/maven-central/v/org.apache.maven.plugins/maven-clean-plugin.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.apache.maven.plugins/maven-clean-plugin)
+[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/org/apache/maven/plugins/maven-clean-plugin/README.md)
[![Jenkins Status](https://img.shields.io/jenkins/s/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-clean-plugin/job/master.svg?)][build]
[![Jenkins tests](https://img.shields.io/jenkins/t/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-clean-plugin/job/master.svg?)][test-results]
diff --git a/debian/changelog b/debian/changelog
index 6daf752..91b4a59 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+maven-clean-plugin (3.3.1-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Fri, 28 Jul 2023 07:10:56 -0000
+
maven-clean-plugin (3.2.0-2) unstable; urgency=medium
* Depend on libmaven-parent-java (Closes: #1028850)
diff --git a/pom.xml b/pom.xml
index a1c52cf..fdf0c5f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,4 @@
-<?xml version='1.0' encoding='UTF-8'?>
-
+<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -18,25 +17,22 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugins</artifactId>
- <version>35</version>
+ <version>39</version>
<relativePath />
</parent>
<artifactId>maven-clean-plugin</artifactId>
- <version>3.2.0</version>
+ <version>3.3.1</version>
<packaging>maven-plugin</packaging>
<name>Apache Maven Clean Plugin</name>
- <description>
- The Maven Clean Plugin is a plugin that removes files generated at build-time in a project's directory.
- </description>
+ <description>The Maven Clean Plugin is a plugin that removes files generated at build-time in a project's directory.</description>
<inceptionYear>2001</inceptionYear>
<prerequisites>
@@ -46,8 +42,8 @@ under the License.
<scm>
<connection>scm:git:https://gitbox.apache.org/repos/asf/maven-clean-plugin.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-clean-plugin.git</developerConnection>
+ <tag>maven-clean-plugin-3.3.1</tag>
<url>https://github.com/apache/maven-clean-plugin/tree/${project.scm.tag}</url>
- <tag>maven-clean-plugin-3.2.0</tag>
</scm>
<issueManagement>
<system>JIRA</system>
@@ -55,7 +51,7 @@ under the License.
</issueManagement>
<ciManagement>
<system>Jenkins</system>
- <url>https://ci-builds.apache.org/job/Maven/job/maven-box/job/maven-clean-plugin/</url>
+ <url>https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-clean-plugin/</url>
</ciManagement>
<distributionManagement>
<site>
@@ -66,10 +62,7 @@ under the License.
<properties>
<mavenVersion>3.2.5</mavenVersion>
- <javaVersion>8</javaVersion>
- <surefire.version>2.22.2</surefire.version>
- <mavenPluginToolsVersion>3.6.4</mavenPluginToolsVersion>
- <project.build.outputTimestamp>2022-04-01T21:20:29Z</project.build.outputTimestamp>
+ <project.build.outputTimestamp>2023-06-14T18:50:40Z</project.build.outputTimestamp>
</properties>
<dependencies>
@@ -80,9 +73,15 @@ under the License.
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.apache.maven.shared</groupId>
- <artifactId>maven-shared-utils</artifactId>
- <version>3.3.4</version>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>4.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-xml</artifactId>
+ <version>4.0.0</version>
+ <scope>provided</scope>
</dependency>
<!-- dependencies to annotations -->
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 4b5ba86..3dff361 100644
--- a/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java
+++ b/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugins.clean;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,6 +16,10 @@ package org.apache.maven.plugins.clean;
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.maven.plugins.clean;
+
+import java.io.File;
+import java.io.IOException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
@@ -25,9 +27,6 @@ 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>
@@ -44,10 +43,8 @@ import java.io.IOException;
* @see org.apache.maven.plugins.clean.Fileset
* @since 2.0
*/
-@Mojo( name = "clean", threadSafe = true )
-public class CleanMojo
- extends AbstractMojo
-{
+@Mojo(name = "clean", threadSafe = true)
+public class CleanMojo extends AbstractMojo {
public static final String FAST_MODE_BACKGROUND = "background";
@@ -58,19 +55,19 @@ public class CleanMojo
/**
* This is where build results go.
*/
- @Parameter( defaultValue = "${project.build.directory}", readonly = true, required = true )
+ @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 )
+ @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 )
+ @Parameter(defaultValue = "${project.build.testOutputDirectory}", readonly = true, required = true)
private File testOutputDirectory;
/**
@@ -78,7 +75,7 @@ public class CleanMojo
*
* @since 2.1.1
*/
- @Parameter( defaultValue = "${project.build.outputDirectory}", readonly = true, required = true )
+ @Parameter(defaultValue = "${project.build.outputDirectory}", readonly = true, required = true)
private File reportDirectory;
/**
@@ -86,15 +83,15 @@ public class CleanMojo
* 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" )
+ @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>
@@ -123,20 +120,20 @@ public class CleanMojo
* 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" )
+ @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" )
+ @Parameter(property = "maven.clean.skip", defaultValue = "false")
private boolean skip;
/**
@@ -144,7 +141,7 @@ public class CleanMojo
*
* @since 2.2
*/
- @Parameter( property = "maven.clean.failOnError", defaultValue = "true" )
+ @Parameter(property = "maven.clean.failOnError", defaultValue = "true")
private boolean failOnError;
/**
@@ -154,7 +151,7 @@ public class CleanMojo
*
* @since 2.4.2
*/
- @Parameter( property = "maven.clean.retryOnError", defaultValue = "true" )
+ @Parameter(property = "maven.clean.retryOnError", defaultValue = "true")
private boolean retryOnError;
/**
@@ -165,7 +162,7 @@ public class CleanMojo
*
* @since 2.3
*/
- @Parameter( property = "maven.clean.excludeDefaultDirectories", defaultValue = "false" )
+ @Parameter(property = "maven.clean.excludeDefaultDirectories", defaultValue = "false")
private boolean excludeDefaultDirectories;
/**
@@ -177,7 +174,7 @@ public class CleanMojo
*
* @since 3.2
*/
- @Parameter( property = "maven.clean.fast", defaultValue = "false" )
+ @Parameter(property = "maven.clean.fast", defaultValue = "false")
private boolean fast;
/**
@@ -192,7 +189,7 @@ public class CleanMojo
* @since 3.2
* @see #fast
*/
- @Parameter( property = "maven.clean.fastDir" )
+ @Parameter(property = "maven.clean.fastDir")
private File fastDir;
/**
@@ -205,10 +202,10 @@ public class CleanMojo
* @since 3.2
* @see #fast
*/
- @Parameter( property = "maven.clean.fastMode", defaultValue = FAST_MODE_BACKGROUND )
+ @Parameter(property = "maven.clean.fastMode", defaultValue = FAST_MODE_BACKGROUND)
private String fastMode;
- @Parameter( defaultValue = "${session}", readonly = true )
+ @Parameter(defaultValue = "${session}", readonly = true)
private MavenSession session;
/**
@@ -218,74 +215,57 @@ public class CleanMojo
* @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." );
+ public void execute() throws MojoExecutionException {
+ if (skip) {
+ getLog().info("Clean is skipped.");
return;
}
- String multiModuleProjectDirectory = session != null
- ? session.getSystemProperties().getProperty( "maven.multiModuleProjectDirectory" ) : null;
+ String multiModuleProjectDirectory =
+ session != null ? session.getSystemProperties().getProperty("maven.multiModuleProjectDirectory") : null;
File fastDir;
- if ( fast && this.fastDir != null )
- {
+ if (fast && this.fastDir != null) {
fastDir = this.fastDir;
- }
- else if ( fast && multiModuleProjectDirectory != null )
- {
- fastDir = new File( multiModuleProjectDirectory, "target/.clean" );
- }
- else
- {
+ } 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, "
+ 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." );
+ + "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 + "'." );
+ 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 );
+ Cleaner cleaner = new Cleaner(session, getLog(), isVerbose(), fastDir, fastMode);
- try
- {
- for ( File directoryItem : getDirectories() )
- {
- if ( directoryItem != null )
- {
- cleaner.delete( directoryItem, null, followSymLinks, failOnError, retryOnError );
+ 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 );
+ 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 );
+ 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 );
+ } catch (IOException e) {
+ throw new MojoExecutionException("Failed to clean project: " + e.getMessage(), e);
}
}
@@ -294,9 +274,8 @@ public class CleanMojo
*
* @return <code>true</code> if verbose output is enabled, <code>false</code> otherwise.
*/
- private boolean isVerbose()
- {
- return ( verbose != null ) ? verbose : getLog().isDebugEnabled();
+ private boolean isVerbose() {
+ return (verbose != null) ? verbose : getLog().isDebugEnabled();
}
/**
@@ -304,18 +283,13 @@ public class CleanMojo
*
* @return The directories to clean or an empty array if none, never <code>null</code>.
*/
- private File[] getDirectories()
- {
+ private File[] getDirectories() {
File[] directories;
- if ( excludeDefaultDirectories )
- {
+ if (excludeDefaultDirectories) {
directories = new File[0];
- }
- else
- {
- directories = new File[] { directory, outputDirectory, testOutputDirectory, reportDirectory };
+ } else {
+ directories = new File[] {directory, outputDirectory, testOutputDirectory, reportDirectory};
}
return directories;
}
-
}
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 4e6e9d2..97ef594 100644
--- a/src/main/java/org/apache/maven/plugins/clean/Cleaner.java
+++ b/src/main/java/org/apache/maven/plugins/clean/Cleaner.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugins.clean;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,6 +16,7 @@ package org.apache.maven.plugins.clean;
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.maven.plugins.clean;
import java.io.File;
import java.io.IOException;
@@ -25,15 +24,17 @@ 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;
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 org.apache.maven.shared.utils.Os;
+import org.codehaus.plexus.util.Os;
import org.eclipse.aether.SessionData;
import static org.apache.maven.plugins.clean.CleanMojo.FAST_MODE_BACKGROUND;
@@ -41,13 +42,12 @@ import static org.apache.maven.plugins.clean.CleanMojo.FAST_MODE_DEFER;
/**
* Cleans directories.
- *
+ *
* @author Benjamin Bentmann
*/
-class Cleaner
-{
+class Cleaner {
- private static final boolean ON_WINDOWS = Os.isFamily( Os.FAMILY_WINDOWS );
+ private static final boolean ON_WINDOWS = Os.isFamily(Os.FAMILY_WINDOWS);
private static final String LAST_DIRECTORY_TO_DELETE = Cleaner.class.getName() + ".lastDirectoryToDelete";
@@ -74,13 +74,12 @@ class Cleaner
* @param verbose Whether to perform verbose logging.
* @param fastMode The fast deletion mode
*/
- Cleaner( MavenSession session, final Log log, boolean verbose, File fastDir, String fastMode )
- {
- logDebug = ( log == null || !log.isDebugEnabled() ) ? null : log::debug;
+ Cleaner(MavenSession session, final Log log, boolean verbose, File fastDir, String fastMode) {
+ logDebug = (log == null || !log.isDebugEnabled()) ? null : log::debug;
- logInfo = ( log == null || !log.isInfoEnabled() ) ? null : log::info;
+ logInfo = (log == null || !log.isInfoEnabled()) ? null : log::info;
- logWarn = ( log == null || !log.isWarnEnabled() ) ? null : log::warn;
+ logWarn = (log == null || !log.isWarnEnabled()) ? null : log::warn;
logVerbose = verbose ? logInfo : logDebug;
@@ -91,7 +90,7 @@ class Cleaner
/**
* 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
@@ -101,115 +100,89 @@ class Cleaner
* @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 )
- throws IOException
- {
- if ( !basedir.isDirectory() )
- {
- if ( !basedir.exists() )
- {
- if ( logDebug != null )
- {
- logDebug.log( "Skipping non-existing directory " + basedir );
+ public void delete(
+ File basedir, Selector selector, boolean followSymlinks, boolean failOnError, boolean retryOnError)
+ throws IOException {
+ if (!basedir.isDirectory()) {
+ if (!basedir.exists()) {
+ if (logDebug != null) {
+ logDebug.log("Skipping non-existing directory " + basedir);
}
return;
}
- throw new IOException( "Invalid base directory " + basedir );
+ throw new IOException("Invalid base directory " + basedir);
}
- if ( logInfo != null )
- {
- logInfo.log( "Deleting " + basedir + ( selector != null ? " (" + selector + ")" : "" ) );
+ if (logInfo != null) {
+ logInfo.log("Deleting " + basedir + (selector != null ? " (" + selector + ")" : ""));
}
File file = followSymlinks ? basedir : basedir.getCanonicalFile();
- if ( selector == null && !followSymlinks && fastDir != null && session != null )
- {
+ if (selector == null && !followSymlinks && fastDir != null && session != null) {
// If anything wrong happens, we'll just use the usual deletion mechanism
- if ( fastDelete( file ) )
- {
+ if (fastDelete(file)) {
return;
}
}
- delete( file, "", selector, followSymlinks, failOnError, retryOnError );
+ delete(file, "", selector, followSymlinks, failOnError, retryOnError);
}
- private boolean fastDelete( File baseDirFile )
- {
+ private boolean fastDelete(File baseDirFile) {
Path baseDir = baseDirFile.toPath();
Path fastDir = this.fastDir.toPath();
// Handle the case where we use ${maven.multiModuleProjectDirectory}/target/.clean for example
- if ( fastDir.toAbsolutePath().startsWith( baseDir.toAbsolutePath() ) )
- {
- try
- {
+ if (fastDir.toAbsolutePath().startsWith(baseDir.toAbsolutePath())) {
+ try {
String prefix = baseDir.getFileName().toString() + ".";
- Path tmpDir = Files.createTempDirectory( baseDir.getParent(), prefix );
- try
- {
- Files.move( baseDir, tmpDir, StandardCopyOption.REPLACE_EXISTING );
- if ( session != null )
- {
- session.getRepositorySession().getData().set( LAST_DIRECTORY_TO_DELETE, baseDir.toFile() );
+ Path tmpDir = Files.createTempDirectory(baseDir.getParent(), prefix);
+ try {
+ Files.move(baseDir, tmpDir, StandardCopyOption.REPLACE_EXISTING);
+ if (session != null) {
+ session.getRepositorySession().getData().set(LAST_DIRECTORY_TO_DELETE, baseDir.toFile());
}
baseDir = tmpDir;
- }
- catch ( IOException e )
- {
- Files.delete( tmpDir );
+ } catch (IOException e) {
+ Files.delete(tmpDir);
throw e;
}
- }
- catch ( IOException e )
- {
- if ( logDebug != null )
- {
+ } catch (IOException e) {
+ if (logDebug != null) {
// TODO: this Logger interface cannot log exceptions and needs refactoring
- logDebug.log( "Unable to fast delete directory: " + e );
+ logDebug.log("Unable to fast delete directory: " + e);
}
return false;
}
}
// Create fastDir and the needed parents if needed
- try
- {
- if ( !Files.isDirectory( fastDir ) )
- {
- Files.createDirectories( fastDir );
+ try {
+ if (!Files.isDirectory(fastDir)) {
+ Files.createDirectories(fastDir);
}
- }
- catch ( IOException e )
- {
- if ( logDebug != null )
- {
+ } catch (IOException e) {
+ if (logDebug != null) {
// TODO: this Logger interface cannot log exceptions and needs refactoring
- logDebug.log( "Unable to fast delete directory as the path "
- + fastDir + " does not point to a directory or cannot be created: " + e );
+ logDebug.log("Unable to fast delete directory as the path " + fastDir
+ + " does not point to a directory or cannot be created: " + e);
}
return false;
}
- try
- {
- Path tmpDir = Files.createTempDirectory( fastDir, "" );
- Path dstDir = tmpDir.resolve( baseDir.getFileName() );
+ try {
+ Path tmpDir = Files.createTempDirectory(fastDir, "");
+ Path dstDir = tmpDir.resolve(baseDir.getFileName());
// Note that by specifying the ATOMIC_MOVE, we expect an exception to be thrown
// if the path leads to a directory on another mountpoint. If this is the case
// 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 );
+ Files.move(baseDir, dstDir, StandardCopyOption.ATOMIC_MOVE);
+ BackgroundCleaner.delete(this, tmpDir.toFile(), fastMode);
return true;
- }
- catch ( IOException e )
- {
- if ( logDebug != null )
- {
+ } catch (IOException e) {
+ if (logDebug != null) {
// TODO: this Logger interface cannot log exceptions and needs refactoring
- logDebug.log( "Unable to fast delete directory: " + e );
+ logDebug.log("Unable to fast delete directory: " + e);
}
return false;
}
@@ -217,7 +190,7 @@ 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
@@ -230,128 +203,104 @@ class Cleaner
* @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, String pathname, Selector selector, boolean followSymlinks, boolean failOnError,
- boolean retryOnError )
- throws IOException
- {
+ private Result delete(
+ File file,
+ String pathname,
+ Selector selector,
+ boolean followSymlinks,
+ boolean failOnError,
+ boolean retryOnError)
+ throws IOException {
Result result = new Result();
boolean isDirectory = file.isDirectory();
- if ( isDirectory )
- {
- if ( selector == null || selector.couldHoldSelected( pathname ) )
- {
- final boolean isSymlink = Files.isSymbolicLink( file.toPath() );
- File canonical = followSymlinks ? file : file.getCanonicalFile();
- if ( followSymlinks || !isSymlink )
- {
+ 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 )
- {
+ if (filenames != null) {
String prefix = pathname.length() > 0 ? pathname + File.separatorChar : "";
- for ( int i = filenames.length - 1; i >= 0; i-- )
- {
+ for (int i = filenames.length - 1; i >= 0; i--) {
String filename = filenames[i];
- File child = new File( canonical, filename );
- result.update( delete( child, prefix + filename, selector, followSymlinks, failOnError,
- retryOnError ) );
+ File child = new File(canonical, filename);
+ result.update(delete(
+ child, prefix + filename, selector, followSymlinks, failOnError, retryOnError));
}
}
+ } else if (logDebug != null) {
+ logDebug.log("Not recursing into symlink " + file);
}
- else if ( logDebug != null )
- {
- logDebug.log( "Not recursing into symlink " + file );
- }
- }
- else if ( logDebug != null )
- {
- logDebug.log( "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 ) ) )
- {
- if ( logVerbose != null )
- {
- if ( isDirectory )
- {
- logVerbose.log( "Deleting directory " + file );
- }
- else if ( file.exists() )
- {
- logVerbose.log( "Deleting file " + file );
- }
- else
- {
- logVerbose.log( "Deleting dangling symlink " + file );
+ if (!result.excluded && (selector == null || selector.isSelected(pathname))) {
+ if (logVerbose != null) {
+ if (isDirectory) {
+ logVerbose.log("Deleting directory " + file);
+ } else if (file.exists()) {
+ logVerbose.log("Deleting file " + file);
+ } else {
+ logVerbose.log("Deleting dangling symlink " + file);
}
}
- result.failures += delete( file, failOnError, retryOnError );
- }
- else
- {
+ result.failures += delete(file, failOnError, retryOnError);
+ } else {
result.excluded = true;
}
return result;
}
+ private boolean isSymbolicLink(Path path) throws IOException {
+ BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
+ return attrs.isSymbolicLink()
+ // MCLEAN-93: NTFS junctions have isDirectory() and isOther() attributes set
+ || (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() )
- {
+ private int delete(File file, boolean failOnError, boolean retryOnError) throws IOException {
+ if (!file.delete()) {
boolean deleted = false;
- if ( retryOnError )
- {
- if ( ON_WINDOWS )
- {
+ if (retryOnError) {
+ if (ON_WINDOWS) {
// try to release any locks held by non-closed files
System.gc();
}
- final int[] delays = { 50, 250, 750 };
- for ( int i = 0; !deleted && i < delays.length; i++ )
- {
- try
- {
- Thread.sleep( delays[i] );
- }
- catch ( InterruptedException e )
- {
+ final int[] delays = {50, 250, 750};
+ for (int i = 0; !deleted && i < delays.length; i++) {
+ try {
+ Thread.sleep(delays[i]);
+ } catch (InterruptedException e) {
// ignore
}
deleted = file.delete() || !file.exists();
}
- }
- else
- {
+ } else {
deleted = !file.exists();
}
- if ( !deleted )
- {
- if ( failOnError )
- {
- throw new IOException( "Failed to delete " + file );
- }
- else
- {
- if ( logWarn != null )
- {
- logWarn.log( "Failed to delete " + file );
+ if (!deleted) {
+ if (failOnError) {
+ throw new IOException("Failed to delete " + file);
+ } else {
+ if (logWarn != null) {
+ logWarn.log("Failed to delete " + file);
}
return 1;
}
@@ -361,30 +310,24 @@ class Cleaner
return 0;
}
- private static class Result
- {
+ private static class Result {
private int failures;
private boolean excluded;
- public void update( Result result )
- {
+ public void update(Result result) {
failures += result.failures;
excluded |= result.excluded;
}
-
}
- private interface Logger
- {
-
- void log( CharSequence message );
+ private interface Logger {
+ void log(CharSequence message);
}
- private static class BackgroundCleaner extends Thread
- {
+ private static class BackgroundCleaner extends Thread {
private static BackgroundCleaner instance;
@@ -400,84 +343,63 @@ class Cleaner
private int status = NEW;
- public static void delete( Cleaner cleaner, File dir, String fastMode )
- {
- synchronized ( BackgroundCleaner.class )
- {
- if ( instance == null || !instance.doDelete( dir ) )
- {
- instance = new BackgroundCleaner( cleaner, dir, fastMode );
+ public static void delete(Cleaner cleaner, File dir, String fastMode) {
+ synchronized (BackgroundCleaner.class) {
+ if (instance == null || !instance.doDelete(dir)) {
+ instance = new BackgroundCleaner(cleaner, dir, fastMode);
}
}
}
- static void sessionEnd()
- {
- synchronized ( BackgroundCleaner.class )
- {
- if ( instance != null )
- {
+ static void sessionEnd() {
+ synchronized (BackgroundCleaner.class) {
+ if (instance != null) {
instance.doSessionEnd();
}
}
}
- private BackgroundCleaner( Cleaner cleaner, File dir, String fastMode )
- {
- super( "mvn-background-cleaner" );
+ private BackgroundCleaner(Cleaner cleaner, File dir, String fastMode) {
+ super("mvn-background-cleaner");
this.cleaner = cleaner;
this.fastMode = fastMode;
- init( cleaner.fastDir, dir );
+ init(cleaner.fastDir, dir);
}
- public void run()
- {
- while ( true )
- {
+ public void run() {
+ while (true) {
File basedir = pollNext();
- if ( basedir == null )
- {
+ if (basedir == null) {
break;
}
- try
- {
- cleaner.delete( basedir, "", null, false, false, true );
- }
- catch ( IOException e )
- {
+ try {
+ cleaner.delete(basedir, "", null, false, false, true);
+ } catch (IOException e) {
// do not display errors
}
}
}
- synchronized void init( File fastDir, File dir )
- {
- if ( fastDir.isDirectory() )
- {
+ 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 );
+ if (children != null && children.length > 0) {
+ for (File child : children) {
+ doDelete(child);
}
}
}
- doDelete( dir );
+ doDelete(dir);
}
- synchronized File pollNext()
- {
+ synchronized File pollNext() {
File basedir = filesToDelete.poll();
- if ( basedir == null )
- {
- if ( cleaner.session != null )
- {
+ if (basedir == null) {
+ if (cleaner.session != null) {
SessionData data = cleaner.session.getRepositorySession().getData();
- File lastDir = ( File ) data.get( LAST_DIRECTORY_TO_DELETE );
- if ( lastDir != null )
- {
- data.set( LAST_DIRECTORY_TO_DELETE, null );
+ File lastDir = (File) data.get(LAST_DIRECTORY_TO_DELETE);
+ if (lastDir != null) {
+ data.set(LAST_DIRECTORY_TO_DELETE, null);
return lastDir;
}
}
@@ -487,15 +409,12 @@ class Cleaner
return basedir;
}
- synchronized boolean doDelete( File dir )
- {
- if ( status == STOPPED )
- {
+ synchronized boolean doDelete(File dir) {
+ if (status == STOPPED) {
return false;
}
- filesToDelete.add( dir );
- if ( status == NEW && FAST_MODE_BACKGROUND.equals( fastMode ) )
- {
+ filesToDelete.add(dir);
+ if (status == NEW && FAST_MODE_BACKGROUND.equals(fastMode)) {
status = RUNNING;
notifyAll();
start();
@@ -511,72 +430,56 @@ class Cleaner
* There's no clean API to do that properly as this is a very unusual use case for a plugin
* to outlive its main execution.
*/
- private void wrapExecutionListener()
- {
+ 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(
+ 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 );
+ new Class[] {ExecutionListener.class},
+ new SpyInvocationHandler(executionListener));
+ cleaner.session.getRequest().setExecutionListener(listener);
}
}
- synchronized void doSessionEnd()
- {
- if ( status != STOPPED )
- {
- if ( status == NEW )
- {
+ synchronized void doSessionEnd() {
+ if (status != STOPPED) {
+ if (status == NEW) {
start();
}
- if ( !FAST_MODE_DEFER.equals( fastMode ) )
- {
- try
- {
- cleaner.logInfo.log( "Waiting for background file deletion" );
- while ( status != STOPPED )
- {
+ if (!FAST_MODE_DEFER.equals(fastMode)) {
+ try {
+ if (cleaner.logInfo != null) {
+ cleaner.logInfo.log("Waiting for background file deletion");
+ }
+ while (status != STOPPED) {
wait();
}
- }
- catch ( InterruptedException e )
- {
+ } catch (InterruptedException e) {
// ignore
}
}
}
}
-
}
- static class SpyInvocationHandler implements InvocationHandler
- {
+ static class SpyInvocationHandler implements InvocationHandler {
private final ExecutionListener delegate;
- SpyInvocationHandler( ExecutionListener delegate )
- {
+ SpyInvocationHandler(ExecutionListener delegate) {
this.delegate = delegate;
}
@Override
- public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
- {
- if ( "sessionEnded".equals( method.getName() ) )
- {
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if ("sessionEnded".equals(method.getName())) {
BackgroundCleaner.sessionEnd();
}
- if ( delegate != null )
- {
- return method.invoke( delegate, args );
+ 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 2df6435..ecd88b0 100644
--- a/src/main/java/org/apache/maven/plugins/clean/Fileset.java
+++ b/src/main/java/org/apache/maven/plugins/clean/Fileset.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugins.clean;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,6 +16,7 @@ package org.apache.maven.plugins.clean;
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.maven.plugins.clean;
import java.io.File;
import java.util.Arrays;
@@ -31,8 +30,7 @@ import java.util.Arrays;
*
* @since 2.1
*/
-public class Fileset
-{
+public class Fileset {
private File directory;
@@ -47,40 +45,35 @@ public class Fileset
/**
* @return {@link #directory}
*/
- public File getDirectory()
- {
+ public File getDirectory() {
return directory;
}
/**
* @return {@link #includes}
*/
- public String[] getIncludes()
- {
- return ( includes != null ) ? includes : new String[0];
+ public String[] getIncludes() {
+ return (includes != null) ? includes : new String[0];
}
/**
* @return {@link #excludes}
*/
- public String[] getExcludes()
- {
- return ( excludes != null ) ? excludes : new String[0];
+ public String[] getExcludes() {
+ return (excludes != null) ? excludes : new String[0];
}
/**
* @return {@link #followSymlinks}
*/
- public boolean isFollowSymlinks()
- {
+ public boolean isFollowSymlinks() {
return followSymlinks;
}
/**
* @return {@link #useDefaultExcludes}
*/
- public boolean isUseDefaultExcludes()
- {
+ public boolean isUseDefaultExcludes() {
return useDefaultExcludes;
}
@@ -94,10 +87,8 @@ public class Fileset
* <I>[included files]</I>, excluded: <I>[excluded files]</I>)"</code>
* @see java.lang.Object#toString()
*/
- public String toString()
- {
- return "file set: " + getDirectory() + " (included: " + Arrays.asList( getIncludes() ) + ", excluded: "
- + Arrays.asList( getExcludes() ) + ")";
+ public String toString() {
+ return "file set: " + getDirectory() + " (included: " + Arrays.asList(getIncludes()) + ", excluded: "
+ + Arrays.asList(getExcludes()) + ")";
}
-
}
diff --git a/src/main/java/org/apache/maven/plugins/clean/GlobSelector.java b/src/main/java/org/apache/maven/plugins/clean/GlobSelector.java
index ab791eb..2d2f99d 100644
--- a/src/main/java/org/apache/maven/plugins/clean/GlobSelector.java
+++ b/src/main/java/org/apache/maven/plugins/clean/GlobSelector.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugins.clean;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,22 +16,20 @@ package org.apache.maven.plugins.clean;
* specific language governing permissions and limitations
* under the License.
*/
-
-import org.apache.maven.shared.utils.io.DirectoryScanner;
-import org.apache.maven.shared.utils.io.SelectorUtils;
+package org.apache.maven.plugins.clean;
import java.io.File;
import java.util.Arrays;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.SelectorUtils;
/**
* Selects paths based on Ant-like glob patterns.
- *
+ *
* @author Benjamin Bentmann
*/
-class GlobSelector
- implements Selector
-{
+class GlobSelector implements Selector {
private final String[] includes;
@@ -41,113 +37,87 @@ class GlobSelector
private final String str;
- GlobSelector( String[] includes, String[] excludes )
- {
- this( includes, excludes, false );
+ GlobSelector(String[] includes, String[] excludes) {
+ this(includes, excludes, false);
}
- GlobSelector( String[] includes, String[] excludes, boolean useDefaultExcludes )
- {
- this.str = "includes = " + toString( includes ) + ", excludes = " + toString( excludes );
- this.includes = normalizePatterns( includes );
- this.excludes = normalizePatterns( addDefaultExcludes( excludes, useDefaultExcludes ) );
+ GlobSelector(String[] includes, String[] excludes, boolean useDefaultExcludes) {
+ this.str = "includes = " + toString(includes) + ", excludes = " + toString(excludes);
+ this.includes = normalizePatterns(includes);
+ this.excludes = normalizePatterns(addDefaultExcludes(excludes, useDefaultExcludes));
}
- private static String toString( String[] patterns )
- {
- return ( patterns == null ) ? "[]" : Arrays.asList( patterns ).toString();
+ private static String toString(String[] patterns) {
+ return (patterns == null) ? "[]" : Arrays.asList(patterns).toString();
}
- private static String[] addDefaultExcludes( String[] excludes, boolean useDefaultExcludes )
- {
+ private static String[] addDefaultExcludes(String[] excludes, boolean useDefaultExcludes) {
String[] defaults = DirectoryScanner.DEFAULTEXCLUDES;
- if ( !useDefaultExcludes )
- {
+ if (!useDefaultExcludes) {
return excludes;
- }
- else if ( excludes == null || excludes.length <= 0 )
- {
+ } else if (excludes == null || excludes.length <= 0) {
return defaults;
- }
- else
- {
+ } else {
String[] patterns = new String[excludes.length + defaults.length];
- System.arraycopy( excludes, 0, patterns, 0, excludes.length );
- System.arraycopy( defaults, 0, patterns, excludes.length, defaults.length );
+ System.arraycopy(excludes, 0, patterns, 0, excludes.length);
+ System.arraycopy(defaults, 0, patterns, excludes.length, defaults.length);
return patterns;
}
}
- private static String[] normalizePatterns( String[] patterns )
- {
+ private static String[] normalizePatterns(String[] patterns) {
String[] normalized;
- if ( patterns != null )
- {
+ if (patterns != null) {
normalized = new String[patterns.length];
- for ( int i = patterns.length - 1; i >= 0; i-- )
- {
- normalized[i] = normalizePattern( patterns[i] );
+ for (int i = patterns.length - 1; i >= 0; i--) {
+ normalized[i] = normalizePattern(patterns[i]);
}
- }
- else
- {
+ } else {
normalized = new String[0];
}
return normalized;
}
- private static String normalizePattern( String pattern )
- {
- if ( pattern == null )
- {
+ private static String normalizePattern(String pattern) {
+ if (pattern == null) {
return "";
}
- String normalized = pattern.replace( ( File.separatorChar == '/' ) ? '\\' : '/', File.separatorChar );
+ String normalized = pattern.replace((File.separatorChar == '/') ? '\\' : '/', File.separatorChar);
- if ( normalized.endsWith( File.separator ) )
- {
+ if (normalized.endsWith(File.separator)) {
normalized += "**";
}
return normalized;
}
- public boolean isSelected( String pathname )
- {
- return ( includes.length <= 0 || isMatched( pathname, includes ) )
- && ( excludes.length <= 0 || !isMatched( pathname, excludes ) );
+ public boolean isSelected(String pathname) {
+ return (includes.length <= 0 || isMatched(pathname, includes))
+ && (excludes.length <= 0 || !isMatched(pathname, excludes));
}
- private static boolean isMatched( String pathname, String[] patterns )
- {
- for ( String pattern : patterns )
- {
- if ( SelectorUtils.matchPath( pattern, pathname ) )
- {
+ private static boolean isMatched(String pathname, String[] patterns) {
+ for (String pattern : patterns) {
+ if (SelectorUtils.matchPath(pattern, pathname)) {
return true;
}
}
return false;
}
- public boolean couldHoldSelected( String pathname )
- {
- for ( String include : includes )
- {
- if ( SelectorUtils.matchPatternStart( include, pathname ) )
- {
+ public boolean couldHoldSelected(String pathname) {
+ for (String include : includes) {
+ if (SelectorUtils.matchPatternStart(include, pathname)) {
return true;
}
}
return includes.length <= 0;
}
- public String toString()
- {
+ public String toString() {
return str;
}
-
}
diff --git a/src/main/java/org/apache/maven/plugins/clean/Selector.java b/src/main/java/org/apache/maven/plugins/clean/Selector.java
index aa80009..93a0695 100644
--- a/src/main/java/org/apache/maven/plugins/clean/Selector.java
+++ b/src/main/java/org/apache/maven/plugins/clean/Selector.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugins.clean;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,31 +16,30 @@ package org.apache.maven.plugins.clean;
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.maven.plugins.clean;
/**
* Determines whether a path is selected for deletion. The pathnames used for method parameters will be relative to some
* base directory and use {@link java.io.File#separatorChar} as separator.
- *
+ *
* @author Benjamin Bentmann
*/
-interface Selector
-{
+interface Selector {
/**
* Determines whether a path is selected for deletion.
- *
+ *
* @param pathname The pathname to test, must not be <code>null</code>.
* @return <code>true</code> if the given path is selected for deletion, <code>false</code> otherwise.
*/
- boolean isSelected( String pathname );
+ boolean isSelected(String pathname);
/**
* Determines whether a directory could contain selected paths.
- *
+ *
* @param pathname The directory pathname to test, must not be <code>null</code>.
* @return <code>true</code> if the given directory might contain selected paths, <code>false</code> if the
* directory will definitively not contain selected paths..
*/
- boolean couldHoldSelected( String pathname );
-
+ boolean couldHoldSelected(String pathname);
}
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 84b638f..f82e615 100644
--- a/src/test/java/org/apache/maven/plugins/clean/CleanMojoTest.java
+++ b/src/test/java/org/apache/maven/plugins/clean/CleanMojoTest.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugins.clean;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,50 +16,58 @@ package org.apache.maven.plugins.clean;
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.maven.plugins.clean;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.testing.AbstractMojoTestCase;
-
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
+import java.nio.file.Files;
+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.testing.AbstractMojoTestCase;
import static org.apache.commons.io.FileUtils.copyDirectory;
+import static org.codehaus.plexus.util.IOUtil.copy;
/**
* Test the clean mojo.
*
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
*/
-public class CleanMojoTest
- extends AbstractMojoTestCase
-{
+public class CleanMojoTest extends AbstractMojoTestCase {
/**
* Tests the simple removal of directories
*
* @throws Exception in case of an error.
*/
- public void testBasicClean()
- throws Exception
- {
+ public void testBasicClean() throws Exception {
String pluginPom = getBasedir() + "/src/test/resources/unit/basic-clean-test/plugin-pom.xml";
// safety
- copyDirectory( new File( getBasedir(), "src/test/resources/unit/basic-clean-test" ),
- new File( getBasedir(), "target/test-classes/unit/basic-clean-test" ) );
+ copyDirectory(
+ new File(getBasedir(), "src/test/resources/unit/basic-clean-test"),
+ new File(getBasedir(), "target/test-classes/unit/basic-clean-test"));
- CleanMojo mojo = (CleanMojo) lookupMojo( "clean", pluginPom );
- assertNotNull( mojo );
+ CleanMojo mojo = (CleanMojo) lookupMojo("clean", pluginPom);
+ assertNotNull(mojo);
mojo.execute();
- assertFalse( "Directory exists", checkExists( getBasedir() + "/target/test-classes/unit/"
- + "basic-clean-test/buildDirectory" ) );
- assertFalse( "Directory exists", checkExists( getBasedir() + "/target/test-classes/unit/basic-clean-test/"
- + "buildOutputDirectory" ) );
- assertFalse( "Directory exists", checkExists( getBasedir() + "/target/test-classes/unit/basic-clean-test/"
- + "buildTestDirectory" ) );
+ assertFalse(
+ "Directory exists",
+ checkExists(getBasedir() + "/target/test-classes/unit/" + "basic-clean-test/buildDirectory"));
+ assertFalse(
+ "Directory exists",
+ checkExists(getBasedir() + "/target/test-classes/unit/basic-clean-test/" + "buildOutputDirectory"));
+ assertFalse(
+ "Directory exists",
+ checkExists(getBasedir() + "/target/test-classes/unit/basic-clean-test/" + "buildTestDirectory"));
}
/**
@@ -69,23 +75,22 @@ public class CleanMojoTest
*
* @throws Exception in case of an error.
*/
- public void testCleanNestedStructure()
- throws Exception
- {
+ public void testCleanNestedStructure() throws Exception {
String pluginPom = getBasedir() + "/src/test/resources/unit/nested-clean-test/plugin-pom.xml";
// safety
- copyDirectory( new File( getBasedir(), "src/test/resources/unit/nested-clean-test" ),
- new File( getBasedir(), "target/test-classes/unit/nested-clean-test" ) );
+ copyDirectory(
+ new File(getBasedir(), "src/test/resources/unit/nested-clean-test"),
+ new File(getBasedir(), "target/test-classes/unit/nested-clean-test"));
- CleanMojo mojo = (CleanMojo) lookupMojo( "clean", pluginPom );
- assertNotNull( mojo );
+ CleanMojo mojo = (CleanMojo) lookupMojo("clean", pluginPom);
+ assertNotNull(mojo);
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/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"));
}
/**
@@ -94,27 +99,26 @@ public class CleanMojoTest
*
* @throws Exception in case of an error.
*/
- public void testCleanEmptyDirectories()
- throws Exception
- {
+ public void testCleanEmptyDirectories() throws Exception {
String pluginPom = getBasedir() + "/src/test/resources/unit/empty-clean-test/plugin-pom.xml";
// safety
- copyDirectory( new File( getBasedir(), "src/test/resources/unit/empty-clean-test" ),
- new File( getBasedir(), "target/test-classes/unit/empty-clean-test" ) );
+ copyDirectory(
+ new File(getBasedir(), "src/test/resources/unit/empty-clean-test"),
+ new File(getBasedir(), "target/test-classes/unit/empty-clean-test"));
- CleanMojo mojo = (CleanMojo) lookupEmptyMojo( "clean", pluginPom );
- assertNotNull( mojo );
+ CleanMojo mojo = (CleanMojo) lookupEmptyMojo("clean", pluginPom);
+ assertNotNull(mojo);
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() + "/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"));
}
/**
@@ -122,35 +126,34 @@ public class CleanMojoTest
*
* @throws Exception in case of an error.
*/
- public void testFilesetsClean()
- throws Exception
- {
+ public void testFilesetsClean() throws Exception {
String pluginPom = getBasedir() + "/src/test/resources/unit/fileset-clean-test/plugin-pom.xml";
// safety
- copyDirectory( new File( getBasedir(), "src/test/resources/unit/fileset-clean-test" ),
- new File( getBasedir(), "target/test-classes/unit/fileset-clean-test" ) );
+ copyDirectory(
+ new File(getBasedir(), "src/test/resources/unit/fileset-clean-test"),
+ new File(getBasedir(), "target/test-classes/unit/fileset-clean-test"));
- CleanMojo mojo = (CleanMojo) lookupMojo( "clean", pluginPom );
- assertNotNull( mojo );
+ CleanMojo mojo = (CleanMojo) lookupMojo("clean", pluginPom);
+ assertNotNull(mojo);
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/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"));
// 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() + "/target/test-classes/unit/fileset-clean-test/" + "buildOutputDirectory"));
+ assertFalse(checkExists(
+ getBasedir() + "/target/test-classes/unit/fileset-clean-test/" + "buildOutputDirectory/file.txt"));
}
/**
@@ -158,27 +161,23 @@ public class CleanMojoTest
*
* @throws Exception in case of an error.
*/
- public void testCleanInvalidDirectory()
- throws Exception
- {
+ public void testCleanInvalidDirectory() throws Exception {
String pluginPom = getBasedir() + "/src/test/resources/unit/invalid-directory-test/plugin-pom.xml";
// safety
- copyDirectory( new File( getBasedir(), "src/test/resources/unit/invalid-directory-test" ),
- new File( getBasedir(), "target/test-classes/unit/invalid-directory-test" ) );
+ copyDirectory(
+ new File(getBasedir(), "src/test/resources/unit/invalid-directory-test"),
+ new File(getBasedir(), "target/test-classes/unit/invalid-directory-test"));
- CleanMojo mojo = (CleanMojo) lookupMojo( "clean", pluginPom );
- assertNotNull( mojo );
+ CleanMojo mojo = (CleanMojo) lookupMojo("clean", pluginPom);
+ assertNotNull(mojo);
- try
- {
+ try {
mojo.execute();
- fail( "Should fail to delete a file treated as a directory" );
- }
- catch ( MojoExecutionException expected )
- {
- assertTrue( true );
+ fail("Should fail to delete a file treated as a directory");
+ } catch (MojoExecutionException expected) {
+ assertTrue(true);
}
}
@@ -187,21 +186,20 @@ public class CleanMojoTest
*
* @throws Exception in case of an error.
*/
- public void testMissingDirectory()
- throws Exception
- {
+ public void testMissingDirectory() throws Exception {
String pluginPom = getBasedir() + "/src/test/resources/unit/missing-directory-test/plugin-pom.xml";
// safety
- copyDirectory( new File( getBasedir(), "src/test/resources/unit/missing-directory-test" ),
- new File( getBasedir(), "target/test-classes/unit/missing-directory-test" ) );
+ copyDirectory(
+ new File(getBasedir(), "src/test/resources/unit/missing-directory-test"),
+ new File(getBasedir(), "target/test-classes/unit/missing-directory-test"));
- CleanMojo mojo = (CleanMojo) lookupMojo( "clean", pluginPom );
- assertNotNull( mojo );
+ CleanMojo mojo = (CleanMojo) lookupMojo("clean", pluginPom);
+ assertNotNull(mojo);
mojo.execute();
- assertFalse( checkExists( getBasedir() + "/target/test-classes/unit/missing-directory-test/does-not-exist" ) );
+ assertFalse(checkExists(getBasedir() + "/target/test-classes/unit/missing-directory-test/does-not-exist"));
}
/**
@@ -212,34 +210,29 @@ public class CleanMojoTest
*
* @throws Exception in case of an error.
*/
- public void testCleanLockedFile()
- throws Exception
- {
- if (!System.getProperty("os.name").toLowerCase().contains("windows"))
- {
- assertTrue( "Ignored this test on none Windows based systems", true );
+ public void testCleanLockedFile() throws Exception {
+ if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
+ assertTrue("Ignored this test on non Windows based systems", true);
return;
}
String pluginPom = getBasedir() + "/src/test/resources/unit/locked-file-test/plugin-pom.xml";
// safety
- copyDirectory( new File( getBasedir(), "src/test/resources/unit/locked-file-test" ),
- new File( getBasedir(), "target/test-classes/unit/locked-file-test" ) );
+ copyDirectory(
+ new File(getBasedir(), "src/test/resources/unit/locked-file-test"),
+ new File(getBasedir(), "target/test-classes/unit/locked-file-test"));
- CleanMojo mojo = (CleanMojo) lookupMojo( "clean", pluginPom );
- assertNotNull( mojo );
+ CleanMojo mojo = (CleanMojo) lookupMojo("clean", pluginPom);
+ assertNotNull(mojo);
- File f = new File( getBasedir(), "target/test-classes/unit/locked-file-test/buildDirectory/file.txt" );
- try ( FileChannel channel = new RandomAccessFile( f, "rw" ).getChannel();
- FileLock ignored = channel.lock() )
- {
+ File f = new File(getBasedir(), "target/test-classes/unit/locked-file-test/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 )
- {
- assertTrue( true );
+ fail("Should fail to delete a file that is locked");
+ } catch (MojoExecutionException expected) {
+ assertTrue(true);
}
}
@@ -251,54 +244,131 @@ public class CleanMojoTest
*
* @throws Exception in case of an error.
*/
- public void testCleanLockedFileWithNoError()
- throws Exception
- {
- if (!System.getProperty("os.name").toLowerCase().contains("windows"))
- {
- assertTrue( "Ignored this test on none Windows based systems", true );
+ public void testCleanLockedFileWithNoError() throws Exception {
+ if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
+ assertTrue("Ignore this test on non Windows based systems", true);
return;
}
String pluginPom = getBasedir() + "/src/test/resources/unit/locked-file-test/plugin-pom.xml";
// safety
- copyDirectory( new File( getBasedir(), "src/test/resources/unit/locked-file-test" ),
- new File( getBasedir(), "target/test-classes/unit/locked-file-test" ) );
+ copyDirectory(
+ new File(getBasedir(), "src/test/resources/unit/locked-file-test"),
+ new File(getBasedir(), "target/test-classes/unit/locked-file-test"));
- CleanMojo mojo = (CleanMojo) lookupMojo( "clean", pluginPom );
- setVariableValueToObject( mojo, "failOnError", Boolean.FALSE );
- assertNotNull( mojo );
+ CleanMojo mojo = (CleanMojo) lookupMojo("clean", pluginPom);
+ setVariableValueToObject(mojo, "failOnError", Boolean.FALSE);
+ assertNotNull(mojo);
- File f = new File( getBasedir(), "target/test-classes/unit/locked-file-test/buildDirectory/file.txt" );
- try ( FileChannel channel = new RandomAccessFile( f, "rw" ).getChannel();
- FileLock ignored = channel.lock())
- {
+ File f = new File(getBasedir(), "target/test-classes/unit/locked-file-test/buildDirectory/file.txt");
+ try (FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
+ FileLock ignored = channel.lock()) {
mojo.execute();
- assertTrue( true );
+ assertTrue(true);
+ } catch (MojoExecutionException expected) {
+ fail("Should display a warning when deleting a file that is locked");
+ }
+ }
+
+ /**
+ * Test the followLink option with windows junctions
+ * @throws Exception
+ */
+ public void testFollowLinksWithWindowsJunction() throws Exception {
+ if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
+ assertTrue("Ignore this test on non Windows based systems", true);
+ return;
}
- catch ( MojoExecutionException expected )
- {
- fail( "Should display a warning when deleting a file that is locked" );
+
+ testSymlink((link, target) -> {
+ Process process = new ProcessBuilder()
+ .directory(link.getParent().toFile())
+ .command("cmd", "/c", "mklink", "/j", link.getFileName().toString(), target.toString())
+ .start();
+ process.waitFor();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ copy(process.getInputStream(), baos);
+ copy(process.getErrorStream(), baos);
+ if (!Files.exists(link)) {
+ throw new IOException("Unable to create junction: " + baos);
+ }
+ });
+ }
+
+ /**
+ * Test the followLink option with sym link
+ * @throws Exception
+ */
+ public void testFollowLinksWithSymLinkOnPosix() throws Exception {
+ if (System.getProperty("os.name").toLowerCase().contains("windows")) {
+ assertTrue("Ignore this test on Windows based systems", true);
+ return;
}
+
+ testSymlink((link, target) -> {
+ try {
+ Files.createSymbolicLink(link, target);
+ } catch (IOException e) {
+ throw new IOException("Unable to create symbolic link", e);
+ }
+ });
+ }
+
+ @FunctionalInterface
+ interface LinkCreator {
+ void createLink(Path link, Path target) throws Exception;
+ }
+
+ private void testSymlink(LinkCreator linkCreator) throws Exception {
+ 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");
+ Path jctDir = dirWithLnk.resolve("jct-dir");
+ Path file = orgDir.resolve("file.txt");
+
+ // create directories, links and file
+ Files.createDirectories(dirWithLnk);
+ Files.createDirectories(orgDir);
+ Files.write(file, Collections.singleton("Hello world"));
+ linkCreator.createLink(jctDir, orgDir);
+ // delete
+ cleaner.delete(dirWithLnk.toFile(), null, false, true, false);
+ // verify
+ assertTrue(Files.exists(file));
+ assertFalse(Files.exists(jctDir));
+ assertTrue(Files.exists(orgDir));
+ assertFalse(Files.exists(dirWithLnk));
+
+ // create directories, links and file
+ Files.createDirectories(dirWithLnk);
+ Files.createDirectories(orgDir);
+ Files.write(file, Collections.singleton("Hello world"));
+ linkCreator.createLink(jctDir, orgDir);
+ // delete
+ cleaner.delete(dirWithLnk.toFile(), null, true, true, false);
+ // verify
+ assertFalse(Files.exists(file));
+ assertFalse(Files.exists(jctDir));
+ assertTrue(Files.exists(orgDir));
+ assertFalse(Files.exists(dirWithLnk));
}
/**
* @param dir a dir or a file
* @return true if a file/dir exists, false otherwise
*/
- private boolean checkExists( String dir )
- {
- return new File( new File( dir ).getAbsolutePath() ).exists();
+ private boolean checkExists(String dir) {
+ return new File(new File(dir).getAbsolutePath()).exists();
}
/**
* @param dir a directory
* @return true if a dir is empty, false otherwise
*/
- private boolean checkEmpty( String dir )
- {
- File[] files = new File( dir ).listFiles();
+ private boolean checkEmpty(String dir) {
+ File[] files = new File(dir).listFiles();
return files == null || files.length == 0;
}
}
diff --git a/src/test/java/org/apache/maven/plugins/clean/Utils.java b/src/test/java/org/apache/maven/plugins/clean/Utils.java
index c6f1342..f96226d 100644
--- a/src/test/java/org/apache/maven/plugins/clean/Utils.java
+++ b/src/test/java/org/apache/maven/plugins/clean/Utils.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugins.clean;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,6 +16,7 @@ package org.apache.maven.plugins.clean;
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.maven.plugins.clean;
import java.io.File;
@@ -26,35 +25,29 @@ import org.codehaus.plexus.util.cli.Commandline;
/**
* Testing helpers for the IT scripts.
- *
+ *
* @author Benjamin Bentmann
*/
-public class Utils
-{
+public class Utils {
/**
* Creates a symbolic link.
- *
+ *
* @param target The target (file or directory) of the link, must not be <code>null</code>.
* @param link The path to the link, must not be <code>null</code>.
* @return <code>true</code> if the symlink could be created, <code>false</code> otherwise.
*/
- public static boolean createSymlink( File target, File link )
- {
- try
- {
+ public static boolean createSymlink(File target, File link) {
+ try {
Commandline cli = new Commandline();
- cli.setExecutable( "ln" );
- cli.createArg().setValue( "-s" );
- cli.createArg().setFile( target );
- cli.createArg().setFile( link );
- int code = CommandLineUtils.executeCommandLine( cli, System.out::println, System.err::println );
+ cli.setExecutable("ln");
+ cli.createArg().setValue("-s");
+ cli.createArg().setFile(target);
+ cli.createArg().setFile(link);
+ int code = CommandLineUtils.executeCommandLine(cli, System.out::println, System.err::println);
return 0 == code;
- }
- catch ( Exception e )
- {
+ } catch (Exception e) {
return false;
}
}
-
}