public suspend fun resolve()

in build-systems/src/commonMain/kotlin/org/jetbrains/packagesearch/maven/PomResolver.kt [107:184]


    public suspend fun resolve(model: ProjectObjectModel): ProjectObjectModel {
        // Initialize the mergedPom with the given model.
        var mergedPom = model

        // Start by retrieving the parent of the given model.
        var currentParent = mergedPom.parent

        // Initialize a count variable to ensure that the loop does not run indefinitely.
        var count = 0

        // Loop to merge parent POMs until a max of 10 parent POMs or until there's no parent.
        while (count < 10) {
            count++

            // If there's no parent, break out of the loop.
            val parent = currentParent ?: break

            // Attempt to retrieve the POM for the parent. If it fails or if it's null, break out of the loop.
            val parentPom = runCatching { getPom(parent) }.getOrNull() ?: break

            // Merge the current mergedPom with its parent. This includes merging the dependencies,
            // dependencyManagement, and properties.
            // Note: The 'distinct()' function ensures that there are no duplicate items.
            mergedPom =
                mergedPom.copy(
                    groupId = mergedPom.groupId ?: parentPom.groupId,
                    artifactId = mergedPom.artifactId ?: parentPom.artifactId,
                    dependencies = parentPom.dependencies.plus(mergedPom.dependencies).distinct(),
                    dependencyManagement = parentPom.dependencyManagement.plus(mergedPom.dependencyManagement).distinct(),
                    properties = parentPom.properties + mergedPom.properties,
                )

            // Update the currentParent for the next iteration.
            currentParent = parentPom.parent
        }

        // Convert the mergedPom to a JSON object for easier property value resolution.
        val accessor = Json.encodeToJsonElement(mergedPom).jsonObject

        // Resolve the versions in the dependencyManagement section of the mergedPom.
        // This creates a map with keys as DependencyKey and values as the corresponding dependency with resolved version.
        val resolvedDependencyManagement =
            mergedPom.dependencyManagement
                .map { it.copy(version = it.version?.resolve(mergedPom.properties, accessor)) }
                .associateBy { DependencyKey(it.groupId, it.artifactId) }

        // Resolve the versions in the dependencies section of the mergedPom.
        // If the version is present in resolvedDependencyManagement, use that. Otherwise, resolve it using properties.
        val resolvedDependencies =
            mergedPom.dependencies
                .map {
                    it.copy(
                        version =
                            resolvedDependencyManagement[DependencyKey(it.groupId, it.artifactId)]
                                ?.takeIf { it.version != null }
                                ?.version
                                ?: it.version?.resolve(mergedPom.properties, accessor),
                    )
                }

        // Return the final mergedPom with all resolved properties, dependencies, and dependencyManagement.
        return mergedPom.copy(
            groupId = mergedPom.groupId?.resolve(mergedPom.properties, accessor),
            artifactId = mergedPom.artifactId?.resolve(mergedPom.properties, accessor),
            dependencies = resolvedDependencies,
            dependencyManagement = resolvedDependencyManagement.values.toList(),
            properties = mergedPom.properties.mapValues { it.value.resolve(mergedPom.properties, accessor) },
            name = mergedPom.name?.resolve(mergedPom.properties, accessor),
            description = mergedPom.description?.resolve(mergedPom.properties, accessor),
            scm =
                mergedPom.scm?.copy(
                    connection = mergedPom.scm?.connection?.resolve(mergedPom.properties, accessor),
                    developerConnection = mergedPom.scm?.developerConnection?.resolve(mergedPom.properties, accessor),
                    url = mergedPom.scm?.url?.resolve(mergedPom.properties, accessor),
                    tag = mergedPom.scm?.tag?.resolve(mergedPom.properties, accessor),
                ),
        )
    }