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

main.name.remal.gradle_plugins.plugins.publish.MavenPublicationsExtensions.kt Maven / Gradle / Ivy

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

import name.remal.appendElement
import name.remal.default
import name.remal.getChildElements
import name.remal.gradle_plugins.dsl.Extension
import name.remal.gradle_plugins.dsl.extensions.afterEvaluateOrNow
import name.remal.gradle_plugins.dsl.extensions.all
import name.remal.gradle_plugins.dsl.extensions.classifierCompatible
import name.remal.gradle_plugins.dsl.extensions.createWithOptionalUniqueSuffix
import name.remal.gradle_plugins.dsl.extensions.get
import name.remal.gradle_plugins.dsl.extensions.getOrNull
import name.remal.gradle_plugins.dsl.extensions.main
import name.remal.gradle_plugins.dsl.extensions.makeSrcDirsUnique
import name.remal.gradle_plugins.dsl.utils.getGradleLogger
import name.remal.hierarchy
import name.remal.plusAssign
import name.remal.remove
import name.remal.warn
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency.ARCHIVES_CONFIGURATION
import org.gradle.api.component.SoftwareComponent
import org.gradle.api.component.SoftwareComponentContainer
import org.gradle.api.internal.java.WebApplication
import org.gradle.api.plugins.BasePlugin.ASSEMBLE_TASK_NAME
import org.gradle.api.publish.PublicationContainer
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.api.tasks.bundling.Jar
import org.w3c.dom.Element
import kotlin.LazyThreadSafetyMode.NONE

@Extension
class MavenPublicationsExtensions(
    private val publications: PublicationContainer,
    private val tasks: TaskContainer,
    private val sourceSets: SourceSetContainer,
    private val project: Project
) {

    companion object {
        private val logger = getGradleLogger(MavenPublicationsExtensions::class.java)

        private val webApplicationComponentClass: Class by lazy(NONE) { WebApplication::class.java }
    }

    fun mavenDefault() = publications.createWithOptionalUniqueSuffix("mavenDefault", MavenPublication::class.java) { publication ->
        project.afterEvaluateOrNow { _ ->

            var isComponentSet = false
            fun tryToSetComponent(getter: SoftwareComponentContainer.() -> SoftwareComponent?) {
                if (isComponentSet) return
                val component = getter(project.components)
                if (component != null) {
                    try {
                        publication.from(component)
                    } catch (e: ClassCastException) {
                        logger.warn(e)
                        return
                    }
                    isComponentSet = true
                }
            }
            tryToSetComponent { singleOrNull() }
            tryToSetComponent { firstOrNull { webApplicationComponentClass.isInstance(it) } }
            tryToSetComponent { firstOrNull { it.javaClass.hierarchy.any { it.simpleName == "JavaPlatform" } } }
            tryToSetComponent { firstOrNull { it.javaClass.hierarchy.any { it.simpleName == "KotlinSoftwareComponent" } } }
            tryToSetComponent { firstOrNull { it.javaClass.hierarchy.any { it.simpleName == "BuildableJavaComponent" } } }

            val archivesConf = project.configurations[ARCHIVES_CONFIGURATION]
            archivesConf.allArtifacts.forEach { artifact ->
                if (publication.artifacts.none { it.extension.default() == artifact.extension.default() && it.classifier.default() == artifact.classifier.default() }) {
                    publication.artifact(artifact)
                }
            }

            if (publication.artifacts.none { "sources" == it.classifier }) {
                publication.artifact(
                    tasks.withType(AbstractArchiveTask::class.java).firstOrNull { "sources" == it.classifierCompatible }
                        ?: tasks.createWithOptionalUniqueSuffix("sourcesJar", Jar::class.java) { task ->
                            task.classifierCompatible = "sources"
                            task.from(sourceSets.main.allSource.makeSrcDirsUnique())
                        }
                )
            }

            if (publication.artifacts.none { "javadoc" == it.classifier }) {
                publication.artifact(
                    tasks.withType(AbstractArchiveTask::class.java).firstOrNull { "javadoc" == it.classifierCompatible }
                        ?: tasks.createWithOptionalUniqueSuffix("emptyJavadocJar", Jar::class.java) { task ->
                            task.classifierCompatible = "javadoc"
                            project.tasks.all(ASSEMBLE_TASK_NAME) { task.shouldRunAfter(it) }
                        }
                )
            }

        }
    }

    fun mavenBom() = publications.createWithOptionalUniqueSuffix("mavenBom", MavenPublication::class.java) { publication ->
        publication.pom { pom ->

            project.afterEvaluateOrNow { _ ->
                publication.artifactId += "-bom"
            }

            pom.packaging = "pom"

            pom.withXml {
                val root: Element = it.asElement()

                root.getChildElements("dependencyManagement").forEach { it.remove() }
                root.getChildElements("dependencies").forEach { it.remove() }

                val managementNode: Element by lazy(NONE) { root.appendElement("dependencyManagement").appendElement("dependencies") }

                val groupIdPrefix = publication.groupId + '.'
                val version = publication.version
                project.allprojects.asSequence()
                    .mapNotNull { it.getOrNull(PublishingExtension::class.java) }
                    .flatMap { it.publications.asSequence() }
                    .filterIsInstance(MavenPublication::class.java)
                    .filter { it !== publication }
                    .filter { "${it.groupId}.".startsWith(groupIdPrefix) && it.version == version }
                    .forEach { otherPublication ->
                        managementNode.appendElement("dependency").apply {
                            appendElement("groupId") += otherPublication.groupId
                            appendElement("artifactId") += otherPublication.artifactId
                            appendElement("version") += otherPublication.version
                        }
                    }
            }

        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy