mirror of
https://github.com/facebook/sapling.git
synced 2024-10-12 09:48:05 +03:00
9dc21f8d0b
Summary: D13853115 adds `edenscm/` to `sys.path` and code still uses `import mercurial`. That has nasty problems if both `import mercurial` and `import edenscm.mercurial` are used, because Python would think `mercurial.foo` and `edenscm.mercurial.foo` are different modules so code like `try: ... except mercurial.error.Foo: ...`, or `isinstance(x, mercurial.foo.Bar)` would fail to handle the `edenscm.mercurial` version. There are also some module-level states (ex. `extensions._extensions`) that would cause trouble if they have multiple versions in a single process. Change imports to use the `edenscm` so ideally the `mercurial` is no longer imported at all. Add checks in extensions.py to catch unexpected extensions importing modules from the old (wrong) locations when running tests. Reviewed By: phillco Differential Revision: D13868981 fbshipit-source-id: f4e2513766957fd81d85407994f7521a08e4de48
142 lines
4.1 KiB
Python
Executable File
142 lines
4.1 KiB
Python
Executable File
#!/usr/bin/env python2
|
|
from __future__ import absolute_import, print_function
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
from edenscm.mercurial import util
|
|
|
|
|
|
# Always load hg libraries from the hg we can find on $PATH.
|
|
hglib = json.loads(subprocess.check_output(["hg", "debuginstall", "-Tjson"]))[0][
|
|
"hgmodules"
|
|
]
|
|
sys.path.insert(0, os.path.dirname(hglib))
|
|
|
|
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument(
|
|
"--paranoid",
|
|
action="store_true",
|
|
help=(
|
|
"Be paranoid about how version numbers compare and "
|
|
"produce something that's more likely to sort "
|
|
"reasonably."
|
|
),
|
|
)
|
|
ap.add_argument("--selftest", action="store_true", help="Run self-tests.")
|
|
ap.add_argument("versionfile", help="Path to a valid mercurial __version__.py")
|
|
|
|
|
|
def paranoidver(ver):
|
|
"""Given an hg version produce something that distutils can sort.
|
|
|
|
Some Mac package management systems use distutils code in order to
|
|
figure out upgrades, which makes life difficult. The test case is
|
|
a reduced version of code in the Munki tool used by some large
|
|
organizations to centrally manage OS X packages, which is what
|
|
inspired this kludge.
|
|
|
|
>>> paranoidver('3.4')
|
|
'3.4.0'
|
|
>>> paranoidver('3.4.2')
|
|
'3.4.2'
|
|
>>> paranoidver('3.0-rc+10')
|
|
'2.9.9999-rc+10'
|
|
>>> paranoidver('4.2+483-5d44d7d4076e')
|
|
'4.2.0+483-5d44d7d4076e'
|
|
>>> paranoidver('4.2.1+598-48d1e1214d8c')
|
|
'4.2.1+598-48d1e1214d8c'
|
|
>>> paranoidver('4.3-rc')
|
|
'4.2.9999-rc'
|
|
>>> paranoidver('4.3')
|
|
'4.3.0'
|
|
>>> from distutils import version
|
|
>>> class LossyPaddedVersion(version.LooseVersion):
|
|
... '''Subclass version.LooseVersion to compare things like
|
|
... "10.6" and "10.6.0" as equal'''
|
|
... def __init__(self, s):
|
|
... self.parse(s)
|
|
...
|
|
... def _pad(self, version_list, max_length):
|
|
... 'Pad a version list by adding extra 0 components to the end'
|
|
... # copy the version_list so we don't modify it
|
|
... cmp_list = list(version_list)
|
|
... while len(cmp_list) < max_length:
|
|
... cmp_list.append(0)
|
|
... return cmp_list
|
|
...
|
|
... def __cmp__(self, other):
|
|
... if isinstance(other, str):
|
|
... other = MunkiLooseVersion(other)
|
|
... max_length = max(len(self.version), len(other.version))
|
|
... self_cmp_version = self._pad(self.version, max_length)
|
|
... other_cmp_version = self._pad(other.version, max_length)
|
|
... return cmp(self_cmp_version, other_cmp_version)
|
|
>>> def testver(older, newer):
|
|
... o = LossyPaddedVersion(paranoidver(older))
|
|
... n = LossyPaddedVersion(paranoidver(newer))
|
|
... return o < n
|
|
>>> testver('3.4', '3.5')
|
|
True
|
|
>>> testver('3.4.0', '3.5-rc')
|
|
True
|
|
>>> testver('3.4-rc', '3.5')
|
|
True
|
|
>>> testver('3.4-rc+10-deadbeef', '3.5')
|
|
True
|
|
>>> testver('3.4.2', '3.5-rc')
|
|
True
|
|
>>> testver('3.4.2', '3.5-rc+10-deadbeef')
|
|
True
|
|
>>> testver('4.2+483-5d44d7d4076e', '4.2.1+598-48d1e1214d8c')
|
|
True
|
|
>>> testver('4.3-rc', '4.3')
|
|
True
|
|
>>> testver('4.3', '4.3-rc')
|
|
False
|
|
"""
|
|
major, minor, micro, extra = util.versiontuple(ver, n=4)
|
|
if micro is None:
|
|
micro = 0
|
|
if extra:
|
|
if extra.startswith("rc"):
|
|
if minor == 0:
|
|
major -= 1
|
|
minor = 9
|
|
else:
|
|
minor -= 1
|
|
micro = 9999
|
|
extra = "-" + extra
|
|
else:
|
|
extra = "+" + extra
|
|
else:
|
|
extra = ""
|
|
return "%d.%d.%d%s" % (major, minor, micro, extra)
|
|
|
|
|
|
def main(argv):
|
|
opts = ap.parse_args(argv[1:])
|
|
if opts.selftest:
|
|
import doctest
|
|
|
|
doctest.testmod()
|
|
return
|
|
with open(opts.versionfile) as f:
|
|
for l in f:
|
|
if l.startswith("version = "):
|
|
# version number is entire line minus the quotes
|
|
ver = l[len("version = ") + 1 : -2]
|
|
break
|
|
if opts.paranoid:
|
|
print(paranoidver(ver))
|
|
else:
|
|
print(ver)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv)
|