xref: /titanic_41/usr/src/tools/onbld/Scm/Version.py (revision db0d7085f45406af6c45f0b36804a0a97f078084)
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'''
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', '1.7.5',
62                 '1.8', '1.8.1']
63
64
65def 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
82def _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
97def 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
123