11from pathlib import Path
22from threading import Event
3- import subprocess
3+
4+ from watchdog .observers import Observer
5+ from watchdog .events import FileSystemEventHandler , FileSystemEvent
46
57from ..status import find_watch_dirs
68
79from .sync import run_sync
810from .main import main
911
1012
13+ class EventHandler (FileSystemEventHandler ):
14+ def __init__ (self ):
15+ self .update_watched ()
16+
17+ def update_watched (self ):
18+ self .watched = find_watch_dirs ()
19+
20+ def on_any_event (self , event : FileSystemEvent ):
21+ if event .event_type == "opened" :
22+ return
23+
24+ if isinstance (event .src_path , bytes ):
25+ path = Path (event .src_path .decode ("utf-8" ))
26+ else :
27+ path = Path (event .src_path )
28+
29+ if path .absolute ().is_relative_to (Path ("./.entangled" ).absolute ()):
30+ return
31+ if any (path .absolute ().is_relative_to (p .absolute ()) for p in self .watched ):
32+ run_sync ()
33+ # os.sync()
34+ self .update_watched ()
35+
36+
1137def _watch (_stop_event : Event | None = None , _start_event : Event | None = None ):
1238 """Keep a loop running, watching for changes. This interface is separated
1339 from the CLI one, so that it can be tested using threading instead of
@@ -16,12 +42,22 @@ def _watch(_stop_event: Event | None = None, _start_event: Event | None = None):
1642 def stop () -> bool :
1743 return _stop_event is not None and _stop_event .is_set ()
1844
45+ run_sync ()
46+
47+ event_handler = EventHandler ()
48+ observer = Observer ()
49+ observer .schedule (event_handler , "." , recursive = True )
50+ observer .start ()
51+
1952 if _start_event :
2053 _start_event .set ()
2154
22- while not stop ():
23- subprocess .run (["watchman-wait" ] + list (find_watch_dirs ()))
24- run_sync ()
55+ try :
56+ while observer .is_alive () and not stop ():
57+ observer .join (0.1 )
58+ finally :
59+ observer .stop ()
60+ observer .join ()
2561
2662
2763@main .command ()
0 commit comments