This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-io.git
The following commit(s) were added to refs/heads/master by this push: new 5bcc9a889 [IO-875] CopyDirectoryVisitor ignores fileFilter (#743) 5bcc9a889 is described below commit 5bcc9a8890ccb33b1615ac5e0a74f56bc7c01037 Author: Pierre Baumard <pbaum...@gmail.com> AuthorDate: Mon May 5 14:14:16 2025 +0200 [IO-875] CopyDirectoryVisitor ignores fileFilter (#743) * [IO-875] CopyDirectoryVisitor ignores fileFilter * 100% test coverage for CopyDirectoryVisitor * Fix javadoc typo --- .../commons/io/file/CopyDirectoryVisitor.java | 11 ++++-- .../commons/io/file/CountingPathVisitor.java | 16 +++++++- .../commons/io/file/CopyDirectoryVisitorTest.java | 44 ++++++++++++++++++---- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java b/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java index 2716357b8..da9d1408c 100644 --- a/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java +++ b/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java @@ -45,7 +45,7 @@ private static CopyOption[] toCopyOption(final CopyOption... copyOptions) { private final Path targetDirectory; /** - * Constructs a instance that deletes files except for the files and directories explicitly given. + * Constructs an instance that copies all files. * * @param pathCounter How to count visits. * @param sourceDirectory The source directory @@ -60,7 +60,7 @@ public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDir } /** - * Constructs a instance that deletes files except for the files and directories explicitly given. + * Constructs an instance that copies files matching the given file and directory filters. * * @param pathCounter How to count visits. * @param fileFilter How to filter file paths. @@ -171,8 +171,11 @@ private Path resolveRelativeAsString(final Path directory) { @Override public FileVisitResult visitFile(final Path sourceFile, final BasicFileAttributes attributes) throws IOException { final Path targetFile = resolveRelativeAsString(sourceFile); - copy(sourceFile, targetFile); - return super.visitFile(targetFile, attributes); + if (accept(sourceFile, attributes)) { + copy(sourceFile, targetFile); + updateFileCounters(targetFile, attributes); + } + return FileVisitResult.CONTINUE; } } diff --git a/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java b/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java index a8ca9055f..d0a58251e 100644 --- a/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java +++ b/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java @@ -290,6 +290,18 @@ protected void updateDirCounter(final Path dir, final IOException exc) { pathCounters.getDirectoryCounter().increment(); } + /** + * Returns true to copy the given file, false if not. + * + * @param file the visited file. + * @param attributes the visited file attributes. + * @return true to copy the given file, false if not. + */ + protected boolean accept(final Path file, final BasicFileAttributes attributes) { + // Note: A file can be a symbolic link to a directory. + return Files.exists(file) && fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE; + } + /** * Updates the counters for visiting the given file. * @@ -303,10 +315,10 @@ protected void updateFileCounters(final Path file, final BasicFileAttributes att @Override public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) throws IOException { - // Note: A file can be a symbolic link to a directory. - if (Files.exists(file) && fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE) { + if (accept(file, attributes)) { updateFileCounters(file, attributes); } return FileVisitResult.CONTINUE; } + } diff --git a/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java b/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java index e61c5cfe7..1bf5e90cd 100644 --- a/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java +++ b/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java @@ -20,23 +20,27 @@ import static org.apache.commons.io.file.CounterAssertions.assertCounts; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.nio.file.CopyOption; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.function.Supplier; import org.apache.commons.io.file.Counters.PathCounters; +import org.apache.commons.io.filefilter.NameFileFilter; import org.apache.commons.io.filefilter.TrueFileFilter; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; /** - * Tests {@link CountingPathVisitor}. + * Tests {@link CopyDirectoryVisitor}. */ public class CopyDirectoryVisitorTest extends TestArguments { @@ -59,19 +63,22 @@ public void testCopyDirectoryEmptyFolder(final PathCounters pathCounters) throws assertEquals(sourceDir.get(), ((AbstractPathWrapper) visitFileTree.getSourceDirectory()).get()); assertEquals(sourceDir, visitFileTree.getSourceDirectory()); assertEquals(targetDir, visitFileTree.getTargetDirectory()); - assertEquals(targetDir, visitFileTree.getTargetDirectory()); - // + // Tests equals and hashCode assertEquals(visitFileTree, supplier.get()); assertEquals(visitFileTree.hashCode(), supplier.get().hashCode()); assertEquals(visitFileTree, visitFileTree); assertEquals(visitFileTree.hashCode(), visitFileTree.hashCode()); assertNotEquals(visitFileTree, "not"); + assertNotEquals(visitFileTree, new DeletingPathVisitor(pathCounters)); + assertNotEquals(visitFileTree, new CopyDirectoryVisitor(pathCounters, sourceDir, targetDir)); + assertNotEquals(visitFileTree, new CopyDirectoryVisitor(pathCounters, sourceDir, sourceDir, EXPECTED_COPY_OPTIONS)); + assertNotEquals(visitFileTree, new CopyDirectoryVisitor(pathCounters, targetDir, sourceDir, EXPECTED_COPY_OPTIONS)); assertNotEquals(visitFileTree, CountingPathVisitor.withLongCounters()); } } /** - * Tests an empty folder. + * Tests an empty folder with filters. */ @ParameterizedTest @MethodSource("pathCounters") @@ -84,7 +91,7 @@ public void testCopyDirectoryEmptyFolderFilters(final PathCounters pathCounters) assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions()); assertEquals(sourceDir, visitFileTree.getSourceDirectory()); assertEquals(targetDir, visitFileTree.getTargetDirectory()); - // + // Tests equals and hashCode assertEquals(visitFileTree, supplier.get()); assertEquals(visitFileTree.hashCode(), supplier.get().hashCode()); assertEquals(visitFileTree, visitFileTree); @@ -92,6 +99,26 @@ public void testCopyDirectoryEmptyFolderFilters(final PathCounters pathCounters) } } + /** + * Tests filters. + */ + @ParameterizedTest + @MethodSource("pathCounters") + public void testCopyDirectoryFilters(final PathCounters pathCounters) throws IOException { + final Path sourceDir = Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-4"); + final CopyDirectoryVisitor visitFileTree = PathUtils.visitFileTree(new CopyDirectoryVisitor(pathCounters, new NameFileFilter("file-size-1.bin"), + new NameFileFilter("dirs-2-file-size-4", "dirs-a-file-size-1"), sourceDir, targetDir, null), + sourceDir); + assertCounts(2, 1, 2, visitFileTree); + assertArrayEquals(PathUtils.EMPTY_COPY_OPTIONS, visitFileTree.getCopyOptions()); + assertEquals(sourceDir, visitFileTree.getSourceDirectory()); + assertEquals(targetDir, visitFileTree.getTargetDirectory()); + assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1/file-size-1.bin"))); + assertFalse(Files.exists(targetDir.resolve("dirs-a-file-size-1/file-size-2.bin"))); + assertFalse(Files.exists(targetDir.resolve("dirs-a-file-size-2"))); + } + + /** * Tests a directory with one file of size 0. */ @@ -105,10 +132,10 @@ public void testCopyDirectoryFolders1FileSize0(final PathCounters pathCounters) assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions()); assertEquals(sourceDir, visitFileTree.getSourceDirectory()); assertEquals(targetDir, visitFileTree.getTargetDirectory()); - // + assertTrue(Files.exists(targetDir.resolve("file-size-0.bin"))); + // Tests equals and hashCode assertEquals(visitFileTree, supplier.get()); assertEquals(visitFileTree.hashCode(), supplier.get().hashCode()); - assertEquals(visitFileTree, visitFileTree); assertEquals(visitFileTree.hashCode(), visitFileTree.hashCode()); } @@ -125,6 +152,7 @@ public void testCopyDirectoryFolders1FileSize1(final PathCounters pathCounters) assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions()); assertEquals(sourceDir, visitFileTree.getSourceDirectory()); assertEquals(targetDir, visitFileTree.getTargetDirectory()); + assertTrue(Files.exists(targetDir.resolve("file-size-1.bin"))); } /** @@ -140,6 +168,8 @@ public void testCopyDirectoryFolders2FileSize2(final PathCounters pathCounters) assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions()); assertEquals(sourceDir, visitFileTree.getSourceDirectory()); assertEquals(targetDir, visitFileTree.getTargetDirectory()); + assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1/file-size-1.bin"))); + assertTrue(Files.exists(targetDir.resolve("dirs-b-file-size-1/file-size-1.bin"))); } }