comparison mercurial/util.py @ 30736:d9e5b0aeeb90

util: extract the logic calculating environment variables The method will be reused in chgserver. Move it out so it can be reused.
author Jun Wu <quark@fb.com>
date Tue, 10 Jan 2017 06:58:02 +0800
parents 10b17ed9b591
children c1b7b2285522
comparison
equal deleted inserted replaced
30735:9823e2f50a93 30736:d9e5b0aeeb90
972 972
973 def _isstdout(f): 973 def _isstdout(f):
974 fileno = getattr(f, 'fileno', None) 974 fileno = getattr(f, 'fileno', None)
975 return fileno and fileno() == sys.__stdout__.fileno() 975 return fileno and fileno() == sys.__stdout__.fileno()
976 976
977 def system(cmd, environ=None, cwd=None, onerr=None, errprefix=None, out=None): 977 def shellenviron(environ=None):
978 '''enhanced shell command execution. 978 """return environ with optional override, useful for shelling out"""
979 run with environment maybe modified, maybe in different dir.
980
981 if command fails and onerr is None, return status, else raise onerr
982 object as exception.
983
984 if out is specified, it is assumed to be a file-like object that has a
985 write() method. stdout and stderr will be redirected to out.'''
986 if environ is None:
987 environ = {}
988 try:
989 stdout.flush()
990 except Exception:
991 pass
992 def py2shell(val): 979 def py2shell(val):
993 'convert python object into string that is useful to shell' 980 'convert python object into string that is useful to shell'
994 if val is None or val is False: 981 if val is None or val is False:
995 return '0' 982 return '0'
996 if val is True: 983 if val is True:
997 return '1' 984 return '1'
998 return str(val) 985 return str(val)
986 env = dict(encoding.environ)
987 if environ:
988 env.update((k, py2shell(v)) for k, v in environ.iteritems())
989 env['HG'] = hgexecutable()
990 return env
991
992 def system(cmd, environ=None, cwd=None, onerr=None, errprefix=None, out=None):
993 '''enhanced shell command execution.
994 run with environment maybe modified, maybe in different dir.
995
996 if command fails and onerr is None, return status, else raise onerr
997 object as exception.
998
999 if out is specified, it is assumed to be a file-like object that has a
1000 write() method. stdout and stderr will be redirected to out.'''
1001 try:
1002 stdout.flush()
1003 except Exception:
1004 pass
999 origcmd = cmd 1005 origcmd = cmd
1000 cmd = quotecommand(cmd) 1006 cmd = quotecommand(cmd)
1001 if pycompat.sysplatform == 'plan9' and (sys.version_info[0] == 2 1007 if pycompat.sysplatform == 'plan9' and (sys.version_info[0] == 2
1002 and sys.version_info[1] < 7): 1008 and sys.version_info[1] < 7):
1003 # subprocess kludge to work around issues in half-baked Python 1009 # subprocess kludge to work around issues in half-baked Python
1004 # ports, notably bichued/python: 1010 # ports, notably bichued/python:
1005 if not cwd is None: 1011 if not cwd is None:
1006 os.chdir(cwd) 1012 os.chdir(cwd)
1007 rc = os.system(cmd) 1013 rc = os.system(cmd)
1008 else: 1014 else:
1009 env = dict(encoding.environ) 1015 env = shellenviron(environ)
1010 env.update((k, py2shell(v)) for k, v in environ.iteritems())
1011 env['HG'] = hgexecutable()
1012 if out is None or _isstdout(out): 1016 if out is None or _isstdout(out):
1013 rc = subprocess.call(cmd, shell=True, close_fds=closefds, 1017 rc = subprocess.call(cmd, shell=True, close_fds=closefds,
1014 env=env, cwd=cwd) 1018 env=env, cwd=cwd)
1015 else: 1019 else:
1016 proc = subprocess.Popen(cmd, shell=True, close_fds=closefds, 1020 proc = subprocess.Popen(cmd, shell=True, close_fds=closefds,