forked from mirrors/gecko-dev
--HG-- rename : third_party/python/hglib/LICENSE => third_party/python/python-hglib/LICENSE rename : third_party/python/hglib/hglib/__init__.py => third_party/python/python-hglib/hglib/__init__.py rename : third_party/python/hglib/hglib/client.py => third_party/python/python-hglib/hglib/client.py rename : third_party/python/hglib/hglib/context.py => third_party/python/python-hglib/hglib/context.py rename : third_party/python/hglib/hglib/error.py => third_party/python/python-hglib/hglib/error.py rename : third_party/python/hglib/hglib/merge.py => third_party/python/python-hglib/hglib/merge.py rename : third_party/python/hglib/hglib/templates.py => third_party/python/python-hglib/hglib/templates.py rename : third_party/python/hglib/hglib/util.py => third_party/python/python-hglib/hglib/util.py rename : third_party/python/hglib/setup.py => third_party/python/python-hglib/setup.py extra : rebase_source : 552d93c9e90c04171c8b627c8f4f4fa5ec506cc3
217 lines
5.4 KiB
Python
217 lines
5.4 KiB
Python
import os, subprocess, sys
|
|
from hglib import error
|
|
try:
|
|
from io import BytesIO
|
|
except ImportError:
|
|
from cStringIO import StringIO as BytesIO
|
|
|
|
if sys.version_info[0] > 2:
|
|
izip = zip
|
|
integertypes = (int,)
|
|
|
|
def b(s):
|
|
"""Encode the string as bytes."""
|
|
return s.encode('latin-1')
|
|
else:
|
|
from itertools import izip
|
|
integertypes = (long, int)
|
|
bytes = str # Defined in Python 2.6/2.7, but to the same value.
|
|
|
|
def b(s):
|
|
"""Encode the string as bytes."""
|
|
return s
|
|
|
|
def strtobytes(s):
|
|
"""Return the bytes of the string representation of an object."""
|
|
return str(s).encode('latin-1')
|
|
|
|
def grouper(n, iterable):
|
|
''' list(grouper(2, range(4))) -> [(0, 1), (2, 3)] '''
|
|
args = [iter(iterable)] * n
|
|
return izip(*args)
|
|
|
|
def eatlines(s, n):
|
|
"""
|
|
>>> eatlines(b("1\\n2"), 1) == b('2')
|
|
True
|
|
>>> eatlines(b("1\\n2"), 2) == b('')
|
|
True
|
|
>>> eatlines(b("1\\n2"), 3) == b('')
|
|
True
|
|
>>> eatlines(b("1\\n2\\n3"), 1) == b('2\\n3')
|
|
True
|
|
"""
|
|
cs = BytesIO(s)
|
|
|
|
for line in cs:
|
|
n -= 1
|
|
if n == 0:
|
|
return cs.read()
|
|
return b('')
|
|
|
|
def skiplines(s, prefix):
|
|
"""
|
|
Skip lines starting with prefix in s
|
|
|
|
>>> skiplines(b('a\\nb\\na\\n'), b('a')) == b('b\\na\\n')
|
|
True
|
|
>>> skiplines(b('a\\na\\n'), b('a')) == b('')
|
|
True
|
|
>>> skiplines(b(''), b('a')) == b('')
|
|
True
|
|
>>> skiplines(b('a\\nb'), b('b')) == b('a\\nb')
|
|
True
|
|
"""
|
|
cs = BytesIO(s)
|
|
|
|
for line in cs:
|
|
if not line.startswith(prefix):
|
|
return line + cs.read()
|
|
|
|
return b('')
|
|
|
|
def _cmdval(val):
|
|
if isinstance(val, bytes):
|
|
return val
|
|
else:
|
|
return strtobytes(val)
|
|
|
|
def cmdbuilder(name, *args, **kwargs):
|
|
"""
|
|
A helper for building the command arguments
|
|
|
|
args are the positional arguments
|
|
|
|
kwargs are the options
|
|
keys that are single lettered are prepended with '-', others with '--',
|
|
underscores are replaced with dashes
|
|
|
|
keys with False boolean values are ignored, lists add the key multiple times
|
|
|
|
None arguments are skipped
|
|
|
|
>>> cmdbuilder(b('cmd'), a=True, b=False, c=None) == [b('cmd'), b('-a')]
|
|
True
|
|
>>> cmdbuilder(b('cmd'), long=True) == [b('cmd'), b('--long')]
|
|
True
|
|
>>> cmdbuilder(b('cmd'), str=b('s')) == [b('cmd'), b('--str'), b('s')]
|
|
True
|
|
>>> cmdbuilder(b('cmd'), d_ash=True) == [b('cmd'), b('--d-ash')]
|
|
True
|
|
>>> cmdbuilder(b('cmd'), _=True) == [b('cmd'), b('-')]
|
|
True
|
|
>>> expect = [b('cmd'), b('--list'), b('1'), b('--list'), b('2')]
|
|
>>> cmdbuilder(b('cmd'), list=[1, 2]) == expect
|
|
True
|
|
>>> cmdbuilder(b('cmd'), None) == [b('cmd')]
|
|
True
|
|
"""
|
|
cmd = [name]
|
|
for arg, val in kwargs.items():
|
|
if val is None:
|
|
continue
|
|
|
|
arg = arg.encode('latin-1').replace(b('_'), b('-'))
|
|
if arg != b('-'):
|
|
if len(arg) == 1:
|
|
arg = b('-') + arg
|
|
else:
|
|
arg = b('--') + arg
|
|
if isinstance(val, bool):
|
|
if val:
|
|
cmd.append(arg)
|
|
elif isinstance(val, list):
|
|
for v in val:
|
|
cmd.append(arg)
|
|
cmd.append(_cmdval(v))
|
|
else:
|
|
cmd.append(arg)
|
|
cmd.append(_cmdval(val))
|
|
|
|
for a in args:
|
|
if a is not None:
|
|
cmd.append(a)
|
|
|
|
return cmd
|
|
|
|
class reterrorhandler(object):
|
|
"""This class is meant to be used with rawcommand() error handler
|
|
argument. It remembers the return value the command returned if
|
|
it's one of allowed values, which is only 1 if none are given.
|
|
Otherwise it raises a CommandError.
|
|
|
|
>>> e = reterrorhandler('')
|
|
>>> bool(e)
|
|
True
|
|
>>> e(1, 'a', '')
|
|
'a'
|
|
>>> bool(e)
|
|
False
|
|
|
|
"""
|
|
def __init__(self, args, allowed=None):
|
|
self.args = args
|
|
self.ret = 0
|
|
if allowed is None:
|
|
self.allowed = [1]
|
|
else:
|
|
self.allowed = allowed
|
|
|
|
def __call__(self, ret, out, err):
|
|
self.ret = ret
|
|
if ret not in self.allowed:
|
|
raise error.CommandError(self.args, ret, out, err)
|
|
return out
|
|
|
|
def __nonzero__(self):
|
|
""" Returns True if the return code was 0, False otherwise """
|
|
return self.ret == 0
|
|
|
|
def __bool__(self):
|
|
return self.__nonzero__()
|
|
|
|
class propertycache(object):
|
|
"""
|
|
Decorator that remembers the return value of a function call.
|
|
|
|
>>> execcount = 0
|
|
>>> class obj(object):
|
|
... def func(self):
|
|
... global execcount
|
|
... execcount += 1
|
|
... return []
|
|
... func = propertycache(func)
|
|
>>> o = obj()
|
|
>>> o.func
|
|
[]
|
|
>>> execcount
|
|
1
|
|
>>> o.func
|
|
[]
|
|
>>> execcount
|
|
1
|
|
"""
|
|
def __init__(self, func):
|
|
self.func = func
|
|
self.name = func.__name__
|
|
def __get__(self, obj, type=None):
|
|
result = self.func(obj)
|
|
setattr(obj, self.name, result)
|
|
return result
|
|
|
|
close_fds = os.name == 'posix'
|
|
|
|
startupinfo = None
|
|
if os.name == 'nt':
|
|
startupinfo = subprocess.STARTUPINFO()
|
|
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
|
|
|
def popen(args, env=None):
|
|
environ = None
|
|
if env:
|
|
environ = dict(os.environ)
|
|
environ.update(env)
|
|
|
|
return subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE, close_fds=close_fds,
|
|
startupinfo=startupinfo, env=environ)
|