feat(cli): watch files with event streams
Build and Push Docker Container / build-and-push (push) Successful in 2m3s
Build and Push Docker Container / build-and-push (push) Successful in 2m3s
- Add a private SSE endpoint that emits file change events for authenticated clients. - Replace the watch sleep loop with watchdog local file events and remote SSE triggers. - Debounce local event bursts and keep watch running after transient sync failures. - Add watchdog as a standalone CLI dependency and cover watch behavior in tests. - Bump NanoShare to 1.25.0 and the standalone CLI to 0.4.0.
This commit is contained in:
@@ -11,6 +11,7 @@ from nanoshare_client.auth import _CallbackServer
|
||||
from nanoshare_client.completion import script as completion_script
|
||||
from nanoshare_client.ignore import load_ignore_patterns, is_ignored
|
||||
from nanoshare_client.table import format_table
|
||||
from nanoshare_client.watch import _is_relevant_path
|
||||
|
||||
class FakeClient:
|
||||
def __init__(self):
|
||||
@@ -268,6 +269,44 @@ def test_default_ignore_patterns_skip_common_generated_files(tmp_path):
|
||||
assert is_ignored('nested/Thumbs.db', patterns)
|
||||
assert not is_ignored('docs/note.txt', patterns)
|
||||
|
||||
def test_watch_loop_retries_after_sync_error(monkeypatch, tmp_path):
|
||||
from nanoshare_client import watch as watch_module
|
||||
|
||||
calls = []
|
||||
|
||||
class FakeFlag:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def clear(self):
|
||||
pass
|
||||
|
||||
def wait(self, timeout):
|
||||
return False
|
||||
|
||||
def fake_sync(args):
|
||||
calls.append(args.folder)
|
||||
if len(calls) == 1:
|
||||
return 1
|
||||
raise KeyboardInterrupt
|
||||
|
||||
monkeypatch.setattr(watch_module, '_ChangeFlag', FakeFlag)
|
||||
monkeypatch.setattr(watch_module, '_watchdog_observer', lambda *args: None)
|
||||
args = type('Args', (), {'folder': str(tmp_path), 'ignore': [], 'interval': 0.1})()
|
||||
|
||||
code = watch_module.watch_loop(args, fake_sync)
|
||||
|
||||
assert code == 0
|
||||
assert calls == [str(tmp_path), str(tmp_path)]
|
||||
|
||||
def test_watch_relevance_ignores_sync_state_and_default_ignores(tmp_path):
|
||||
patterns = load_ignore_patterns(tmp_path)
|
||||
|
||||
assert _is_relevant_path(tmp_path, str(tmp_path / 'note.txt'), patterns)
|
||||
assert not _is_relevant_path(tmp_path, str(tmp_path / '.nanoshare-sync' / 'state.json'), patterns)
|
||||
assert not _is_relevant_path(tmp_path, str(tmp_path / '.comments' / 'comment.xml'), patterns)
|
||||
assert not _is_relevant_path(tmp_path, str(tmp_path / '.env'), patterns)
|
||||
|
||||
def test_completion_scripts_include_commands():
|
||||
zsh = completion_script('zsh')
|
||||
bash = completion_script('bash')
|
||||
|
||||
Reference in New Issue
Block a user