22import asyncio
33import datetime
44import importlib .util
5+ import json
56import os
67import signal
78import threading
@@ -220,7 +221,7 @@ def show(app_flow_specifier: str, color: bool, verbose: bool) -> None:
220221 console .print (table )
221222
222223
223- def _drop_flows (flows : Iterable [flow .Flow ], force : bool = False ) -> None :
224+ def _drop_flows (flows : Iterable [flow .Flow ], app_ref : str , force : bool = False ) -> None :
224225 """
225226 Helper function to drop flows without user interaction.
226227 Used internally by --reset flag
@@ -229,17 +230,29 @@ def _drop_flows(flows: Iterable[flow.Flow], force: bool = False) -> None:
229230 flows: Iterable of Flow objects to drop
230231 force: If True, skip confirmation prompts
231232 """
232- flows_list = list (flows )
233- if not flows_list :
233+ flow_full_names = ", " .join (fl .full_name for fl in flows )
234+ click .echo (
235+ f"Preparing to drop specified flows: { flow_full_names } (in '{ app_ref } ')." ,
236+ err = True ,
237+ )
238+
239+ if not flows :
240+ click .echo ("No flows identified for the drop operation." )
234241 return
235242
236- setup_bundle = flow .make_drop_bundle (flows_list )
243+ setup_bundle = flow .make_drop_bundle (flows )
237244 description , is_up_to_date = setup_bundle .describe ()
238-
245+ click . echo ( description )
239246 if is_up_to_date :
247+ click .echo ("No flows need to be dropped." )
248+ return
249+ if not force and not click .confirm (
250+ f"\n This will apply changes to drop setup for: { flow_full_names } . Continue? [yes/N]" ,
251+ default = False ,
252+ show_default = False ,
253+ ):
254+ click .echo ("Drop operation aborted by user." )
240255 return
241-
242- click .echo (description )
243256 setup_bundle .apply (report_to_stdout = True )
244257
245258
@@ -310,7 +323,7 @@ def setup(app_target: str, force: bool, reset: bool) -> None:
310323
311324 # If --reset is specified, drop existing setup first
312325 if reset :
313- _drop_flows (flow .flows ().values (), force = force )
326+ _drop_flows (flow .flows ().values (), app_ref = app_ref , force = force )
314327
315328 _setup_flows (flow .flows ().values (), force = force , always_show_setup = True )
316329
@@ -360,30 +373,7 @@ def drop(app_target: str | None, flow_name: tuple[str, ...], force: bool) -> Non
360373 else :
361374 flows = flow .flows ().values ()
362375
363- flow_full_names = ", " .join (fl .full_name for fl in flows )
364- click .echo (
365- f"Preparing to drop specified flows: { flow_full_names } (in '{ app_ref } ')." ,
366- err = True ,
367- )
368-
369- if not flows :
370- click .echo ("No flows identified for the drop operation." )
371- return
372-
373- setup_bundle = flow .make_drop_bundle (flows )
374- description , is_up_to_date = setup_bundle .describe ()
375- click .echo (description )
376- if is_up_to_date :
377- click .echo ("No flows need to be dropped." )
378- return
379- if not force and not click .confirm (
380- f"\n This will apply changes to drop setup for: { flow_full_names } . Continue? [yes/N]" ,
381- default = False ,
382- show_default = False ,
383- ):
384- click .echo ("Drop operation aborted by user." )
385- return
386- setup_bundle .apply (report_to_stdout = True )
376+ _drop_flows (flows , app_ref = app_ref , force = force )
387377
388378
389379@cli .command ()
@@ -450,15 +440,13 @@ def update(
450440 """
451441 app_ref , flow_name = _parse_app_flow_specifier (app_flow_specifier )
452442 _load_user_app (app_ref )
443+ flow_list = (
444+ [flow .flow_by_name (flow_name )] if flow_name else list (flow .flows ().values ())
445+ )
453446
454447 # If --reset is specified, drop existing setup first
455448 if reset :
456- if flow_name :
457- # Reset specific flow only
458- _drop_flows ([flow .flow_by_name (flow_name )], force = force )
459- else :
460- # Reset all flows
461- _drop_flows (flow .flows ().values (), force = force )
449+ _drop_flows (flow_list , app_ref = app_ref , force = force )
462450
463451 if live :
464452 click .secho (
@@ -471,19 +459,14 @@ def update(
471459 reexport_targets = reexport ,
472460 print_stats = not quiet ,
473461 )
462+ if reset or setup :
463+ _setup_flows (flow_list , force = force , quiet = quiet )
464+
474465 if flow_name is None :
475- if setup :
476- _setup_flows (
477- flow .flows ().values (),
478- force = force ,
479- quiet = quiet ,
480- )
481466 execution_context .run (_update_all_flows_with_hint_async (options ))
482467 else :
483- fl = flow .flow_by_name (flow_name )
484- if setup :
485- _setup_flows ((fl ,), force = force , quiet = quiet )
486- with flow .FlowLiveUpdater (fl , options ) as updater :
468+ assert len (flow_list ) == 1
469+ with flow .FlowLiveUpdater (flow_list [0 ], options ) as updater :
487470 updater .wait ()
488471 if options .live_mode :
489472 _show_no_live_update_hint ()
@@ -586,7 +569,7 @@ def evaluate(
586569 is_flag = True ,
587570 show_default = True ,
588571 default = False ,
589- help = "Drop existing setup before starting server (equivalent to running 'cocoindex drop' first)." ,
572+ help = "Drop existing setup before starting server (equivalent to running 'cocoindex drop' first). --reset implies --setup. " ,
590573)
591574@click .option (
592575 "--reexport" ,
@@ -648,12 +631,14 @@ def server(
648631 cors_cocoindex ,
649632 cors_local ,
650633 live_update ,
651- setup ,
652- reset ,
653634 reexport ,
654- force ,
655635 quiet ,
656636 )
637+ kwargs = {
638+ "run_reset" : reset ,
639+ "run_setup" : setup ,
640+ "force" : force ,
641+ }
657642
658643 if reload :
659644 watch_paths = {os .getcwd ()}
@@ -671,6 +656,7 @@ def server(
671656 * watch_paths ,
672657 target = _reloadable_server_target ,
673658 args = args ,
659+ kwargs = kwargs ,
674660 watch_filter = watchfiles .PythonFilter (),
675661 callback = lambda changes : click .secho (
676662 f"\n Detected changes in { len (changes )} file(s), reloading server...\n " ,
@@ -682,12 +668,19 @@ def server(
682668 "NOTE: Flow code changes will NOT be reflected until you restart to load the new code. Use --reload to enable auto-reload.\n " ,
683669 fg = "yellow" ,
684670 )
685- _run_server (* args )
671+ _run_server (* args , ** kwargs )
686672
687673
688674def _reloadable_server_target (* args : Any , ** kwargs : Any ) -> None :
689675 """Reloadable target for the watchfiles process."""
690676 _initialize_cocoindex_in_process ()
677+
678+ kwargs ["run_setup" ] = kwargs ["run_setup" ] or kwargs ["run_reset" ]
679+ changed_files = json .loads (os .environ .get ("WATCHFILES_CHANGES" , "[]" ))
680+ if changed_files :
681+ kwargs ["run_reset" ] = False
682+ kwargs ["force" ] = True
683+
691684 _run_server (* args , ** kwargs )
692685
693686
@@ -698,11 +691,13 @@ def _run_server(
698691 cors_cocoindex : bool = False ,
699692 cors_local : int | None = None ,
700693 live_update : bool = False ,
701- run_setup : bool = False ,
702- run_reset : bool = False ,
703694 reexport : bool = False ,
704- force : bool = False ,
705695 quiet : bool = False ,
696+ / ,
697+ * ,
698+ force : bool = False ,
699+ run_reset : bool = False ,
700+ run_setup : bool = False ,
706701) -> None :
707702 """Helper function to run the server with specified settings."""
708703 _load_user_app (app_ref )
@@ -728,7 +723,7 @@ def _run_server(
728723
729724 # If --reset is specified, drop existing setup first
730725 if run_reset :
731- _drop_flows (flow .flows ().values (), force = force )
726+ _drop_flows (flow .flows ().values (), app_ref = app_ref , force = force )
732727
733728 server_settings = setting .ServerSettings .from_env ()
734729 cors_origins : set [str ] = set (server_settings .cors_origins or [])
@@ -743,7 +738,7 @@ def _run_server(
743738 if address is not None :
744739 server_settings .address = address
745740
746- if run_setup :
741+ if run_reset or run_setup :
747742 _setup_flows (
748743 flow .flows ().values (),
749744 force = force ,
0 commit comments