This is an automated email from the ASF dual-hosted git repository.

bodewig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant.git

commit 015da2c68b1681572e3126e22880bcfee3df7fb2
Author: Stefan Bodewig <[email protected]>
AuthorDate: Sat Feb 7 16:02:51 2026 +0100

    add a file selector for Windows junctions
---
 WHATSNEW                                           |  3 +
 manual/Types/selectors.html                        |  9 +++
 .../org/apache/tools/ant/DirectoryScanner.java     |  2 +-
 .../apache/tools/ant/types/AbstractFileSet.java    |  9 +++
 .../types/selectors/AbstractSelectorContainer.java |  8 +++
 .../ant/types/selectors/BaseSelectorContainer.java |  8 +++
 .../tools/ant/types/selectors/SymlinkSelector.java |  2 +-
 ...kSelector.java => WindowsJunctionSelector.java} | 16 ++---
 .../types/selectors/windows-junction-test.xml      | 77 ++++++++++++++++++++++
 9 files changed, 124 insertions(+), 10 deletions(-)

diff --git a/WHATSNEW b/WHATSNEW
index a7c7b1c43..d9c4c79ac 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -71,6 +71,9 @@ Other changes:
  * added <canCreateSymlink> condition that evaluates to true if the
    current Ant process can create symbolic links.
 
+ * added <windowsjunction> file selector which only select directories
+   that are Windows junctions.
+
 Changes from Ant 1.10.14 TO Ant 1.10.15
 =======================================
 
diff --git a/manual/Types/selectors.html b/manual/Types/selectors.html
index 4539992ff..15552346f 100644
--- a/manual/Types/selectors.html
+++ b/manual/Types/selectors.html
@@ -88,6 +88,8 @@ <h3 id="coreselect">Core Selectors</h3>
         files if they have a given POSIX group.</li>
       <li><a 
href="#posixPermissions"><code>&lt;posixPermissions&gt;</code></a>&mdash;Select
         files if they have given POSIX permissions.</li>
+      <li><a 
href="#windowsjunction"><code>&lt;windowsjunction&gt;</code></a>&mdash;Select 
files if they are
+        Windows junctions.</li>
     </ul>
 
     <h4 id="containsselect">Contains Selector</h4>
@@ -998,6 +1000,13 @@ <h4 id="posixPermissions">PosixPermissions Selector</h4>
       </tr>
     </table>
 
+    <h4 id="windowsjunction">Windows Junction Selector</h4>
+
+    <p>The <code>&lt;windowsjunction&gt;</code> selector selects only
+    directories that are Windows junctions.</p>
+
+    <p><em>Since Ant 1.10.16</em></p>
+
     <h4 id="scriptselector">Script Selector</h4>
 
     <p>The <code>&lt;scriptselector&gt;</code> element enables you to write a 
complex selection
diff --git a/src/main/org/apache/tools/ant/DirectoryScanner.java 
b/src/main/org/apache/tools/ant/DirectoryScanner.java
index ea459da69..0b8454102 100644
--- a/src/main/org/apache/tools/ant/DirectoryScanner.java
+++ b/src/main/org/apache/tools/ant/DirectoryScanner.java
@@ -47,8 +47,8 @@ import org.apache.tools.ant.types.selectors.SelectorUtils;
 import org.apache.tools.ant.types.selectors.TokenizedPath;
 import org.apache.tools.ant.types.selectors.TokenizedPattern;
 import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.WindowsJunctionUtils;
 import org.apache.tools.ant.util.VectorSet;
+import org.apache.tools.ant.util.WindowsJunctionUtils;
 
 /**
  * Class for scanning a directory for files/directories which match certain
diff --git a/src/main/org/apache/tools/ant/types/AbstractFileSet.java 
b/src/main/org/apache/tools/ant/types/AbstractFileSet.java
index a3c5d1b88..fa2608b73 100644
--- a/src/main/org/apache/tools/ant/types/AbstractFileSet.java
+++ b/src/main/org/apache/tools/ant/types/AbstractFileSet.java
@@ -55,6 +55,7 @@ import org.apache.tools.ant.types.selectors.SelectorScanner;
 import org.apache.tools.ant.types.selectors.SizeSelector;
 import org.apache.tools.ant.types.selectors.SymlinkSelector;
 import org.apache.tools.ant.types.selectors.TypeSelector;
+import org.apache.tools.ant.types.selectors.WindowsJunctionSelector;
 import org.apache.tools.ant.types.selectors.WritableSelector;
 import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
 
@@ -885,6 +886,14 @@ public abstract class AbstractFileSet extends DataType
         appendSelector(o);
     }
 
+    /**
+     * @param e WindowsJunctionSelector
+     * @since 1.10.16
+     */
+    public void addWindowsJunction(WindowsJunctionSelector e) {
+        appendSelector(e);
+    }
+
     /**
      * Add an arbitrary selector.
      * @param selector the <code>FileSelector</code> to add.
diff --git 
a/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java 
b/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java
index 8ebad85ca..33f447244 100644
--- 
a/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java
+++ 
b/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java
@@ -339,6 +339,14 @@ public abstract class AbstractSelectorContainer extends 
DataType
         appendSelector(o);
     }
 
+    /**
+     * @param e WindowsJunctionSelector
+     * @since 1.10.16
+     */
+    public void addWindowsJunction(WindowsJunctionSelector e) {
+        appendSelector(e);
+    }
+
     /**
      * add an arbitrary selector
      * @param selector the selector to add
diff --git 
a/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java 
b/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
index fcf44136f..938f0e91c 100644
--- a/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
+++ b/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
@@ -336,6 +336,14 @@ public abstract class BaseSelectorContainer extends 
BaseSelector
         appendSelector(o);
     }
 
+    /**
+     * @param e WindowsJunctionSelector
+     * @since 1.10.16
+     */
+    public void addWindowsJunction(WindowsJunctionSelector e) {
+        appendSelector(e);
+    }
+
     /**
      * add an arbitrary selector
      * @param selector the selector to add
diff --git a/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java 
b/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
index e9b552c2b..760a49ee0 100644
--- a/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
@@ -24,7 +24,7 @@ import java.nio.file.Files;
 /**
  * A selector that selects symbolic links.
  *
- * <p>Executable is defined in terms of {@link
+ * <p>Is defined in terms of {@link
  * java.nio.file.Files#isSymbolicLink}, this means the selector will
  * accept any file that exists and is a symbolic link.</p>
  *
diff --git a/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java 
b/src/main/org/apache/tools/ant/types/selectors/WindowsJunctionSelector.java
similarity index 68%
copy from src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
copy to 
src/main/org/apache/tools/ant/types/selectors/WindowsJunctionSelector.java
index e9b552c2b..dcc01b480 100644
--- a/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/WindowsJunctionSelector.java
@@ -19,21 +19,21 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
-import java.nio.file.Files;
+import org.apache.tools.ant.util.WindowsJunctionUtils;
 
 /**
- * A selector that selects symbolic links.
+ * A selector that selects Windows junctions.
  *
- * <p>Executable is defined in terms of {@link
- * java.nio.file.Files#isSymbolicLink}, this means the selector will
- * accept any file that exists and is a symbolic link.</p>
+ * <p>The selector will accept any file that exists and is a Windows 
junction.</p>
  *
- * @since Ant 1.10.0
+ * @since Ant 1.10.16
  */
-public class SymlinkSelector implements FileSelector {
+public class WindowsJunctionSelector implements FileSelector {
+
+    private static final WindowsJunctionUtils JUNCTION_UTILS = 
WindowsJunctionUtils.getWindowsJunctionUtils();
 
     public boolean isSelected(File basedir, String filename, File file) {
-        return file != null && Files.isSymbolicLink(file.toPath());
+        return file != null && JUNCTION_UTILS.isJunctionSafe(file);
     }
 
 }
diff --git a/src/tests/antunit/types/selectors/windows-junction-test.xml 
b/src/tests/antunit/types/selectors/windows-junction-test.xml
new file mode 100644
index 000000000..39ad47819
--- /dev/null
+++ b/src/tests/antunit/types/selectors/windows-junction-test.xml
@@ -0,0 +1,77 @@
+<?xml version="1.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
+
+      https://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 xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+  <import file="../../antunit-base.xml" />
+
+  <property name="dir" value="testdir"/>
+  <property name="link" value="testlink"/>
+
+  <target name="createTestdir">
+    <mkdir dir="${output}/${dir}"/>
+  </target>
+
+  <target name="testWindowsJunction" depends="makeJunction" if="windows_os">
+    <au:assertTrue>
+      <resourcecount when="equal" count="1">
+        <dirset dir="${output}">
+          <windowsJunction/>
+        </dirset>
+      </resourcecount>
+    </au:assertTrue>
+    <au:assertTrue>
+      <resourcecount when="equal" count="0">
+        <dirset dir="${output}" excludes="${link}">
+          <windowsJunction/>
+        </dirset>
+      </resourcecount>
+    </au:assertTrue>
+  </target>
+
+  <target name="makeJunction" depends="createTestdir" if="windows_os">
+    <mklink linktype="junction"
+        link="${output}/${link}" targetFile="${output}/${dir}"/>
+  </target>
+
+  <target name="testNoWindowsJunction" depends="createTestdir">
+    <au:assertTrue>
+      <resourcecount when="equal" count="0">
+        <dirset dir="${output}">
+          <windowsJunction/>
+        </dirset>
+      </resourcecount>
+    </au:assertTrue>
+  </target>
+
+  <target name="testAsFalseConditions" depends="createTestdir">
+    <au:assertFalse>
+      <isfileselected file="${output}/${link}">
+        <windowsJunction/>
+      </isfileselected>
+    </au:assertFalse>
+  </target>
+
+  <target name="testAsTrueConditions" depends="makeJunction" if="windows_os">
+    <au:assertTrue>
+      <isfileselected file="${output}/${link}">
+        <windowsJunction/>
+      </isfileselected>
+    </au:assertTrue>
+  </target>
+
+</project>

Reply via email to