Skip to content

Commit 5b4daf7

Browse files
committed
change command to shell
1 parent d32edc8 commit 5b4daf7

File tree

9 files changed

+54
-47
lines changed

9 files changed

+54
-47
lines changed

patchwork/common/utils/utils.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
import atexit
44
import dataclasses
5+
import random
56
import signal
7+
import string
68
import tempfile
9+
from collections.abc import Mapping
710
from pathlib import Path
811

12+
import chevron
913
import tiktoken
1014
from chardet.universaldetector import UniversalDetector
1115
from git import Head, Repo
@@ -19,6 +23,20 @@
1923
_NEWLINES = {"\n", "\r\n", "\r"}
2024

2125

26+
def mustache_render(template: str, data: Mapping) -> str:
27+
if len(data.keys()) < 1:
28+
return template
29+
30+
chevron.render.__globals__["_html_escape"] = lambda x: x
31+
return chevron.render(
32+
template=template,
33+
data=data,
34+
partials_path=None,
35+
partials_ext="".join(random.choices(string.ascii_uppercase + string.digits, k=32)),
36+
partials_dict=dict(),
37+
)
38+
39+
2240
def detect_newline(path: str | Path) -> str | None:
2341
with open(path, "r", newline="") as f:
2442
lines = f.read().splitlines(keepends=True)

patchwork/steps/CallCommand/typed.py

Lines changed: 0 additions & 19 deletions
This file was deleted.

patchwork/steps/CallSQL/CallSQL.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
from sqlalchemy import URL, create_engine, exc, text
44

5+
from patchwork.common.utils.utils import mustache_render
56
from patchwork.step import Step, StepStatus
67
from patchwork.steps.CallSQL.typed import CallSQLInputs, CallSQLOutputs
78

89

910
class CallSQL(Step, input_class=CallSQLInputs, output_class=CallSQLOutputs):
1011
def __init__(self, inputs: dict):
1112
super().__init__(inputs)
12-
self.query = inputs["query"]
13+
query_template_data = inputs.get("query_template_values", {})
14+
self.query = mustache_render(inputs["query"], query_template_data)
1315
self.__build_engine(inputs)
1416

1517
def __build_engine(self, inputs: dict):

patchwork/steps/CallSQL/typed.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class CallSQLInputs(__RequiredCallSQLInputs, total=False):
1515
host: str
1616
port: int
1717
database: str
18+
query_template_values: dict[str, Any]
1819

1920

2021
class CallSQLOutputs(TypedDict):

patchwork/steps/CallCommand/CallCommand.py renamed to patchwork/steps/CallShell/CallShell.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
from __future__ import annotations
22

33
import shlex
4-
import shutil
54
import subprocess
65
from pathlib import Path
76

7+
from patchwork.common.utils.utils import mustache_render
88
from patchwork.logger import logger
99
from patchwork.step import Step, StepStatus
10-
from patchwork.steps.CallCommand.typed import CallCommandInputs, CallCommandOutputs
10+
from patchwork.steps.CallShell.typed import CallShellInputs, CallShellOutputs
1111

1212

13-
class CallCommand(Step, input_class=CallCommandInputs, output_class=CallCommandOutputs):
13+
class CallShell(Step, input_class=CallShellInputs, output_class=CallShellOutputs):
1414
def __init__(self, inputs: dict):
1515
super().__init__(inputs)
16-
self.command = shutil.which(inputs["command"])
17-
if self.command is None:
18-
raise ValueError(f"Command `{inputs['command']}` not found in PATH")
19-
self.command_args = shlex.split(inputs.get("command_args", ""))
16+
script_template_values = inputs.get("script_template_values", {})
17+
self.script = mustache_render(inputs["script"], script_template_values)
2018
self.working_dir = inputs.get("working_dir", Path.cwd())
2119
self.env = self.__parse_env_text(inputs.get("env", ""))
2220

@@ -47,14 +45,12 @@ def __parse_env_text(env_text: str) -> dict[str, str]:
4745
return env
4846

4947
def run(self) -> dict:
50-
cmd = [self.command, *self.command_args]
51-
p = subprocess.run(cmd, capture_output=True, text=True, cwd=self.working_dir, env=self.env)
48+
p = subprocess.run(self.script, shell=True, capture_output=True, text=True, cwd=self.working_dir, env=self.env)
5249
try:
5350
p.check_returncode()
54-
return dict(stdout_output=p.stdout)
5551
except subprocess.CalledProcessError as e:
5652
self.set_status(
5753
StepStatus.FAILED,
58-
f"`{self.command} {self.command_args}` failed with stdout:\n{p.stdout}\nstderr:\n{e.stderr}",
54+
f"script failed with stdout:\n{p.stdout}\nstderr:\n{e.stderr}",
5955
)
60-
return dict(stdout_output="")
56+
return dict(stdout_output=p.stdout, stderr_output=p.stderr)

patchwork/steps/CallShell/typed.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from __future__ import annotations
2+
3+
from typing_extensions import Annotated, Any, TypedDict
4+
5+
from patchwork.common.utils.step_typing import StepTypeConfig
6+
7+
8+
class __RequiredCallShellInputs(TypedDict):
9+
script: str
10+
11+
12+
class CallShellInputs(__RequiredCallShellInputs, total=False):
13+
working_dir: Annotated[str, StepTypeConfig(is_path=True)]
14+
env: str
15+
script_template_values: dict[str, Any]
16+
17+
18+
class CallShellOutputs(TypedDict):
19+
stdout_output: str

patchwork/steps/PreparePrompt/PreparePrompt.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
from __future__ import annotations
22

33
import json
4-
import random
5-
import string
64
from pathlib import Path
75

8-
import chevron
9-
106
from patchwork.common.constants import PROMPT_TEMPLATE_FILE_KEY
7+
from patchwork.common.utils.utils import mustache_render
118
from patchwork.logger import logger
129
from patchwork.step import Step, StepStatus
1310

@@ -76,7 +73,6 @@ def run(self) -> dict:
7673
return dict(prompts=[])
7774

7875
prompts = []
79-
chevron.render.__globals__["_html_escape"] = lambda string: string
8076
for prompt_value in self.prompt_values:
8177
dict_value = prompt_value
8278
if not isinstance(dict_value, dict):
@@ -86,13 +82,7 @@ def run(self) -> dict:
8682
for prompt_part in self.prompt_template:
8783
prompt_instance = {}
8884
for key, value in prompt_part.items():
89-
new_value = chevron.render(
90-
template=value,
91-
data=dict_value,
92-
partials_path=None,
93-
partials_ext="".join(random.choices(string.ascii_uppercase + string.digits, k=32)),
94-
partials_dict=dict(),
95-
)
85+
new_value = mustache_render(value, dict_value)
9686
prompt_instance[key] = new_value
9787
prompt.append(prompt_instance)
9888
prompts.append(prompt)

patchwork/steps/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from patchwork.steps.CallAPI.CallAPI import CallAPI
44
from patchwork.steps.CallCode2Prompt.CallCode2Prompt import CallCode2Prompt
55
from patchwork.steps.CallLLM.CallLLM import CallLLM
6+
from patchwork.steps.CallShell.CallShell import CallShell
7+
from patchwork.steps.CallSQL.CallSQL import CallSQL
68
from patchwork.steps.Combine.Combine import Combine
79
from patchwork.steps.CommitChanges.CommitChanges import CommitChanges
810
from patchwork.steps.CreateIssue.CreateIssue import CreateIssue
@@ -48,8 +50,6 @@
4850
from patchwork.steps.SimplifiedLLM.SimplifiedLLM import SimplifiedLLM
4951
from patchwork.steps.SimplifiedLLMOnce.SimplifiedLLMOnce import SimplifiedLLMOnce
5052
from patchwork.steps.SlackMessage.SlackMessage import SlackMessage
51-
from patchwork.steps.CallCommand.CallCommand import CallCommand
52-
from patchwork.steps.CallSQL.CallSQL import CallSQL
5353

5454
# Compatibility Aliases
5555
JoinListPB = JoinList
@@ -63,7 +63,7 @@
6363
"AnalyzeImpact",
6464
"CallAPI",
6565
"CallCode2Prompt",
66-
"CallCommand",
66+
"CallShell",
6767
"CallSQL",
6868
"CallLLM",
6969
"Combine",

0 commit comments

Comments
 (0)