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

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

package name.remal.gradle_plugins.dsl.utils

import name.remal.escapeRegex
import name.remal.nullIfEmpty
import name.remal.version.VersionRange

class DependencyNotationMatcher(val pattern: String) : Comparable {

    private val groupRegex: Regex
    private val moduleRegex: Regex
    private val version: String?
    private val versionRange: VersionRange?
    private val classifier: String?
    private val extension: String?

    init {
        val patternNotation = try {
            parseDependencyNotation(pattern)
        } catch (e: InvalidDependencyNotationString) {
            throw InvalidDependencyNotationPattern(pattern, e)
        }

        groupRegex = patternNotation.group.nullIfEmpty()?.createRegex() ?: throw InvalidDependencyNotationPattern("Empty group: $pattern")
        moduleRegex = patternNotation.module.nullIfEmpty()?.createRegex() ?: throw InvalidDependencyNotationPattern("Empty module: $pattern")

        if (patternNotation.version.isNotEmpty()) {
            if (patternNotation.version.contains('*')) {
                throw InvalidDependencyNotationPattern("Don't use '*' for version range, use '+' instead: $pattern")
            }
            if (patternNotation.version.contains('+')
                || patternNotation.version.contains('[')
                || patternNotation.version.contains(']')
                || patternNotation.version.contains('(')
                || patternNotation.version.contains(')')
            ) {
                version = null
                versionRange = try {
                    VersionRange.parse(patternNotation.version)
                } catch (e: Exception) {
                    throw InvalidDependencyNotationPattern("Invalid version: $pattern", e)
                }
            } else {
                version = patternNotation.version
                versionRange = null
            }
        } else {
            version = null
            versionRange = null
        }

        classifier = patternNotation.classifier.nullIfEmpty()
        extension = patternNotation.extension.nullIfEmpty()
    }

    private fun String.createRegex() = Regex(escapeRegex(this).replace("\\*", ".*"))

    fun matches(notation: DependencyNotation): Boolean {
        if (!groupRegex.matches(notation.group)) return false
        if (!moduleRegex.matches(notation.module)) return false
        if (version != null && version != notation.version) return false
        if (versionRange != null) {
            val parsedVersion = notation.parsedVersion
            if (parsedVersion == null || !versionRange.contains(parsedVersion)) return false
        }
        if (classifier != null && classifier != notation.classifier) return false
        if (extension != null && extension != notation.extension) return false
        return true
    }

    fun matches(notation: String) = matches(parseDependencyNotation(notation))

    fun notMatches(notation: DependencyNotation) = !matches(notation)
    fun notMatches(notation: String) = !matches(parseDependencyNotation(notation))


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

    override fun compareTo(other: DependencyNotationMatcher) = pattern.compareTo(other.pattern)

}

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


fun DependencyNotation.matches(pattern: String) = DependencyNotationMatcher(pattern).matches(this)
fun isDependencyNotationMatches(notation: String, pattern: String) = DependencyNotationMatcher(pattern).matches(notation)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy