main.name.remal.gradle_plugins.plugins.merge_resources.MergeResourcesPlugin.kt Maven / Gradle / Ivy
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