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, 2011, Richard Lowe
  21 #
  22 
  23 '''
  24 Deal with Mercurial versioning.
  25 
  26 At a basic level, code to verify that the version of Mercurial in use
  27 is suitable for use with Cadmium, and compare that version for the
  28 sake 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 #
  46 from mercurial import util
  47 if hasattr(util, 'version'):
  48     hg_version = util.version
  49 else:
  50     from mercurial import version
  51     hg_version = version.get_version
  52 
  53 
  54 class 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 #
  61 GOOD_VERSIONS = ['1.3.1', '1.4.2', '1.5.4', '1.6.2', '1.6.3', '1.7.5',
  62                  '1.8', '1.8.1']
  63 
  64 
  65 def check_version():
  66     '''Check that we're running on a suitable version of Mercurial'''
  67 
  68     def versionstring(versions):
  69         '''return the list, versions, as a vaguely grammatical string'''
  70         if len(versions) > 1:
  71             return "%s or %s" % (', '.join(versions[0:-1]), versions[-1])
  72         else:
  73             return versions[0]
  74 
  75     if hg_version() not in GOOD_VERSIONS:
  76         raise VersionMismatch("Scm expects Mercurial version %s, "
  77                               "actual version is %s." %
  78                               (versionstring(GOOD_VERSIONS),
  79                                hg_version()))
  80 
  81 
  82 def _split_version(ver):
  83     '''Return the Mercurial version as a list [MAJOR, MINOR, MICRO],
  84     if this is not a released Mercurial return None.'''
  85 
  86     try:
  87         l = map(int, ver.split('.'))
  88         # If there's only one element, it's not really a tagged version
  89         if len(l) <= 1:
  90             return None
  91         else:
  92             return l
  93     except ValueError:
  94         return None
  95 
  96 
  97 def at_least(desired):
  98     '''Return boolean indicating if the running version is greater
  99     than or equal to, the version specified by major, minor, micro'''
 100 
 101     hgver = _split_version(hg_version())
 102     desired = map(int, desired.split('.'))
 103 
 104     #
 105     # If _split_version() returns None, we're running on a Mercurial that
 106     # has not been tagged as a release.  We assume this to be newer
 107     # than any released version.
 108     #
 109     if hgver == None:
 110         return True
 111 
 112     # Pad our versions to the same overall length, appending 0's
 113     while len(hgver) < len(desired):
 114         hgver.append(0)
 115     while len(desired) < len(hgver):
 116         desired.append(0)
 117 
 118     for real, req in zip(hgver, desired):
 119         if real != req:
 120             return real > req
 121 
 122     return True