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

grails.plugins.VersionComparator.groovy Maven / Gradle / Ivy

/*
 * Copyright 2004-2023 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package grails.plugins

import groovy.transform.CompileStatic

/**
 * A comparator capable of sorting versions from from newest to oldest
 * @author Graeme Rocher
 */
@CompileStatic
class VersionComparator implements Comparator {

    static private final List SNAPSHOT_SUFFIXES = ['-SNAPSHOT', '.BUILD-SNAPSHOT'].asImmutable()

    int compare(String o1, String o2) {
        int result = 0
        if (o1 == '*') {
            result = 1
        }
        else if (o2 == '*') {
            result = -1
        }
        else {
            List nums1
            try {
                String[] tokens = deSnapshot(o1).split(/\./)
                Collection tokenList = tokens.findAll { String it -> it.trim() ==~ /\d+/ }
                nums1 = tokenList*.toInteger()
            }
            catch (NumberFormatException e) {
                throw new InvalidVersionException("Cannot compare versions, left side [$o1] is invalid: ${e.message}")
            }
            List nums2
            try {
                String[] tokens = deSnapshot(o2).split(/\./)
                Collection tokenList = tokens.findAll { String it -> it.trim() ==~ /\d+/ }
                nums2 = tokenList*.toInteger()
            }
            catch (NumberFormatException e) {
                throw new InvalidVersionException("Cannot compare versions, right side [$o2] is invalid: ${e.message}")
            }
            boolean bigRight = nums2.size() > nums1.size()
            boolean bigLeft = nums1.size() > nums2.size()
            for (int i in 0.. i) {
                    result = nums1[i].compareTo(nums2[i])
                    if (result != 0) {
                        break
                    }
                    if (i == (nums1.size() - 1) && bigRight) {
                        if (nums2[i + 1] != 0) {
                            result = -1
                            break
                        }
                    }
                }
                else if (bigLeft) {
                    if (nums1[i] != 0) {
                        result = 1
                        break
                    }
                }
            }
        }

        if (result == 0) {
            // Versions are equal, but one may be a snapshot.
            // A snapshot version is considered less than a non snapshot version
            boolean o1IsSnapshot = isSnapshot(o1)
            boolean o2IsSnapshot = isSnapshot(o2)

            if (o1IsSnapshot && !o2IsSnapshot) {
                result = -1
            }
            else if (!o1IsSnapshot && o2IsSnapshot) {
                result = 1
            }
        }

        result
    }

    boolean equals(obj) { false }

    /**
     * Removes any suffixes that indicate that the version is a kind of snapshot
     */
    @CompileStatic
    protected String deSnapshot(String version) {
        String suffix = SNAPSHOT_SUFFIXES.find { String it -> version?.endsWith(it) }
        if (suffix) {
            return version[0..-(suffix.size() + 1)]
        }
        version
    }

    @CompileStatic
    protected boolean isSnapshot(String version) {
        SNAPSHOT_SUFFIXES.any { String it -> version?.endsWith(it) }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy