| 382 | |
| 383 | |
| 384 | class CodeWatcher: |
| 385 | def __init__( |
| 386 | self, |
| 387 | graph_builder: "GraphBuilder", |
| 388 | job_manager="JobManager", |
| 389 | use_polling: typing.Optional[bool] = None, |
| 390 | ): |
| 391 | self.graph_builder = graph_builder |
| 392 | observer_cls = PollingObserver if should_use_polling_observer(use_polling) else Observer |
| 393 | self.observer = observer_cls() |
| 394 | |
| 395 | self.watched_paths = set() |
| 396 | self.watches = {} |
| 397 | self.handlers = {} |
| 398 | |
| 399 | def watch_directory( |
| 400 | self, |
| 401 | path: str, |
| 402 | perform_initial_scan: bool = True, |
| 403 | cgcignore_path: str = None, |
| 404 | sync_on_start: bool = False, |
| 405 | ): |
| 406 | path_obj = Path(path).resolve() |
| 407 | path_str = str(path_obj) |
| 408 | |
| 409 | if path_str in self.watched_paths: |
| 410 | return {"message": "Already watching"} |
| 411 | |
| 412 | handler = RepositoryEventHandler( |
| 413 | self.graph_builder, |
| 414 | path_obj, |
| 415 | perform_initial_scan=perform_initial_scan, |
| 416 | sync_on_start=sync_on_start, |
| 417 | cgcignore_path=cgcignore_path, |
| 418 | ) |
| 419 | |
| 420 | watch = self.observer.schedule(handler, path_str, recursive=True) |
| 421 | |
| 422 | self.watches[path_str] = watch |
| 423 | self.handlers[path_str] = handler |
| 424 | self.watched_paths.add(path_str) |
| 425 | |
| 426 | return {"message": f"Watching {path_str}"} |
| 427 | |
| 428 | def unwatch_directory(self, path: str): |
| 429 | path_str = str(Path(path).resolve()) |
| 430 | |
| 431 | handler = self.handlers.pop(path_str, None) |
| 432 | if handler: |
| 433 | handler.cancel_timers() |
| 434 | |
| 435 | watch = self.watches.pop(path_str, None) |
| 436 | if watch: |
| 437 | self.observer.unschedule(watch) |
| 438 | |
| 439 | self.watched_paths.discard(path_str) |
| 440 | |
| 441 | return {"message": f"Stopped watching {path_str}"} |
no outgoing calls
no test coverage detected