bug 1257607 - Add Version type to moz.configure. r=glandium

This change adds a `Version` type to moz.configure which is a small
wrapper around `distutils.version.Version`. It's suitable for wrapping
version numbers in configure checks and doing equality or greater-than
less-than comparisons in a sensible way.

MozReview-Commit-ID: BOL6yvemulG

--HG--
extra : rebase_source : 3b463eac0499086f8acffda0d01418b6ab17f3d6
extra : amend_source : aebd6e40c408d9f868623b2f53fcdf7455e2fff5
This commit is contained in:
Ted Mielczarek 2016-03-17 11:52:18 -04:00
parent 8f2baa8e8b
commit 5986418419
5 changed files with 93 additions and 1 deletions

View File

@ -89,6 +89,12 @@ def unique_list(l):
result.append(i)
return result
@template
@advanced
def Version(v):
'A version number that can be compared usefully.'
from mozbuild.configure.util import Version as _Version
return _Version(v)
# Denotes a deprecated option. Combines option() and @depends:
# @deprecated_option('--option')

View File

@ -84,7 +84,7 @@ def perl_version_check(min_version):
def get_perl_version(perl):
import subprocess
try:
return subprocess.check_output([perl, '-e', 'print $]'])
return Version(subprocess.check_output([perl, '-e', 'print $]']))
except subprocess.CalledProcessError as e:
error('Failed to get perl version: %s' % e.message)

View File

@ -36,6 +36,7 @@ PYTHON_UNIT_TESTS += [
'mozbuild/mozbuild/test/compilation/test_warnings.py',
'mozbuild/mozbuild/test/configure/test_configure.py',
'mozbuild/mozbuild/test/configure/test_options.py',
'mozbuild/mozbuild/test/configure/test_util.py',
'mozbuild/mozbuild/test/controller/test_ccachestats.py',
'mozbuild/mozbuild/test/controller/test_clobber.py',
'mozbuild/mozbuild/test/frontend/test_context.py',

View File

@ -0,0 +1,36 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, print_function, unicode_literals
import itertools
from distutils.version import LooseVersion
class Version(LooseVersion):
'''A simple subclass of distutils.version.LooseVersion.
Adds attributes for `major`, `minor`, `patch` for the first three
version components so users can easily pull out major/minor
versions, like:
v = Version('1.2b')
v.major == 1
v.minor == 2
v.patch == 0
'''
def __init__(self, version):
# Can't use super, LooseVersion's base class is not a new-style class.
LooseVersion.__init__(self, version)
# Take the first three integer components, stopping at the first
# non-integer and padding the rest with zeroes.
(self.major, self.minor, self.patch) = list(itertools.chain(
itertools.takewhile(lambda x:isinstance(x, int), self.version),
(0, 0, 0)))[:3]
def __cmp__(self, other):
# LooseVersion checks isinstance(StringType), so work around it.
if isinstance(other, unicode):
other = other.encode('ascii')
return LooseVersion.__cmp__(self, other)

View File

@ -0,0 +1,49 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, print_function, unicode_literals
import unittest
from mozunit import main
from mozbuild.configure.util import Version
class TestVersion(unittest.TestCase):
def test_version_simple(self):
v = Version('1')
self.assertEqual(v, '1')
self.assertLess(v, '2')
self.assertGreater(v, '0.5')
self.assertEqual(v.major, 1)
self.assertEqual(v.minor, 0)
self.assertEqual(v.patch, 0)
def test_version_more(self):
v = Version('1.2.3b')
self.assertLess(v, '2')
self.assertEqual(v.major, 1)
self.assertEqual(v.minor, 2)
self.assertEqual(v.patch, 3)
def test_version_bad(self):
# A version with a letter in the middle doesn't really make sense,
# so everything after it should be ignored.
v = Version('1.2b.3')
self.assertLess(v, '2')
self.assertEqual(v.major, 1)
self.assertEqual(v.minor, 2)
self.assertEqual(v.patch, 0)
def test_version_badder(self):
v = Version('1b.2.3')
self.assertLess(v, '2')
self.assertEqual(v.major, 1)
self.assertEqual(v.minor, 0)
self.assertEqual(v.patch, 0)
if __name__ == '__main__':
main()