All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.name.remal.gradle_plugins.plugins.merge_resources.MergeResourcesPlugin.kt Maven / Gradle / Ivy

There is a newer version: 1.9.2
Show newest version
package name.remal.gradle_plugins.plugins.merge_resources

import com.google.common.collect.MultimapBuilder
import name.remal.Services.loadServicesList
import name.remal.buildList
import name.remal.buildMap
import name.remal.forceDeleteRecursively
import name.remal.gradle_plugins.dsl.ApplyPluginClasses
import name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin
import name.remal.gradle_plugins.dsl.Plugin
import name.remal.gradle_plugins.dsl.PluginAction
import name.remal.gradle_plugins.dsl.extensions.all
import name.remal.gradle_plugins.dsl.extensions.buildTempDir
import name.remal.gradle_plugins.dsl.extensions.visitFiles
import name.remal.gradle_plugins.dsl.utils.matches
import name.remal.gradle_plugins.plugins.common.CommonSettingsPlugin
import org.gradle.api.file.RelativePath
import org.gradle.api.tasks.AbstractCopyTask
import org.gradle.api.tasks.TaskContainer
import java.io.File

@Plugin(
    id = "name.remal.merge-resources",
    description = "Plugin that merges resources from different output directories while executing Copy tasks",
    tags = ["common"]
)
@ApplyPluginClasses(CommonSettingsPlugin::class)
class MergeResourcesPlugin : BaseReflectiveProjectPlugin() {

    companion object {
        private val resourceMergers = loadServicesList(ResourceMerger::class.java)
        private val resourceMergerFactories = loadServicesList(ResourceMergerFactory::class.java)
    }

    @PluginAction(isHidden = true)
    fun TaskContainer.setupAllAbstractCopyTask() {
        all(AbstractCopyTask::class.java) { task ->
            task.doFirst { _ ->

                val taskResourceMergers = buildList {
                    addAll(resourceMergers)
                    resourceMergerFactories.forEach {
                        addAll(it.createResourceMerger(task))
                    }
                }.sorted().apply { if (isEmpty()) return@doFirst }

                val filesToMerge = buildMap> {
                    val filesMapping = MultimapBuilder.treeKeys().linkedHashSetValues().build()
                    task.rootSpec.buildRootResolver().allSource.visitFiles { details ->
                        if (taskResourceMergers.any { it.getPatternMatcher(task.isCaseSensitive).matches(details.relativePath) }) {
                            filesMapping.put(details.relativePath, details.file)
                        }
                    }
                    filesMapping.asMap().forEach { relativePath, files ->
                        if (2 <= files.size) {
                            put(relativePath, files.toList())
                        }
                    }
                }.apply { if (isEmpty()) return@doFirst }

                val mergedFilesDir = task.project.file("${task.project.buildTempDir}/${task.name}.merged").forceDeleteRecursively()
                task.from(mergedFilesDir)

                val mergedFilesPath = mergedFilesDir.toPath().toAbsolutePath().normalize()
                task.exclude { details ->
                    if (details.relativePath in filesToMerge) {
                        val path = details.file.toPath().toAbsolutePath().normalize()
                        if (!mergedFilesPath.startsWith(path)) {
                            return@exclude true
                        }
                    }
                    return@exclude false
                }

                filesToMerge.forEach { relativePath, files ->
                    val resourceMerger = taskResourceMergers.first { it.getPatternMatcher(task.isCaseSensitive).matches(relativePath) }
                    logger.debug("Merge {} by {} into {}", files, resourceMerger.javaClass.name, mergedFilesDir)
                    resourceMerger.mergeFiles(relativePath, files, mergedFilesDir)
                }

            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy