One important aspect of a package-management system is the ability to deal with the different versions of a package. Because of the current state of packaging, there is no real standard format for version numbers. Any potential package manager must be able to figure out the version of a given package without being told it explicitly by a user (otherwise maintaining the packages would be way too hard). Currently, package.el has a simple-ish way of dealing with version numbers: it uses the
lisp-mnt library (which comes with Emacs) to pull out the Version or Package-Version headers, strips RCS info (some version numbers are like $Id: linkd.el,v 1.63 2007/05/19 00:16:17 dto Exp dto $, and we really only want 1.63), and then split the result by periods and convert the pieces to integers. This means that it only works for versions like 1.2.3 and not 1.2.3alpha.It would be nice if we could get everyone to use only dotted-numeric version numbers, but that's not happening any time soon. Instead, a package manager must be able to make sense of more complex version numbers, such as
6.34a (which is what org-mode uses), 1.0pre7 or (cedet). I'm going to look at the following three version parsing solutions:version-to-list, included in Gnu Emacs.inversion, from CEDET, now included in Gnu Emacs (not sure which version).vcompWritten by Jonas Bernoulli, creator of the Emacs Mirror
I'll take a bunch of examples and show the output that each one produces. If you have any suggestions for additional version formats, please let me know :)
"1.0pre7"version-to-list(1 0 -1 7)inversion-decode-version(prerelease 1 0 7)vcomp--internnil
"1.0.7pre"version-to-list(1 0 7 -1)inversion-decode-versionnilvcomp--internnil
"6.34a"version-to-list(6 34 -3)inversion-decode-versionnilvcomp--intern((6 34) (104 0 96 0))
"1.3.7"version-to-list(1 3 7)inversion-decode-version(point 1 3 7)vcomp--intern((1 3 7) (104 0 96 0))
"1.0alpha"version-to-list(1 0 -3)inversion-decode-version(alpha 1 0 1)vcomp--internnil
"1.0PRE2"version-to-list(1 0 -1 2)inversion-decode-version(prerelease 1 0 2)vcomp--internnil
"0.9alpha"version-to-list(0 9 -3)inversion-decode-version(alpha 0 9 1)vcomp--internnil
"2009.04.01"version-to-list(2009 4 1)inversion-decode-version(point 2009 4 1)vcomp--intern((2009 4 1) (104 0 96 0))
"2009.10.5"version-to-list(2009 10 5)inversion-decode-version(point 2009 10 5)vcomp--intern((2009 10 5) (104 0 96 0))
"20091005"version-to-list(20091005)inversion-decode-versionnilvcomp--intern((20091005) (104 0 96 0))
"20091005pre"version-to-list(20091005 -1)inversion-decode-versionnilvcomp--internnil
"20091005alpha"version-to-list(20091005 -3)inversion-decode-versionnilvcomp--internnil
"20091005alpha2"version-to-list(20091005 -3 2)inversion-decode-versionnilvcomp--internnil
Looking at this, it seems like
version-to-list is the way to go, as it handles the different possibilities better than any of the other functions.
7 comments: