Compare commits

...

2 Commits

Author SHA1 Message Date
poikilos 60e9027e2e Fix type-o. 1 year ago
poikilos 2024251efb Work on issue #616 (not fixed yet). 1 year ago
  1. 73
      utilities/run-any

73
utilities/run-any

@ -13,6 +13,7 @@ import sys
import subprocess import subprocess
import copy import copy
import shlex import shlex
import platform
from pprint import pformat from pprint import pformat
from collections import OrderedDict from collections import OrderedDict
@ -90,6 +91,7 @@ def show_and_return(cmd, enable_collect=False, cwd=None, shell=False):
Returns: Returns:
dict: 'code' is return code of the command. dict: 'code' is return code of the command.
""" """
prefix = "[show_and_return] "
# (See # (See
# <https://cyberciti.biz/faq/python-run-external-command-and-get-output/>) # <https://cyberciti.biz/faq/python-run-external-command-and-get-output/>)
if shell not in [None, True, False]: if shell not in [None, True, False]:
@ -101,16 +103,59 @@ def show_and_return(cmd, enable_collect=False, cwd=None, shell=False):
# shell cannot correctly utilize a list/tuple (only first # shell cannot correctly utilize a list/tuple (only first
# element is used!) so join as string to use all arguments: # element is used!) so join as string to use all arguments:
cmd = shlex.join(cmd) cmd = shlex.join(cmd)
echo0("Running %s" % pformat(cmd)) remove_bin = False # FIXME: True for debug only
proc = subprocess.Popen(cmd, shell=shell, stderr=subprocess.PIPE, # ^ Either True/False succeeds in bash, either fails in vscode
stdout=subprocess.PIPE, cwd=cwd) # with https://github.com/Poikilos/EnlivenMinetest/issues/616
code = None if remove_bin:
# Do not wait for finish--start displaying output immediately cwd = os.path.join(cwd, "bin")
bin_rel = "./bin/"
if isinstance(cmd, list):
if cmd[0].startswith(bin_rel):
cmd[0] = "./" + cmd[0][len(bin_rel):]
else:
if cmd.startswith(bin_rel):
cmd = "./" + cmd[len(bin_rel):]
force_shell = False
# ^ Either True/False succeeds in bash, either fails in vscode
# with https://github.com/Poikilos/EnlivenMinetest/issues/616
if not shell and force_shell:
# force_shell fails with shell=True (just hangs
# near `meta['bytes'] = err['source'].read(1)`,
# even if run-any is run from bash prompt manually)
if platform.system() == "Linux":
if isinstance(cmd, list):
cmd = ["bash", "-c", "cd '" + cwd + "'; " + shlex.join(cmd)]
else:
cmd = ["bash", "-c", "cd '" + cwd + "'; " + cmd]
run_msg = "Running %s" % pformat(cmd)
run_msg += ' # shell=%s in "%s"' % (shell, cwd)
echo0(run_msg)
if cwd is not None:
os.chdir(cwd)
enable_call = False
out = { out = {
'bytes': None, # current line bytes 'bytes': None, # current line bytes
'string': "", # current line string (same as bytes if Python 2 running) 'string': "", # current line string
# ^ (same as bytes if Python 2 running)
'buffer': "", # cumulative buffer 'buffer': "", # cumulative buffer
'lines': [],
} }
if enable_call: # FIXME: True for debug only--issue #616 (doesn't fix)
err = copy.deepcopy(out)
out['source'] = []
stream_metas = OrderedDict({
'out': out,
'err': err,
})
code = subprocess.call(cmd)
return { # FIXME: for debug issue #616 only
'code': code,
'streams': stream_metas,
}
proc = subprocess.Popen(cmd, shell=shell, stderr=subprocess.PIPE,
stdout=subprocess.PIPE, cwd=cwd)
code = None
# Do not wait for finish--start displaying output immediately
if enable_collect: if enable_collect:
out['lines'] = [] # already-shown lines out['lines'] = [] # already-shown lines
err = copy.deepcopy(out) # sets err['lines'] if enable_collect err = copy.deepcopy(out) # sets err['lines'] if enable_collect
@ -150,7 +195,7 @@ def show_and_return(cmd, enable_collect=False, cwd=None, shell=False):
print(meta['buffer'].rstrip("\n\r")) print(meta['buffer'].rstrip("\n\r"))
else: else:
echo0(meta['buffer'].rstrip("\n\r")) echo0(meta['buffer'].rstrip("\n\r"))
meta['lines'] += this_chunk.split("\n") meta['lines'] += meta['buffer'].split("\n")
break break
for _, meta in stream_metas.items(): for _, meta in stream_metas.items():
@ -206,14 +251,20 @@ def main():
raise ValueError("expected an executable!") raise ValueError("expected an executable!")
cwd = None cwd = None
if os.path.isfile(path): if os.path.isfile(path):
cwd = os.path.dirname(path) cwd = os.path.dirname(os.path.realpath(path))
if os.path.basename(cwd) == "bin": dir_name = os.path.basename(cwd)
if dir_name == "bin":
# Minetest must run from minetest not from minetest/bin # Minetest must run from minetest not from minetest/bin
# (especially when minetest is a script in minetest.org # (especially when minetest is a script in minetest.org
# builds) # builds)
cwd = os.path.dirname(cwd) cwd = os.path.dirname(cwd)
else:
echo0("Warning: not Minetest-like dir_name=%s" % dir_name)
else:
raise ValueError('missing "%s"--use absolute path if not in cwd'
% path)
# else: # else:
# cwd = os.dirname(hierosoft.which(path)) # TODO: uncomment this case? # cwd = os.dirname(hierosoft.which(path)) # TODO:uncomment this case?
basename = os.path.basename(path) basename = os.path.basename(path)
project_name = basename.replace("server", "") project_name = basename.replace("server", "")
cmd = path cmd = path
@ -224,10 +275,8 @@ def main():
# minetest/ not minetest/bin/ is the root of paths in tracebacks # minetest/ not minetest/bin/ is the root of paths in tracebacks
# Do not write debug.txt to cwd, since Python code will read # Do not write debug.txt to cwd, since Python code will read
# stdout and stderr. # stdout and stderr.
echo0("Running %s" % shlex.join(cmd))
else: else:
targetBaseDir = exeDir targetBaseDir = exeDir
echo0("Running %s" % path)
if inspector: if inspector:
OutputInspector.addRoot(targetBaseDir) OutputInspector.addRoot(targetBaseDir)
enable_collect = True enable_collect = True

Loading…
Cancel
Save