99
1010import shtab
1111
12+ from vectorcode .subcommands .vectorise import (
13+ chunked_add ,
14+ exclude_paths_by_spec ,
15+ find_exclude_specs ,
16+ load_files_from_include ,
17+ )
18+
1219try : # pragma: nocover
1320 from lsprotocol import types
1421 from pygls .exceptions import (
2936 Config ,
3037 cleanup_path ,
3138 config_logging ,
39+ expand_globs ,
3240 find_project_root ,
3341 get_project_config ,
3442 parse_cli_args ,
@@ -86,14 +94,6 @@ async def execute_command(ls: LanguageServer, args: list[str]):
8694 logger .info ("Received command arguments: %s" , args )
8795 parsed_args = await parse_cli_args (args )
8896 logger .info ("Parsed command arguments: %s" , parsed_args )
89- if parsed_args .action not in {CliAction .query , CliAction .ls }:
90- error_message = (
91- f"Unsupported vectorcode subcommand: { str (parsed_args .action )} "
92- )
93- logger .error (
94- error_message ,
95- )
96- raise JsonRpcInvalidRequest (error_message )
9797 if parsed_args .project_root is None :
9898 if DEFAULT_PROJECT_ROOT is not None :
9999 parsed_args .project_root = DEFAULT_PROJECT_ROOT
@@ -136,12 +136,12 @@ async def execute_command(ls: LanguageServer, args: list[str]):
136136 )
137137 final_results = []
138138 try :
139- if collection is None :
140- print ( "Please specify a project to search in." , file = sys . stderr )
141- else :
142- final_results .extend (
143- await build_query_results (collection , final_configs )
144- )
139+ assert collection is not None , (
140+ "Failed to find the correct collection."
141+ )
142+ final_results .extend (
143+ await build_query_results (collection , final_configs )
144+ )
145145 finally :
146146 log_message = f"Retrieved { len (final_results )} result{ 's' if len (final_results ) > 1 else '' } in { round (time .time () - start_time , 2 )} s."
147147 ls .progress .end (
@@ -168,11 +168,73 @@ async def execute_command(ls: LanguageServer, args: list[str]):
168168 )
169169 logger .info (f"Retrieved { len (projects )} project(s)." )
170170 return projects
171- except Exception as e :
171+ case CliAction .vectorise :
172+ assert collection is not None , "Failed to find the correct collection."
173+ ls .progress .begin (
174+ progress_token ,
175+ types .WorkDoneProgressBegin (
176+ title = "VectorCode" , message = "Vectorising files..." , percentage = 0
177+ ),
178+ )
179+ files = await expand_globs (
180+ final_configs .files
181+ or load_files_from_include (str (final_configs .project_root )),
182+ recursive = final_configs .recursive ,
183+ include_hidden = final_configs .include_hidden ,
184+ )
185+ if not final_configs .force : # pragma: nocover
186+ # tested in 'vectorise.py'
187+ for spec in find_exclude_specs (final_configs ):
188+ if os .path .isfile (spec ):
189+ logger .info (f"Loading ignore specs from { spec } ." )
190+ files = exclude_paths_by_spec ((str (i ) for i in files ), spec )
191+ stats = {"add" : 0 , "update" : 0 , "removed" : 0 }
192+ collection_lock = asyncio .Lock ()
193+ stats_lock = asyncio .Lock ()
194+ max_batch_size = await client .get_max_batch_size ()
195+ semaphore = asyncio .Semaphore (os .cpu_count () or 1 )
196+ tasks = [
197+ asyncio .create_task (
198+ chunked_add (
199+ str (file ),
200+ collection ,
201+ collection_lock ,
202+ stats ,
203+ stats_lock ,
204+ final_configs ,
205+ max_batch_size ,
206+ semaphore ,
207+ )
208+ )
209+ for file in files
210+ ]
211+ for i , task in enumerate (asyncio .as_completed (tasks ), start = 1 ):
212+ await task
213+ ls .progress .report (
214+ progress_token ,
215+ types .WorkDoneProgressReport (
216+ message = "Vectorising files..." ,
217+ percentage = int (100 * i / len (tasks )),
218+ ),
219+ )
220+ ls .progress .end (
221+ progress_token ,
222+ types .WorkDoneProgressEnd (
223+ message = f"Vectorised { stats ['add' ] + stats ['update' ]} files."
224+ ),
225+ )
226+ return stats
227+ case _ as c : # pragma: nocover
228+ error_message = f"Unsupported vectorcode subcommand: { str (c )} "
229+ logger .error (
230+ error_message ,
231+ )
232+ raise JsonRpcInvalidRequest (error_message )
233+ except Exception as e : # pragma: nocover
172234 if isinstance (e , JsonRpcException ):
173235 # pygls exception. raise it as is.
174236 raise
175- else : # pragma: nocover
237+ else :
176238 # wrap non-pygls errors for error codes.
177239 raise JsonRpcInternalError (message = traceback .format_exc ()) from e
178240
0 commit comments