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

org.jetbrains.kotlin.gradle.plugin.mpp.ModuleIds.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC2
Show newest version
/*
 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.gradle.plugin.mpp

import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.component.*
import org.gradle.api.artifacts.result.ResolvedComponentResult
import org.gradle.api.publish.maven.MavenPublication
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.PublishedModuleCoordinatesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.currentBuildId
import org.jetbrains.kotlin.gradle.utils.buildPathCompat
import org.jetbrains.kotlin.gradle.utils.currentBuild
import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.project.model.KpmLocalModuleIdentifier
import org.jetbrains.kotlin.project.model.KpmMavenModuleIdentifier
import org.jetbrains.kotlin.project.model.KpmModuleIdentifier

internal object ModuleIds {
    fun fromDependency(dependency: Dependency): ModuleDependencyIdentifier = when (dependency) {
        is ProjectDependency -> idOfRootModule(dependency.dependencyProject)
        else -> ModuleDependencyIdentifier(dependency.group, dependency.name)
    }

    fun fromComponentSelector(
        thisProject: Project,
        componentSelector: ComponentSelector
    ): ModuleDependencyIdentifier = when (componentSelector) {
        is ProjectComponentSelector -> idOfRootModuleByProjectPath(thisProject, componentSelector.projectPath)
        is ModuleComponentSelector -> ModuleDependencyIdentifier(componentSelector.group, componentSelector.module)
        else -> idFromName(componentSelector.displayName)
    }

    private fun fromComponentId(
        thisProject: Project,
        componentIdentifier: ComponentIdentifier
    ): ModuleDependencyIdentifier =
        when (componentIdentifier) {
            is ProjectComponentIdentifier -> idOfRootModuleByProjectPath(thisProject, componentIdentifier.projectPath)
            is ModuleComponentIdentifier -> ModuleDependencyIdentifier(componentIdentifier.group, componentIdentifier.module)
            else -> idFromName(componentIdentifier.displayName)
        }

    fun fromComponent(thisProject: Project, component: ResolvedComponentResult) =
        // If the project component comes from another build, we can't extract anything from it, so just use the module coordinates:
        if (component is ProjectComponentIdentifier && component !in thisProject.currentBuild)
            ModuleDependencyIdentifier(component.moduleVersion?.group ?: "unspecified", component.moduleVersion?.name ?: "unspecified")
        else
            fromComponentId(thisProject, component.id)

    fun idOfRootModule(project: Project): ModuleDependencyIdentifier =
        if (project.multiplatformExtensionOrNull != null) {
            val rootPublication = project.multiplatformExtension.rootSoftwareComponent.publicationDelegate
            val group = rootPublication?.groupId ?: project.group.toString()
            val name = rootPublication?.artifactId ?: project.name
            ModuleDependencyIdentifier(group, name)
        } else {
            ModuleDependencyIdentifier(project.group.toString(), project.name)
        }

    private fun idFromName(name: String) =
        ModuleDependencyIdentifier(null, name)

    private fun idOfRootModuleByProjectPath(thisProject: Project, projectPath: String): ModuleDependencyIdentifier =
        idOfRootModule(thisProject.project(projectPath))

    // FIXME use capabilities to point to auxiliary modules
    fun lossyFromModuleIdentifier(thisProject: Project, moduleIdentifier: KpmModuleIdentifier): ModuleDependencyIdentifier {
        when (moduleIdentifier) {
            is KpmLocalModuleIdentifier -> {
                check(moduleIdentifier.buildId == thisProject.currentBuildId().buildPathCompat)
                val dependencyProject = thisProject.project(moduleIdentifier.projectId)
                val topLevelExtension = dependencyProject.topLevelExtension
                val getRootPublication: () -> MavenPublication? = when {
                    dependencyProject.pm20ExtensionOrNull != null -> {
                        { dependencyProject.pm20Extension.kpmModelContainer.rootPublication }
                    }
                    topLevelExtension is KotlinMultiplatformExtension -> {
                        { topLevelExtension.rootSoftwareComponent.publicationDelegate }
                    }
                    else -> error("unexpected top-level extension $topLevelExtension")
                }
                val capabilities = when {
                    dependencyProject.pm20ExtensionOrNull != null -> listOfNotNull(ComputedCapability.capabilityStringFromModule(
                        dependencyProject.pm20Extension.modules.single { it.moduleIdentifier == moduleIdentifier }
                    ))
                    topLevelExtension is KotlinMultiplatformExtension -> emptyList()
                    else -> error("unexpected top-level extension $topLevelExtension")
                }
                val coordinatesProvider = MavenPublicationCoordinatesProvider(
                    dependencyProject,
                    getRootPublication,
                    defaultModuleSuffix = null,
                    capabilities = capabilities
                )
                return ChangingModuleDependencyIdentifier({ coordinatesProvider.group }, { coordinatesProvider.name })
            }
            is KpmMavenModuleIdentifier -> {
                return ModuleDependencyIdentifier(moduleIdentifier.group, moduleIdentifier.name)
            }
            else -> error("unexpected module identifier $moduleIdentifier")
        }
    }
}

open class MavenPublicationCoordinatesProvider(
    project: Project,
    val getPublication: () -> MavenPublication?,
    defaultModuleSuffix: String?,
    override val capabilities: Iterable = emptyList()
) : PublishedModuleCoordinatesProvider {

    override val group: String by project.provider {
        getPublication()?.groupId ?: project.group.toString()
    }

    override val name: String by project.provider {
        getPublication()?.artifactId ?: project.name.plus(defaultModuleSuffix?.let { "-$it" }.orEmpty())
    }

    override val version: String by project.provider {
        getPublication()?.version ?: project.version.toString()
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy