@@ -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 ()
8181def 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 ()
11198def 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 ()
126118def 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
204158def run_mcp_server () -> None :
205159 """
0 commit comments