Skip to content

Commit a0b040e

Browse files
committed
Try pexpect
1 parent 874eb87 commit a0b040e

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

build/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
GitPython
22
PyYAML
3+
pexpect
34
psutil
45
python-dotenv
56
structlog

src/source_repo/svn.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,12 +361,23 @@ def _test_connection_and_credentials(ctx: Context, commands: dict) -> bool:
361361
job_config = ctx.job.get("config",{})
362362
max_retries = job_config.get("max_retries")
363363
password = job_config.get("password")
364-
expect = job_config.get("expect")
364+
expect_tuple = job_config.get("expect")
365365
cmd_svn_info = commands["cmd_svn_info"]
366366
tries_attempted = 1
367367

368368
while True:
369369

370+
expect, response = expect_tuple
371+
372+
test = cmd.run_pexpect(
373+
ctx,
374+
args = cmd_svn_info,
375+
expect = expect,
376+
response = response
377+
)
378+
379+
log(ctx, "test:", "debug", {"test": test})
380+
370381
# Run the command, capture the output
371382
svn_info = cmd.run_subprocess(
372383
ctx,

src/utils/cmd.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
from typing import Union, Optional, Dict, Any, List
1212
import os
1313
import subprocess
14+
import sys
15+
import time
1416
import textwrap
1517
import uuid
1618

1719
# Import third party modules
20+
import pexpect # https://pexpect.readthedocs.io/en/stable/install.html
1821
import psutil # Check for breaking changes https://github.com/giampaolo/psutil/blob/master/HISTORY.rst
1922

20-
2123
def get_pid_uptime(pid: int = 1) -> Optional[timedelta]:
2224
"""
2325
Get the uptime of a running process by its PID.
@@ -222,6 +224,71 @@ def log_process_status(
222224
log(ctx, status_message, log_level, structured_log_dict)
223225

224226

227+
def run_pexpect(
228+
ctx: Context,
229+
args: Union[str, List[str]],
230+
expect: Union[str, List[str]],
231+
response: str
232+
) -> Dict:
233+
"""
234+
Run a command through the pexpect module
235+
Wait for expect to come from the command
236+
Then send the response into the command
237+
"""
238+
239+
return_dict = {}
240+
241+
# Convert args to a string
242+
if isinstance(args, List):
243+
args = " ".join(args)
244+
245+
246+
try:
247+
248+
child = pexpect.spawn(
249+
command = args,
250+
encoding = 'utf-8',
251+
echo = False
252+
)
253+
254+
return_dict["pid"] = child.pid
255+
256+
log(ctx, f"child.pid: {child.pid}")
257+
258+
child.logfile_read = sys.stdout.buffer
259+
260+
match = child.expect_exact(
261+
pattern = expect,
262+
timeout = 120
263+
)
264+
265+
if match == 0:
266+
child.sendline(response)
267+
log(ctx, "match, sending response")
268+
else:
269+
log(ctx, "no match")
270+
271+
272+
time.sleep(1)
273+
274+
child.close(force=False)
275+
276+
return_dict["output"] = child.before + child.after
277+
return_dict["return_code"] = child.exitstatus
278+
return_dict["signal_status"] = child.signalstatus
279+
280+
except pexpect.EOF:
281+
log(ctx, f"pexpect child exited: {str(child)}")
282+
283+
except pexpect.TIMEOUT:
284+
log(ctx, f"pexpect hit a timeout: {str(child)}", "error")
285+
286+
except:
287+
log(ctx, f"pexpect child threw an exception: {str(child)}", "error")
288+
289+
return return_dict
290+
291+
225292
def run_subprocess(
226293
ctx: Context,
227294
args: Union[str, List[str]],

0 commit comments

Comments
 (0)