diff --git a/subprojects/files/src/main/java/org/gradle/api/internal/file/collections/AbstractSingletonFileTree.java b/subprojects/files/src/main/java/org/gradle/api/internal/file/collections/AbstractSingletonFileTree.java index 046a643d7818..66ee1d9e5e8a 100644 --- a/subprojects/files/src/main/java/org/gradle/api/internal/file/collections/AbstractSingletonFileTree.java +++ b/subprojects/files/src/main/java/org/gradle/api/internal/file/collections/AbstractSingletonFileTree.java @@ -21,7 +21,7 @@ import org.gradle.api.tasks.util.PatternFilterable; import org.gradle.api.tasks.util.PatternSet; -public abstract class AbstractSingletonFileTree implements SingletonFileTree, PatternFilterableFileTree { +public abstract class AbstractSingletonFileTree implements SingletonFileTree, PatternFilterableFileTree, FileSystemMirroringFileTree { private final PatternSet patterns; protected AbstractSingletonFileTree(PatternSet patterns) { @@ -52,4 +52,9 @@ protected PatternSet filterPatternSet(PatternFilterable patterns) { patternSet.copyFrom(patterns); return patternSet; } + + @Override + public DirectoryFileTree getMirror() { + return new FileBackedDirectoryFileTree(getFile()).filter(patterns); + } } diff --git a/subprojects/files/src/test/groovy/org/gradle/api/internal/file/collections/DefaultSingletonFileTreeTest.groovy b/subprojects/files/src/test/groovy/org/gradle/api/internal/file/collections/DefaultSingletonFileTreeTest.groovy index e3fcc8249c4d..805f6727e0f2 100644 --- a/subprojects/files/src/test/groovy/org/gradle/api/internal/file/collections/DefaultSingletonFileTreeTest.groovy +++ b/subprojects/files/src/test/groovy/org/gradle/api/internal/file/collections/DefaultSingletonFileTreeTest.groovy @@ -15,13 +15,19 @@ */ package org.gradle.api.internal.file.collections +import org.gradle.api.file.FileVisitDetails +import org.gradle.api.file.FileVisitor +import org.gradle.test.fixtures.file.TestNameTestDirectoryProvider import org.gradle.util.UsesNativeServices +import org.junit.Rule +import spock.lang.Issue import spock.lang.Specification -import org.gradle.api.file.FileVisitor -import org.gradle.api.file.FileVisitDetails @UsesNativeServices class DefaultSingletonFileTreeTest extends Specification { + @Rule + final TestNameTestDirectoryProvider temporaryFolder = new TestNameTestDirectoryProvider() + def hasUsefulDisplayName() { File f = new File('test-file') DefaultSingletonFileTree tree = new DefaultSingletonFileTree(f) @@ -45,4 +51,46 @@ class DefaultSingletonFileTreeTest extends Specification { } 0 * visitor._ } + + def "can be converted to a directory tree"() { + File f = temporaryFolder.file('test-file') + f.createNewFile() + DefaultSingletonFileTree singletonFileTree = new DefaultSingletonFileTree(f) + def tree = new FileTreeAdapter(singletonFileTree) + + when: + def fileTrees = tree.getAsFileTrees() + then: + fileTrees.size() == 1 + def directoryTree = fileTrees[0] + directoryTree.dir == f.parentFile + new FileTreeAdapter(directoryTree).files == [f] as Set + } + + @Issue("https://github.com/gradle/gradle/issues/8394") + def "convert filtered tree to empty file trees"() { + File rootFile = temporaryFolder.file('test-file') + rootFile.createNewFile() + DefaultSingletonFileTree singletonFileTree = new DefaultSingletonFileTree(rootFile) + def tree = new FileTreeAdapter(singletonFileTree).matching { + it.include 'different' + } + + when: + def fileTrees = tree.getAsFileTrees() + then: + fileTrees.size() == 0 + } + + def "contains delegates correctly"() { + File rootFile = temporaryFolder.file('test-file') + rootFile.createNewFile() + DefaultSingletonFileTree singletonFileTree = new DefaultSingletonFileTree(rootFile) + def tree = new FileTreeAdapter(singletonFileTree) + + expect: + tree.contains(rootFile) + !tree.contains(temporaryFolder.file('test-file-new')) + !tree.matching { it.include 'different' }.contains(rootFile) + } }