Skip to content

Commit 2cb2355

Browse files
committed
Streamline ast-grep command execution handling
1 parent e86ebdb commit 2cb2355

File tree

1 file changed

+30
-76
lines changed

1 file changed

+30
-76
lines changed

main.py

Lines changed: 30 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ def dump_syntax_tree(
7474
7575
Internally calls: ast-grep run --pattern <code> --lang <language> --debug-query=<format>
7676
"""
77-
return run_ast_grep_dump(code, language, format.value)
78-
77+
result = run_ast_grep("run", ["--pattern", code, "--lang", language, f"--debug-query={format.value}"])
78+
return result.stderr.strip()
7979

8080
@mcp.tool()
8181
def test_match_code_rule(
@@ -88,24 +88,11 @@ def test_match_code_rule(
8888
8989
Internally calls: ast-grep scan --inline-rules <yaml> --json --stdin
9090
"""
91-
args = ["ast-grep", "scan","--inline-rules", yaml, "--json", "--stdin"]
92-
if CONFIG_PATH:
93-
args.extend(["--config", CONFIG_PATH])
94-
try:
95-
# Run command and capture output
96-
result = subprocess.run(
97-
args,
98-
capture_output=True,
99-
input=code,
100-
text=True,
101-
check=True # Raises CalledProcessError if return code is non-zero
102-
)
103-
matches = json.loads(result.stdout.strip())
104-
if not matches:
105-
raise ValueError("No matches found for the given code and rule. Try adding `stopBy: end` to your inside/has rule.")
106-
return matches
107-
except subprocess.CalledProcessError as e:
108-
return e.stderr
91+
result = run_ast_grep("scan", ["--inline-rules", yaml, "--json", "--stdin"], input_text = code)
92+
matches = json.loads(result.stdout.strip())
93+
if not matches:
94+
raise ValueError("No matches found for the given code and rule. Try adding `stopBy: end` to your inside/has rule.")
95+
return matches
10996

11097
@mcp.tool()
11198
def find_code(
@@ -120,7 +107,12 @@ def find_code(
120107
121108
Internally calls: ast-grep run --pattern <pattern> --json <project_folder>
122109
"""
123-
return run_ast_grep_command(pattern, project_folder, language)
110+
args = ["--pattern", pattern, "--json"]
111+
if language:
112+
args.extend(["--lang", language])
113+
args.append(project_folder)
114+
result = run_ast_grep("run", args)
115+
return json.loads(result.stdout)
124116

125117
@mcp.tool()
126118
def find_code_by_rule(
@@ -136,70 +128,32 @@ def find_code_by_rule(
136128
137129
Internally calls: ast-grep scan --inline-rules <yaml> --json <project_folder>
138130
"""
139-
return run_ast_grep_yaml(yaml, project_folder)
131+
args = ["--inline-rules", yaml, "--json", project_folder]
132+
result = run_ast_grep("scan", args)
133+
return json.loads(result.stdout)
140134

141-
def run_ast_grep_dump(code: str, language: str, format: str) -> str:
142-
args = ["ast-grep", "run", "--pattern", code, "--lang", language, f"--debug-query={format}"]
143-
if CONFIG_PATH:
144-
args.extend(["--config", CONFIG_PATH])
135+
def run_command(args: List[str], input_text: Optional[str] = None) -> subprocess.CompletedProcess:
145136
try:
146137
result = subprocess.run(
147138
args,
148139
capture_output=True,
140+
input=input_text,
149141
text=True,
150142
check=True # Raises CalledProcessError if return code is non-zero
151143
)
152-
return result.stderr.strip() # Return the output of the command
144+
return result
153145
except subprocess.CalledProcessError as e:
154-
print(f"Command failed with return code {e.returncode}")
155-
print("Error output:", e.stderr)
156-
return e.stderr.strip()
157-
158-
def run_ast_grep_command(pattern: str, project_folder: str, language: Optional[str]) -> List[dict[str, Any]]:
159-
try:
160-
args = ["ast-grep", "run", "--pattern", pattern, "--json"]
161-
if CONFIG_PATH:
162-
args.extend(["--config", CONFIG_PATH])
163-
if language:
164-
args.extend(["--lang", language])
165-
args.append(project_folder)
166-
# Run command and capture output
167-
result = subprocess.run(
168-
args,
169-
capture_output=True,
170-
text=True,
171-
check=True # Raises CalledProcessError if return code is non-zero
172-
)
173-
return json.loads(result.stdout)
174-
except subprocess.CalledProcessError as e:
175-
print(f"Command failed with return code {e.returncode}")
176-
print("Error output:", e.stderr)
177-
return e.stderr
178-
except FileNotFoundError:
179-
print("Command not found")
180-
return []
181-
182-
def run_ast_grep_yaml(yaml: str, project_folder: str) -> List[dict[str, Any]]:
183-
try:
184-
args = ["ast-grep", "scan", "--inline-rules", yaml, "--json"]
185-
if CONFIG_PATH:
186-
args.extend(["--config", CONFIG_PATH])
187-
args.append(project_folder)
188-
# Run command and capture output
189-
result = subprocess.run(
190-
args,
191-
capture_output=True,
192-
text=True,
193-
check=True # Raises CalledProcessError if return code is non-zero
194-
)
195-
return json.loads(result.stdout)
196-
except subprocess.CalledProcessError as e:
197-
print(f"Command failed with return code {e.returncode}")
198-
print("Error output:", e.stderr)
199-
return e.stderr
200-
except FileNotFoundError:
201-
print("Command not found")
202-
return []
146+
stderr_msg = e.stderr.strip() if e.stderr else "(no error output)"
147+
error_msg = f"Command {e.cmd} failed with exit code {e.returncode}: {stderr_msg}"
148+
raise RuntimeError(error_msg) from e
149+
except FileNotFoundError as e:
150+
error_msg = f"Command '{args[0]}' not found. Please ensure {args[0]} is installed and in PATH."
151+
raise RuntimeError(error_msg) from e
152+
153+
def run_ast_grep(command:str, args: List[str], input_text: Optional[str] = None) -> subprocess.CompletedProcess:
154+
if CONFIG_PATH:
155+
args = ["--config", CONFIG_PATH] + args
156+
return run_command(["ast-grep", command] + args, input_text)
203157

204158
def run_mcp_server() -> None:
205159
"""

0 commit comments

Comments
 (0)