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

name.remal.gradle_plugins.dsl.utils.findPluginId.kt Maven / Gradle / Ivy

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

import io.github.classgraph.ClassGraph
import name.remal.asSynchronized
import name.remal.concurrentMapOf
import name.remal.getMetaAnnotation
import name.remal.gradle_plugins.dsl.IMPLEMENTATION_CLASS_PLUGIN_DESCRIPTOR_KEY
import name.remal.gradle_plugins.dsl.Plugin
import name.remal.gradle_plugins.dsl.ProjectPluginClass
import name.remal.gradle_plugins.dsl.extensions.unwrapGradleGenerated
import name.remal.nullIfEmpty
import java.util.*
import java.util.Comparator.comparingInt
import java.util.Comparator.naturalOrder
import java.util.concurrent.ConcurrentMap

private val pluginIdCache: ConcurrentMap = concurrentMapOf()

fun findPluginId(pluginClass: ProjectPluginClass): String? {
    return pluginIdCache.computeIfAbsent(pluginClass.unwrapGradleGenerated()) { pluginClassKey ->
        var currentClass: Class<*>? = pluginClassKey
        while (currentClass != null && Any::class.java != currentClass) {
            currentClass.getMetaAnnotation(Plugin::class.java)?.id?.nullIfEmpty()?.let {
                return@computeIfAbsent it
            }
            currentClass = currentClass.superclass
        }

        val pluginIds = sortedSetOf(comparingInt(String::length).reversed().then(naturalOrder())).asSynchronized()
        ClassGraph()
            .overrideClassLoaders(pluginClassKey.classLoader)
            .whitelistPathsNonRecursive("META-INF/gradle-plugins")
            .scan().use {
                it.allResources.asSequence()
                    .filter { it.path.endsWith(".properties") }
                    .forEach { resource ->
                        val properties = Properties().also { props ->
                            try {
                                resource.open().use { props.load(it) }
                            } catch (e: Exception) {
                                return@forEach
                            }
                        }
                        val implementationClass = properties.getProperty(IMPLEMENTATION_CLASS_PLUGIN_DESCRIPTOR_KEY)
                        if (implementationClass == pluginClassKey.name) {
                            pluginIds.add(resource.path.substringAfterLast('/').substringBeforeLast('.'))
                        }
                    }
            }

        return@computeIfAbsent pluginIds.firstOrNull() ?: ""
    }.nullIfEmpty()
}

fun getPluginIdForLogging(pluginClass: ProjectPluginClass): String = findPluginId(pluginClass) ?: pluginClass.name




© 2015 - 2024 Weber Informatics LLC | Privacy Policy