Search code examples
versioningmacports

How does Macports determine which version is more recent?


I'm trying to figure out how Macports compares two versions to determine which one is the more recent one, but I have not been able to find any documentation on this. For example, the portfile reference does not have any details on this. I'm asking because I am trying to package an application that uses a patch version in addition to the normal versioning. This made me wonder if Macports supports a similar system to Gentoo ebuilds, where additional version information can be specified, such as 1.2_alpha1 < 1.2_alpha2 < 1.2_beta < 1.2_rc3 < 1.2 < 1.2_p1 (http://devmanual.gentoo.org/ebuild-writing/file-format/).

Is there a table somewhere describing which system Macports uses? Or does it only support the basic dot-separated versioning scheme (e.g. 1.2.1)?


Solution

  • MacPorts' version number comparison is based on RPM's original algorithm. It currently does not support a modifier that makes 1.2 > 1.2$something. While comparing the two version strings, non-alphanumeric characters are ignored apart from their separating function. This makes 1.2.3 == 1-2_3.

    To solve your problem, you can use the epoch field, which you'll have to increase every time the version number moves "backwards" according to MacPorts' version comparison algorithm.

    For future reference, the source code for the version comparison is at https://svn.macports.org/repository/macports/trunk/base/src/pextlib1.0/vercomp.c. If you need to test two version numbers without running this code in your head manually, you can use Ryan's vercmp script. Note that his script currently hasn't been updated to work with MacPorts' new bundled tclsh. A fixed version is below:

    #!/usr/bin/env port-tclsh
    
    # Runs vercmp with the two version numbers provided to see which is newer.
    
    package require macports 1.0
    mportinit
    
    if {${argc} != 2} {
        ui_error "usage: [file tail ${argv0}] version1 version2"
        exit 1
    }
    
    set version1 [lindex ${argv} 0]
    set version2 [lindex ${argv} 1]
    
    set cmp [vercmp ${version1} ${version2}]
    
    if {${cmp} < 0} {
        ui_msg "MacPorts considers ${version1} to be less than ${version2}."
    } elseif {${cmp} > 0} {
        ui_msg "MacPorts considers ${version1} to be greater than ${version2}."
    } else {
        ui_msg "MacPorts considers ${version1} to be equal to ${version2}."
    }