diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTask.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTask.kt index cb3991b03739..555c7f649082 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTask.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTask.kt @@ -12,10 +12,14 @@ import java.io.File import javax.inject.Inject import org.gradle.api.DefaultTask import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileCollection import org.gradle.api.file.FileSystemOperations +import org.gradle.api.file.FileTree import org.gradle.api.file.RegularFile +import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.ListProperty import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction @@ -35,44 +39,64 @@ abstract class PreparePrefabHeadersTask : DefaultTask() { @get:OutputDirectory abstract val outputDir: DirectoryProperty + @get:InputFiles + val headers: FileCollection + get() = + objects + .fileCollection() + .from( + input.map { entries -> + entries.flatMap { (_, pathToPrefixCouples) -> + pathToPrefixCouples.map { (headerPath, _) -> headersUnder(headerPath) } + } + } + ) + @get:Inject abstract val fs: FileSystemOperations + @get:Inject abstract val objects: ObjectFactory + @TaskAction fun taskAction() { input.get().forEach { (libraryName, pathToPrefixCouples) -> val outputFolder: RegularFile = outputDir.file(libraryName).get() + fs.delete { deleteSpec -> deleteSpec.delete(outputFolder) } pathToPrefixCouples.forEach { (headerPath, headerPrefix) -> fs.copy { copySpec -> - copySpec.from(headerPath) - copySpec.include("**/*.h") - copySpec.exclude("**/*.cpp") - copySpec.exclude("**/*.txt") - // We don't want to copy all the boost headers as they are 250Mb+ - copySpec.include("boost/config.hpp") - copySpec.include("boost/config/**/*.hpp") - copySpec.include("boost/core/*.hpp") - copySpec.include("boost/detail/workaround.hpp") - copySpec.include("boost/operators.hpp") - copySpec.include("boost/preprocessor/**/*.hpp") - // Headers needed for exposing rrc_text and rrc_textinput - copySpec.include("boost/container_hash/**/*.hpp") - copySpec.include("boost/detail/**/*.hpp") - copySpec.include("boost/intrusive/**/*.hpp") - copySpec.include("boost/iterator/**/*.hpp") - copySpec.include("boost/move/**/*.hpp") - copySpec.include("boost/mpl/**/*.hpp") - copySpec.include("boost/mp11/**/*.hpp") - copySpec.include("boost/describe/**/*.hpp") - copySpec.include("boost/type_traits/**/*.hpp") - copySpec.include("boost/utility/**/*.hpp") - copySpec.include("boost/assert.hpp") - copySpec.include("boost/static_assert.hpp") - copySpec.include("boost/cstdint.hpp") - copySpec.include("boost/utility.hpp") - copySpec.include("boost/version.hpp") + copySpec.from(headersUnder(headerPath)) copySpec.into(File(outputFolder.asFile, headerPrefix)) } } } } + + private fun headersUnder(headerPath: String): FileTree = + objects.fileTree().from(headerPath).matching { patterns -> + patterns.include("**/*.h") + patterns.exclude("**/*.cpp") + patterns.exclude("**/*.txt") + // We don't want to copy all the boost headers as they are 250Mb+ + patterns.include("boost/config.hpp") + patterns.include("boost/config/**/*.hpp") + patterns.include("boost/core/*.hpp") + patterns.include("boost/detail/workaround.hpp") + patterns.include("boost/operators.hpp") + patterns.include("boost/preprocessor/**/*.hpp") + // Headers needed for exposing rrc_text and rrc_textinput + patterns.include("boost/container_hash/**/*.hpp") + patterns.include("boost/detail/**/*.hpp") + patterns.include("boost/intrusive/**/*.hpp") + patterns.include("boost/iterator/**/*.hpp") + patterns.include("boost/move/**/*.hpp") + patterns.include("boost/mpl/**/*.hpp") + patterns.include("boost/mp11/**/*.hpp") + patterns.include("boost/describe/**/*.hpp") + patterns.include("boost/type_traits/**/*.hpp") + patterns.include("boost/utility/**/*.hpp") + patterns.include("boost/assert.hpp") + patterns.include("boost/static_assert.hpp") + patterns.include("boost/cstdint.hpp") + patterns.include("boost/utility.hpp") + patterns.include("boost/version.hpp") + } } diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTaskTest.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTaskTest.kt index b692c65e4b8d..4b1e714e710b 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTaskTest.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTaskTest.kt @@ -204,6 +204,42 @@ class PreparePrefabHeadersTaskTest { assertThat(File(outputDir, "sample_library/boost/anothermodule/wedontuse.hpp")).doesNotExist() } + @Test + fun preparePrefabHeadersTask_declaresTheHeadersItCopiesAsInputs() { + val header = File(tempFolder.root, "input/hello.h").apply { createNewPathAndFile() } + File(tempFolder.root, "input/hello.cpp").createNewPathAndFile() + + val project = createProject(projectDir = tempFolder.root) + val task = + createTestTask(project = project) { + it.outputDir.set(tempFolder.newFolder("output")) + it.input.set(listOf(PrefabPreprocessingEntry("sample_library", "input/" to ""))) + } + + assertThat(task.inputs.files.files).containsExactly(header) + } + + @Test + fun preparePrefabHeadersTask_withARemovedHeader_removesItsCopy() { + val outputDir = tempFolder.newFolder("output") + val removedHeader = File(tempFolder.root, "input/removed.h").apply { createNewPathAndFile() } + File(tempFolder.root, "input/kept.h").createNewPathAndFile() + + val project = createProject(projectDir = tempFolder.root) + val task = + createTestTask(project = project) { + it.outputDir.set(outputDir) + it.input.set(listOf(PrefabPreprocessingEntry("sample_library", "input/" to ""))) + } + + task.taskAction() + removedHeader.delete() + task.taskAction() + + assertThat(File(outputDir, "sample_library/removed.h")).doesNotExist() + assertThat(File(outputDir, "sample_library/kept.h")).exists() + } + private fun File.createNewPathAndFile() { parentFile.mkdirs() createNewFile()