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

name.remal.building.gradle_plugins.CopyDependenciesPlugin.kt Maven / Gradle / Ivy

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

import mu.KLogging
import name.remal.building.gradle_plugins.artifact.ArtifactsCacheCleanerPlugin
import name.remal.building.gradle_plugins.artifact.CachedArtifactsCollection
import name.remal.building.gradle_plugins.classes_relocation.DoNotProcessAnnotationAdder
import name.remal.building.gradle_plugins.dsl.createParentDirectories
import name.remal.building.gradle_plugins.dsl.java
import name.remal.building.gradle_plugins.dsl.use
import name.remal.building.gradle_plugins.utils.*
import name.remal.building.gradle_plugins.utils.Constants.CLASS_FILE_NAME_SUFFIX
import name.remal.building.gradle_plugins.utils.PluginIds.JAVA_PLUGIN_ID
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME
import org.gradle.api.tasks.compile.AbstractCompile
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassWriter
import java.io.File
import kotlin.text.RegexOption.IGNORE_CASE

open class CopyDependenciesPlugin : ProjectPlugin() {

    companion object : KLogging() {
        const val COPY_CONFIGURATION_NAME = "copy"

        private val EXCLUDE_ENTRY_NAME_REGEX = Regex("^META-INF/[^/]+\\.(MF|SF|DSA|RSA)\$", IGNORE_CASE)
    }

    override fun apply(project: Project) {
        project.applyPlugin(ArtifactsCacheCleanerPlugin::class.java)

        project.withPlugin(JAVA_PLUGIN_ID) {
            val copyConf = project.configurations.create(COPY_CONFIGURATION_NAME) {
                it.description = "Dependencies that will be copied directly to build output"
            }

            val mainSourceSet = project.java.sourceSets[MAIN_SOURCE_SET_NAME]
            project.java.sourceSets.configure { sourceSet ->
                val confName = if (sourceSet.name == mainSourceSet.name) sourceSet.compileOnlyConfigurationName else sourceSet.compileConfigurationName
                project.configurations.findByName(confName)?.extendsFrom(copyConf)
            }

            project.afterEvaluateOrdered {
                if (copyConf.allDependencies.isEmpty()) return@afterEvaluateOrdered

                fun executeCopy(destDir: File) {
                    val artifacts = CachedArtifactsCollection(copyConf)
                    artifacts.entryNames.forEach { entryName ->
                        if (EXCLUDE_ENTRY_NAME_REGEX.matches(entryName)) return@forEach
                        destDir.resolve(entryName).createParentDirectories().outputStream().use { outputStream ->
                            artifacts.openStream(entryName).use { inputStream ->
                                if (entryName.endsWith(CLASS_FILE_NAME_SUFFIX)) {
                                    val classWriter = ClassWriter(0)
                                    ClassReader(inputStream.readBytes()).accept(DoNotProcessAnnotationAdder(classWriter), 0)
                                    outputStream.write(classWriter.toByteArray())

                                } else {
                                    inputStream.copyTo(outputStream)
                                }
                            }
                        }
                    }
                }

                val compileJavaTask = project.tasks.findByName(mainSourceSet.compileJavaTaskName)?.apply {
                    doLastOrdered(1000) {
                        it as AbstractCompile
                        executeCopy(it.destinationDir)
                    }
                }

                project.tasks[mainSourceSet.classesTaskName].doLastOrdered(1000) {
                    if (null == compileJavaTask || compileJavaTask.state.noSource) { // TODO: test
                        val classesDir = mainSourceSet.output.classesDirs.iterator().next()
                        executeCopy(classesDir)
                    }
                }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy