|
| 1 | +import json |
| 2 | +import shlex |
| 3 | +import subprocess |
| 4 | +from pathlib import Path |
| 5 | + |
| 6 | +from mypy.state import state |
| 7 | + |
| 8 | +from patchwork.logger import logger |
| 9 | +from patchwork.step import Step, StepStatus |
| 10 | +from patchwork.steps.CallCommand.typed import CallCommandInputs, CallCommandOutputs |
| 11 | + |
| 12 | + |
| 13 | +class CallCommand(Step, input_class=CallCommandInputs, output_class=CallCommandOutputs): |
| 14 | + def __init__(self, inputs: dict): |
| 15 | + super().__init__(inputs) |
| 16 | + self.command = inputs["command"] |
| 17 | + self.command_args = inputs.get("command_args", "") |
| 18 | + self.working_dir = inputs.get("working_dir", Path.cwd()) |
| 19 | + self.env = self.__parse_env_text(inputs.get("env", "")) |
| 20 | + |
| 21 | + @staticmethod |
| 22 | + def __parse_env_text(env_text): |
| 23 | + env_spliter = shlex.shlex(env_text, posix=True) |
| 24 | + env_spliter.whitespace_split = True |
| 25 | + env_spliter.whitespace += ";" |
| 26 | + |
| 27 | + env = dict() |
| 28 | + for env_assign in env_spliter: |
| 29 | + env_assign_spliter = shlex.shlex(env_assign, posix=True) |
| 30 | + env_assign_spliter.whitespace_split = True |
| 31 | + env_assign_spliter.whitespace += "=" |
| 32 | + env_parts = list(env_assign_spliter) |
| 33 | + if len(env_parts) < 1: |
| 34 | + continue |
| 35 | + |
| 36 | + env_assign_target = env_parts[0] |
| 37 | + if len(env_parts) < 2: |
| 38 | + logger.error(f"{env_assign_target} is not assigned anything, skipping...") |
| 39 | + continue |
| 40 | + if len(env_parts) > 2: |
| 41 | + logger.error(f"{env_assign_target} has more than 1 assignment, skipping...") |
| 42 | + continue |
| 43 | + env[env_assign_target] = env_parts[1] |
| 44 | + |
| 45 | + return env |
| 46 | + |
| 47 | + def run(self) -> dict: |
| 48 | + cmd = [self.command, *shlex.split(self.command_args)] |
| 49 | + p = subprocess.run(cmd, capture_output=True, text=True, cwd=self.working_dir, env=self.env) |
| 50 | + try: |
| 51 | + p.check_returncode() |
| 52 | + return dict(stdout_output=p.stdout) |
| 53 | + except subprocess.CalledProcessError as e: |
| 54 | + self.set_status(StepStatus.FAILED, f"`{self.command} {self.command_args}` failed with stdout:\n{p.stdout}\nstderr:\n{e.stderr}") |
| 55 | + return dict() |
0 commit comments