1616 BaseModel ,
1717 ConfigDict ,
1818 Field ,
19+ TypeAdapter ,
1920 model_validator ,
2021)
2122
@@ -443,6 +444,36 @@ def _sync_pydantic(
443444
444445
445446SyncModel = Annotated [RsyncModel | S3SyncModel | GitModel , Field (discriminator = "type" )]
447+ sync_model_adapter = TypeAdapter (SyncModel )
448+
449+
450+ def _get_sync_protocol (sync : dict [str , dict | SyncABC ], protocol : str | None ) -> SyncModel :
451+ """
452+ Get the sync protocol model from the provided dictionary.
453+
454+ Args:
455+ sync: A dictionary of sync protocols, where the keys are protocol names and
456+ the values are `SyncModel` instances or dictionaries that can be validated
457+ into a `SyncModel`.
458+ protocol: The name of the protocol to retrieve. If `None`, the first protocol
459+ in the dictionary will be used.
460+
461+ Returns:
462+ The sync protocol model corresponding to the provided protocol name.
463+
464+ Raises:
465+ ValueError: If the specified protocol is not found in the dictionary.
466+ """
467+ protocol_names = sync .keys ()
468+ target_protocol = protocol_names [0 ] if protocol is None else protocol
469+ if (sync_model := sync .get (target_protocol )) is None :
470+ raise ValueError (
471+ f"Protocol '{ target_protocol } ' not found, available protocols are: "
472+ f"{ ', ' .join (protocol_names )} ."
473+ )
474+ if not issubclass (sync_model , SyncABC ):
475+ sync_model = sync_model_adapter .validate_python (sync_model )
476+ return sync_model
446477
447478
448479class SyncProtocols (SyncABC ):
@@ -465,26 +496,12 @@ def _sync_pydantic(
465496 if not self .sync :
466497 logger .info ("No protocols to sync." )
467498 return run (["echo" , "No protocols to sync" ], check = True )
468- target_protocol = (
469- sync_options .protocol if sync_options .protocol else list (self .sync .keys ())[0 ]
470- )
471- logger .debug ("Resolved protocol: %s." , str (target_protocol ))
472- if proto := self .sync .get (target_protocol ):
473- logger .info ("Executing protocol: %s." , str (proto ))
474- return proto .execute (sync_options , verbosity )
475- logger .error (
476- "Protocol '%s' not found, available protocols are: %s." ,
477- target_protocol ,
478- ", " .join (self .sync .keys ()),
479- )
480- return run (
481- [
482- "echo" ,
483- f"Protocol '{ target_protocol } ' not found, available "
484- f"protocols are: { ', ' .join (self .sync .keys ())} ." ,
485- ],
486- check = True ,
487- )
499+ try :
500+ sync_model = _get_sync_protocol (self .sync , sync_options .protocol )
501+ except ValueError as e :
502+ logger .critical (str (e ))
503+ return run (["echo" , str (e )], check = True )
504+ return sync_model .execute (sync_options , verbosity )
488505
489506
490507def sync_from_yaml (
0 commit comments