Skip to content

Commit fd0f843

Browse files
committed
Add file watcher for automatic push on changes
1 parent 2abbea3 commit fd0f843

File tree

2 files changed

+64
-13
lines changed

2 files changed

+64
-13
lines changed

setup.cfg

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ install_requires =
2525
pipfile-requirements~=0.3
2626
requests~=2.31
2727
semver~=3.0
28+
watchdog~=6.0
2829

2930

3031
[options.packages.find]

src/viur_cli/scriptor/cli.py

+63-13
Original file line numberDiff line numberDiff line change
@@ -180,25 +180,29 @@ def create_file():
180180
@script.command()
181181
@click.option('--force', '-f', is_flag=True, default=False,
182182
help='Force push files from the local working directory onto the server')
183+
@click.option('--watch', '-w', is_flag=True, default=False,
184+
help="Watch for file changes in the script folder and push them to the server")
183185
@click.pass_context
184-
def push(ctx: click.Context, force: bool):
186+
def push(ctx: click.Context, force: bool, watch: bool):
185187
"""
186188
Push contents of working_dir to server.
187189
"""
190+
188191
check_session(ctx)
189192
Request.COOKIES = cookiejar_from_dict(Config().get("cookies", {}))
190193

191194
from .scriptor.module import TreeModule
192195
tree = TreeModule("script")
193196

194-
async def main():
197+
async def main(file_path: str=None):
195198
await tree.structure("node")
196-
197199
working_dir = Config().get("working_dir")
198200
_files = glob.glob(f"{working_dir}/**/*", recursive=True)
199-
200201
for file in _files:
201202
_real_file = file
203+
if file_path and file_path != _real_file:
204+
# only push a single file
205+
continue
202206
parent = os.path.dirname(file)
203207
_type = "leaf"
204208
if os.path.isdir(file):
@@ -224,27 +228,26 @@ async def main():
224228

225229
if hashlib.sha256(entry["script"].encode("utf-8")).digest() \
226230
!= hashlib.sha256(file_content.encode("utf-8")).digest():
227-
_state = force
228-
if not _state:
229-
_state = click.confirm(f"Content of {file} changed. Overwrite?")
231+
can_push = force
232+
if not can_push:
233+
can_push = click.confirm(f"Content of {file} changed. Overwrite?")
230234

231-
if _state:
235+
if can_push:
232236
click.echo(f"Push {_real_file}")
233237
await tree.edit(_type, entry["key"], {
234238
"script": file_content
235239
})
236240

237241
except StopAsyncIteration:
238-
_state = False
239242
text = "folder"
240243
if _type == "leaf":
241244
text = "file"
242245

243-
_state = force
244-
if not _state:
245-
_state = click.confirm(f"There is no {text} named {file}. Create it?")
246+
can_push = force
247+
if not can_push:
248+
can_push = click.confirm(f"There is no {text} named {file}. Create it?")
246249

247-
if _state:
250+
if can_push:
248251
root_node_entry = (await tree.list_root_nodes())[0]
249252

250253
if not parent.endswith("/"):
@@ -286,6 +289,53 @@ async def main():
286289
click.echo(f"Push {_real_file}")
287290
await tree.add(_type, args)
288291

292+
293+
294+
if watch:
295+
print("Watching...")
296+
def watch_loop():
297+
from watchdog.events import RegexMatchingEventHandler
298+
from watchdog.observers import Observer
299+
import time
300+
modified_files = {}
301+
def on_modified(event):
302+
# check for tmp file
303+
if event.src_path.endswith("~"):
304+
return
305+
if event.src_path not in modified_files:
306+
modified_files[event.src_path] = os.path.getmtime(event.src_path)
307+
elif os.path.getmtime(event.src_path) == modified_files[event.src_path]:
308+
return
309+
modified_files[event.src_path] = os.path.getmtime(event.src_path)
310+
asyncio.new_event_loop().run_until_complete(main(event.src_path))
311+
312+
313+
regexes = [r".*\.py"]
314+
ignore_regexes = []
315+
ignore_directories = True
316+
case_sensitive = False
317+
event_handler = RegexMatchingEventHandler(
318+
regexes=regexes,
319+
ignore_regexes=ignore_regexes,
320+
ignore_directories=ignore_directories,
321+
case_sensitive=case_sensitive
322+
)
323+
event_handler.on_modified = on_modified
324+
325+
326+
327+
observer = Observer()
328+
observer.schedule(event_handler, Config().get("working_dir"), recursive=True)
329+
observer.start()
330+
try:
331+
while True:
332+
time.sleep(1)
333+
finally:
334+
observer.stop()
335+
observer.join()
336+
337+
asyncio.new_event_loop().run_until_complete(watch_loop())
338+
return
289339
asyncio.new_event_loop().run_until_complete(main())
290340

291341

0 commit comments

Comments
 (0)