start introducing modules
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from subprocess import Popen, call, check_output, PIPE
|
||||
|
||||
from misc import assert_type
|
||||
|
||||
|
||||
class CommandInterface:
|
||||
_BINARY: Path
|
||||
|
||||
@classmethod
|
||||
def _run_command(cls, *args: str) -> None:
|
||||
CommandRunner.run([str(cls._BINARY), *args])
|
||||
|
||||
@classmethod
|
||||
def _get_output(cls, *args: str) -> str:
|
||||
return CommandRunner.get_output([str(cls._BINARY), *args])
|
||||
|
||||
@classmethod
|
||||
def _open_stream(cls, *args: str) -> Popen:
|
||||
return CommandRunner.send_stream([str(cls._BINARY), *args])
|
||||
|
||||
@classmethod
|
||||
def _receive_stream(cls, *args: str, stream: Popen) -> None:
|
||||
CommandRunner.receive_from_stream([str(cls._BINARY), *args], stream=stream)
|
||||
|
||||
|
||||
class CommandRunner:
|
||||
@staticmethod
|
||||
def _sanity_check(cmdline: list[str]) -> None:
|
||||
assert_type(cmdline, list, "Command line must be a list")
|
||||
for item in cmdline:
|
||||
assert_type(item, str, "Only strings allowed in command line")
|
||||
|
||||
@staticmethod
|
||||
def _to_list(command: str | list[str]) -> list[str]:
|
||||
"""If the command is a str, return it as list. Otherwise, return the command."""
|
||||
if isinstance(command, str):
|
||||
return [command]
|
||||
return command
|
||||
|
||||
@classmethod
|
||||
def run(cls, cmdline: str | list[str]) -> None:
|
||||
"""Run the command, wait for it to return."""
|
||||
cmdline = cls._to_list(cmdline)
|
||||
cls._sanity_check(cmdline)
|
||||
call(cmdline)
|
||||
|
||||
@classmethod
|
||||
def get_output(cls, cmdline: str | list[str]) -> str:
|
||||
"""Run the command, return the output of the command."""
|
||||
cmdline = cls._to_list(cmdline)
|
||||
cls._sanity_check(cmdline)
|
||||
return check_output(cmdline).strip().decode()
|
||||
|
||||
@classmethod
|
||||
def receive_from_stream(cls, cmdline: str | list[str], stream: Popen) -> None:
|
||||
"""Run the command, receive data from a pipe to stdin."""
|
||||
cmdline = cls._to_list(cmdline)
|
||||
cls._sanity_check(cmdline)
|
||||
check_output(cmdline, stdin=stream.stdout)
|
||||
|
||||
@classmethod
|
||||
def send_stream(cls, cmdline: str | list[str]) -> Popen:
|
||||
"""Run the command, redirect stdout to a pipe."""
|
||||
cmdline = cls._to_list(cmdline)
|
||||
cls._sanity_check(cmdline)
|
||||
return Popen(cmdline, stdout=PIPE)
|
||||
Reference in New Issue
Block a user