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

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

package name.remal.gradle_plugins.dsl.utils

import name.remal.default
import name.remal.gradle_plugins.api.todo.TODO
import name.remal.gradle_plugins.dsl.extensions.classifier
import name.remal.gradle_plugins.dsl.extensions.create
import name.remal.gradle_plugins.dsl.extensions.extension
import name.remal.nullIf
import name.remal.nullIfEmpty
import name.remal.version.Version
import org.gradle.api.artifacts.*
import org.gradle.api.artifacts.DependencyArtifact.DEFAULT_TYPE
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.dsl.DependencyHandler
import kotlin.LazyThreadSafetyMode.NONE

@TODO("Move extensions to separate files")
class DependencyNotation(
    val group: String,
    val module: String,
    version: String? = null,
    classifier: String? = null,
    extension: String? = null
) : Comparable {

    val version: String = version.default()
    val classifier: String = classifier.default()
    val extension: String = extension.default()

    val parsedVersion: Version? by lazy(NONE) { Version.parseOrNull(version) }

    private val string = buildString {
        append([email protected]).append(':').append([email protected])
        if ([email protected]() || [email protected]() || [email protected]()) append(':').append([email protected])
        if ([email protected]() || [email protected]()) append(':').append([email protected])
        if ([email protected]()) append('@').append([email protected])
    }

    override fun toString() = string
    override fun equals(other: Any?) = other is DependencyNotation && string == other.string
    override fun hashCode() = 1 + string.hashCode()

    fun compareVersions(other: DependencyNotation): Int {
        val parsedVersion = this.parsedVersion
        val otherParsedVersion = other.parsedVersion
        if (parsedVersion != null && otherParsedVersion != null) {
            return parsedVersion.compareTo(otherParsedVersion)
        } else {
            return version.compareTo(other.version)
        }
    }

    override fun compareTo(other: DependencyNotation): Int {
        group.compareTo(other.group).let { if (it != 0) return it }
        module.compareTo(other.module).let { if (it != 0) return it }
        compareVersions(other).let { if (it != 0) return it }
        classifier.compareTo(other.classifier).let { if (it != 0) return it }
        extension.compareTo(other.extension).let { if (it != 0) return it }
        return 0
    }


    fun withVersion(version: String?) = DependencyNotation(
        group = group,
        module = module,
        version = version,
        classifier = classifier,
        extension = extension
    )

    fun withLatestVersion() = withVersion("+")

    fun withoutVersion() = withVersion(null)

    fun withClassifier(classifier: String?) = DependencyNotation(
        group = group,
        module = module,
        version = version,
        classifier = classifier,
        extension = extension
    )

    fun withoutClassifier() = withClassifier(null)

    fun withExtension(extension: String?) = DependencyNotation(
        group = group,
        module = module,
        version = version,
        classifier = classifier,
        extension = extension
    )

    fun withoutExtension() = withExtension(null)

}

fun DependencyHandler.createWithNotation(notation: DependencyNotation, configurer: (dependency: ExternalModuleDependency) -> Unit = {}) = create(notation.toString(), configurer)


fun parseDependencyNotation(notation: String): DependencyNotation {
    val notationTokens = notation.split(':')
    if (notationTokens.size < 2) throw InvalidDependencyNotationString("Notation have only group: $notation")
    val group = notationTokens[0]
    val module = notationTokens[1]
    val version = notationTokens.getOrNull(2)

    val classifier: String?
    val extension: String?
    val tokens = notationTokens.getOrNull(3).nullIfEmpty()?.split('@')
    if (tokens != null) {
        classifier = tokens[0]
        extension = tokens.getOrNull(1)
    } else {
        classifier = null
        extension = null
    }

    return DependencyNotation(
        group = group,
        module = module,
        version = version,
        classifier = classifier,
        extension = extension
    )
}

class InvalidDependencyNotationString : RuntimeException {
    constructor() : super()
    constructor(message: String?) : super(message)
    constructor(message: String?, cause: Throwable?) : super(message, cause)
    constructor(cause: Throwable?) : super(cause)
}


val Dependency.notation
    get() = DependencyNotation(
        group = group.default(),
        module = name,
        version = version.default(),
        classifier = classifier,
        extension = extension.nullIf { this == DEFAULT_TYPE }
    )

val ResolvedDependency.notation
    get() = DependencyNotation(
        group = moduleGroup,
        module = moduleName,
        version = moduleVersion,
        classifier = classifier,
        extension = extension.nullIf { this == DEFAULT_TYPE }
    )

val UnresolvedDependency.notation get() = selector.notation

val ModuleComponentIdentifier.notation
    get() = DependencyNotation(
        group = group,
        module = module,
        version = version
    )

val ModuleVersionSelector.notation
    get() = DependencyNotation(
        group = group,
        module = name,
        version = version
    )




© 2015 - 2025 Weber Informatics LLC | Privacy Policy