1# 2# This program is free software; you can redistribute it and/or modify 3# it under the terms of the GNU General Public License version 2 4# as published by the Free Software Foundation. 5# 6# This program is distributed in the hope that it will be useful, 7# but WITHOUT ANY WARRANTY; without even the implied warranty of 8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9# GNU General Public License for more details. 10# 11# You should have received a copy of the GNU General Public License 12# along with this program; if not, write to the Free Software 13# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 14# 15 16# 17# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 18# Use is subject to license terms. 19# 20# Copyright 2008, 2010, Richard Lowe 21# 22 23''' 24Deal with Mercurial versioning. 25 26At a basic level, code to verify that the version of Mercurial in use 27is suitable for use with Cadmium, and compare that version for the 28sake of adapting to Mercurial API changes. 29''' 30 31# 32# It is important that this module rely on as little of Mercurial as 33# is possible. 34# 35 36# 37# Mercurial >= 1.2 has util.version(), prior versions 38# version.get_version() We discover which to use this way, rather than 39# via ImportError to account for mercurial.demandimport delaying the 40# ImportError exception. 41# 42# This code needs to remain, even though versions prior to 1.2 aren't 43# supported, to allow us to produce the error message which states that they 44# are not supported. 45# 46from mercurial import util 47if hasattr(util, 'version'): 48 hg_version = util.version 49else: 50 from mercurial import version 51 hg_version = version.get_version 52 53 54class VersionMismatch(Exception): 55 "Exception used to indicate a mismatch between SCM tools and Mercurial" 56 pass 57 58# 59# List of versions that are explicitly acceptable to us 60# 61GOOD_VERSIONS = ['1.3.1', '1.4.2', '1.5.4', '1.6.2', '1.6.3'] 62 63 64def check_version(): 65 '''Check that we're running on a suitable version of Mercurial''' 66 67 def versionstring(versions): 68 '''return the list, versions, as a vaguely grammatical string''' 69 if len(versions) > 1: 70 return "%s or %s" % (', '.join(versions[0:-1]), versions[-1]) 71 else: 72 return versions[0] 73 74 if hg_version() not in GOOD_VERSIONS: 75 raise VersionMismatch("Scm expects Mercurial version %s, " 76 "actual version is %s." % 77 (versionstring(GOOD_VERSIONS), 78 hg_version())) 79 80 81def _split_version(ver): 82 '''Return the Mercurial version as a list [MAJOR, MINOR, MICRO], 83 if this is not a released Mercurial return None.''' 84 85 try: 86 l = map(int, ver.split('.')) 87 # If there's only one element, it's not really a tagged version 88 if len(l) <= 1: 89 return None 90 else: 91 return l 92 except ValueError: 93 return None 94 95 96def at_least(desired): 97 '''Return boolean indicating if the running version is greater 98 than or equal to, the version specified by major, minor, micro''' 99 100 hgver = _split_version(hg_version()) 101 desired = map(int, desired.split('.')) 102 103 # 104 # If _split_version() returns None, we're running on a Mercurial that 105 # has not been tagged as a release. We assume this to be newer 106 # than any released version. 107 # 108 if hgver == None: 109 return True 110 111 # Pad our versions to the same overall length, appending 0's 112 while len(hgver) < len(desired): 113 hgver.append(0) 114 while len(desired) < len(hgver): 115 desired.append(0) 116 117 for real, req in zip(hgver, desired): 118 if real != req: 119 return real > req 120 121 return True 122