@@ -27,7 +27,6 @@ def __init__(self, repos_path, repos):
2727 """
2828 self .repos_path = repos_path
2929 self .repos = repos
30- #logger.info(repos)
3130
3231 logger .debug (f"Repos path for Index: { self .repos_path } " )
3332 self .index_files = {
@@ -152,7 +151,64 @@ def get_item_mtime(self,file):
152151 if t > latest :
153152 latest = t
154153 return latest
155-
154+
155+ def _index_single_repo (self , repo , repos_changed = False , current_item_keys = None ):
156+ repo_path = repo .path
157+ if not os .path .isdir (repo_path ):
158+ return False
159+
160+ changed = False
161+
162+ for folder_type in ["script" , "cache" , "experiment" ]:
163+ folder_path = os .path .join (repo_path , folder_type )
164+ if not os .path .isdir (folder_path ):
165+ continue
166+
167+ for automation_dir in os .listdir (folder_path ):
168+ automation_path = os .path .join (folder_path , automation_dir )
169+ if not os .path .isdir (automation_path ):
170+ continue
171+
172+ yaml_path = os .path .join (automation_path , "meta.yaml" )
173+ json_path = os .path .join (automation_path , "meta.json" )
174+
175+ if os .path .isfile (yaml_path ):
176+ config_path = yaml_path
177+ elif os .path .isfile (json_path ):
178+ config_path = json_path
179+ else :
180+ #logger.debug(f"No config file found in {automation_path}, skipping")
181+ delete_flag = False
182+ if automation_dir in self .modified_times :
183+ del self .modified_times [automation_dir ]
184+ if any (automation_dir in item ["path" ] for item in self .indices [folder_type ]):
185+ logger .debug (f"Removed index entry (if it exists) for { folder_type } : { automation_dir } " )
186+ delete_flag = True
187+ self ._remove_index_entry (automation_path )
188+ if delete_flag :
189+ self ._save_indices ()
190+ continue
191+ if current_item_keys is not None :
192+ current_item_keys .add (config_path )
193+ mtime = self .get_item_mtime (config_path )
194+ old = self .modified_times .get (config_path )
195+ old_mtime = old ["mtime" ] if isinstance (old , dict ) else old
196+
197+ # skip if unchanged
198+ if old_mtime == mtime and repos_changed != 1 :
199+ continue
200+
201+ self .modified_times [config_path ] = {
202+ "mtime" : mtime ,
203+ "date_time" : datetime .fromtimestamp (mtime ).strftime ("%Y-%m-%d %H:%M:%S" )
204+ }
205+
206+ # meta file changed, so reindex
207+ self ._process_config_file (config_path , folder_type , automation_path , repo )
208+ changed = True
209+
210+ return changed
211+
156212 def build_index (self ):
157213 """
158214 Build shared indices for script, cache, and experiment folders across all repositories.
@@ -164,19 +220,15 @@ def build_index(self):
164220 # track all currently detected item paths
165221 current_item_keys = set ()
166222 changed = False
167- repos_changed = False
168-
169- # load existing modified times
223+ force_rebuild = False
224+
225+ # load modified times
170226 self .modified_times = self ._load_modified_times ()
171227
228+ # if missing index file, then force full rebuild
172229 index_json_path = os .path .join (self .repos_path , "index_script.json" )
173-
174- rebuild_index = False
175-
176- #file does not exist, rebuild
177230 if not os .path .exists (index_json_path ):
178231 logger .warning ("index_script.json missing. Forcing full index rebuild..." )
179- #logger.debug("Resetting modified_times...")
180232 self .modified_times = {}
181233 self ._save_modified_times ()
182234 #else:
@@ -211,6 +263,7 @@ def build_index(self):
211263 #else:
212264 # logger.debug("Repos.json not modified")
213265
266+ # index each repo
214267 for repo in self .repos :
215268 repo_path = repo .path #os.path.join(self.repos_path, repo)
216269 if not os .path .isdir (repo_path ):
@@ -287,8 +340,7 @@ def build_index(self):
287340 self ._process_config_file (config_path , folder_type , automation_path , repo )
288341
289342 # remove deleted scripts
290- old_keys = set (self .modified_times .keys ())
291- deleted_keys = old_keys - current_item_keys
343+ deleted_keys = set (self .modified_times ) - current_item_keys
292344 for key in deleted_keys :
293345 logger .warning (f"Detected deleted item, removing entry from modified times: { key } " )
294346 del self .modified_times [key ]
@@ -299,13 +351,10 @@ def build_index(self):
299351 if deleted_keys :
300352 logger .debug (f"Deleted keys removed from modified times and indices: { deleted_keys } " )
301353
302- if changed :
354+ if force_rebuild or changed :
303355 logger .debug ("Changes detected, saving updated index and modified times." )
304356 self ._save_modified_times ()
305357 self ._save_indices ()
306- #logger.debug("**************Index updated (changes detected).*************************")
307- #else:
308- #logger.debug("**************Index unchanged (no changes detected).********************")
309358
310359 def _remove_index_entry (self , key ):
311360 logger .debug (f"Removing index entry for { key } " )
@@ -399,3 +448,48 @@ def _save_indices(self):
399448 #logger.debug(f"Shared index for {folder_type} saved to {output_file}.")
400449 except Exception as e :
401450 logger .error (f"Error saving shared index for { folder_type } : { e } " )
451+
452+
453+ def add_repo (self , repo ):
454+ """
455+ Incrementally index a newly registered repository.
456+ """
457+ changed = self ._index_single_repo (repo , repos_changed = True )
458+
459+ if changed :
460+ self ._save_indices ()
461+ self ._save_modified_times ()
462+
463+
464+ def remove_repo_from_index (self , repo_path ):
465+ """
466+ Remove all index entries and modified times belonging to a repo.
467+ Called when a repo is unregistered from repos.json.
468+ """
469+
470+ logger .info (f"Removing repo from index: { repo_path } " )
471+ changed = False
472+
473+ # remove index entries
474+ for folder_type in self .indices :
475+ before = len (self .indices [folder_type ])
476+ self .indices [folder_type ] = [
477+ item for item in self .indices [folder_type ]
478+ if not item ["path" ].startswith (repo_path )
479+ ]
480+ if len (self .indices [folder_type ]) != before :
481+ changed = True
482+
483+ # remove modified times
484+ keys_to_delete = [
485+ k for k in self .modified_times
486+ if k .startswith (repo_path )
487+ ]
488+
489+ for k in keys_to_delete :
490+ del self .modified_times [k ]
491+ changed = True
492+
493+ if changed :
494+ self ._save_indices ()
495+ self ._save_modified_times ()
0 commit comments