|
# (C) Tai Kedzierski |
|
# Provided under LGPLv3 |
|
# https://www.gnu.org/licenses/lgpl-3.0.txt |
|
|
|
import subprocess |
|
import re |
|
import os |
|
|
|
show_commands = False |
|
|
|
def run(command_array, cwd='./', dry_run=False, addenv={}, stdout=None, stderr=None, string=False): |
|
""" |
|
Convenience function for controlling command runs |
|
|
|
Returns the process handler object (from subprocess.Popen) or None if dry_run is True |
|
|
|
Arguments ------ |
|
|
|
command_array : a string array representing the external command to run |
|
|
|
cwd: the working directory to run in |
|
|
|
dry_run: if True, does not run. Use --show-commands to print out what would have been run |
|
|
|
addenv: a str->str dictionary of environment variables and values to add to the runtime environment |
|
|
|
stdout: |
|
stderr: |
|
use subprocess.PIPE to capture output |
|
|
|
string: if True, treat the output as text-only. Use this if you intend to use .communicate() on the process handler |
|
""" |
|
cwd = os.path.abspath(cwd) |
|
|
|
if show_commands: |
|
print("Add env: "+"".join( |
|
[ "\n %s=%s"%(x,addenv[x]) for x in addenv] |
|
) ) |
|
print("CWD: "+cwd) |
|
print("Command: "+quote(command_array) ) |
|
print("---->") |
|
|
|
myenv = gatherEnv(addenv) |
|
|
|
if dry_run != True: |
|
return subprocess.Popen(command_array, cwd=cwd, env=myenv, stdout=stdout, stderr=stderr, universal_newlines=string) |
|
|
|
def irun(command_array, cwd='./', dry_run=False, addenv={}, input=None, timeout=None, string=True): |
|
""" |
|
Interactive runner convenience function |
|
|
|
Returns stdout and stderr as text pipes, unless string is False ; returns None if dry_run is True |
|
|
|
Arguments ------ |
|
|
|
command_array : a string array representing the external command to run |
|
|
|
cwd: the working directory to run in |
|
|
|
dry_run: if True, does not run. Use --show-commands to print out what would have been run |
|
|
|
addenv: a str->str dictionary of environment variables and values to add to the runtime environment |
|
|
|
input: input string data to write to the process |
|
|
|
timeout: see `help(subprocess.Popen.communicate)` in a python interactive session. Presumably, time to wait for process termination until giving up |
|
|
|
string: if True, treat the output as text-only. Use this if you intend to use .communicate() on the process handler |
|
""" |
|
_pipe = subprocess.PIPE |
|
ph = run(command_array, cwd=cwd, dry_run=dry_run, addenv=addenv, stdout=_pipe, stderr=_pipe, string=string) |
|
return ph.communicate(input=input, timeout=timeout) |
|
|
|
|
|
def quote(command_array): |
|
new_array = [] |
|
|
|
for token in command_array: |
|
if re.match('.*\s+', token): |
|
new_array.append( '"%s"'%token ) |
|
else: |
|
new_array.append(token) |
|
|
|
return " ".join(new_array) |
|
|
|
def gatherEnv(addenv): |
|
myenv = os.environ.copy() |
|
|
|
for k in addenv: |
|
myenv[k] = addenv[k] |
|
|
|
return myenv |
|
|
|
def setShowCommands(show): |
|
global show_commands |
|
show_commands = show |