[cli] Add support for quoted strings in cli calls

pull/2/head
Daniel Van Der Maden 5 years ago
parent 790d6fc695
commit 6a260cf187
  1. 42
      pyhmy/cli.py

@ -60,6 +60,7 @@ else:
_accounts = {} # Internal accounts keystore, make sure to sync when needed.
_account_keystore_path = "~/.hmy/account-keys" # Internal path to account keystore, will match the current binary.
_binary_path = "hmy" # Internal binary path.
_arg_prefix = "__PYHMY_ARG_PREFIX__"
_keystore_cache_lock = Lock()
environment = os.environ.copy() # The environment for the CLI to execute in.
@ -138,6 +139,32 @@ def _sync_accounts():
del _accounts[key]
def _make_call_command(command):
"""
Internal function that processes a command String or String Arg List for
underlying pexpect or subprocess call.
Note that single quote is not respected for strings.
"""
if isinstance(command, list):
command_toks = command
else:
all_strings = re.findall(r'"(.*?)"', command)
for i, string in all_strings:
command = command.replace(string, f"{_arg_prefix}_{i}")
command_toks_prefix = [el for el in command.split(" ") if el]
command_toks = []
for el in command_toks_prefix:
if el.startswith(f'"{_arg_prefix}_') and el.endswith(f'"'):
index = int(el.replace(f'"{_arg_prefix}_', '').replace('"', ''))
command_toks.append(all_strings[index])
else:
command_toks.append(el)
if re.match(".*hmy", command_toks[0]):
command_toks = command_toks[1:]
return command_toks
def get_accounts_keystore():
"""
:returns A dictionary where the keys are the account names/aliases and the
@ -269,16 +296,13 @@ def remove_address(address):
def single_call(command, timeout=60, error_ok=False):
"""
:param command: String of command to execute on CLI
:param command: String or String Arg List of command to execute on CLI.
:param timeout: Optional timeout in seconds
:param error_ok: Optional flag to allow errors and return whatever possible
:returns: Decoded string of response from hmy CLI call
:raises: RuntimeError if bad command
"""
command_toks = [el for el in command.split(" ") if el]
if re.match(".*hmy", command_toks[0]):
command_toks = command_toks[1:]
command_toks = [_binary_path] + command_toks
command_toks = [_binary_path] + _make_call_command(command)
try:
return subprocess.check_output(command_toks, env=environment, timeout=timeout).decode()
except subprocess.CalledProcessError as err:
@ -290,14 +314,12 @@ def single_call(command, timeout=60, error_ok=False):
def expect_call(command, timeout=60):
"""
:param command: String fo command to execute on CLI
:param command: String or String Arg List of command to execute on CLI.
:param timeout: Optional timeout in seconds
:returns: A pexpect child program
:raises: RuntimeError if bad command
"""
command_toks = [el for el in command.split(" ") if el]
if re.match(".*hmy", command_toks[0]):
command_toks = command_toks[1:]
command_toks = _make_call_command(command)
try:
proc = pexpect.spawn(f"{_binary_path}", command_toks, env=environment, timeout=timeout)
proc.delaybeforesend = None
@ -357,4 +379,4 @@ def download(path="./bin/hmy", replace=True, verbose=True):
env.update(get_bls_build_variables())
else:
raise RuntimeWarning(f"Could not get environment for downloaded hmy CLI at `{path}`")
return env
return env

Loading…
Cancel
Save