diff --git a/pyproject.toml b/pyproject.toml index 0830eb31..a0744efb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "splight-cli" -version = "4.6.0.dev2" +version = "4.6.0.dev3" description = "Splight Command Line Interface" authors = ["Splight Dev "] readme = "README.md" diff --git a/splight_cli/solution/importer.py b/splight_cli/solution/importer.py index 85790c70..80a150ad 100644 --- a/splight_cli/solution/importer.py +++ b/splight_cli/solution/importer.py @@ -6,6 +6,7 @@ Alert, Asset, Component, + ComponentObject, Function, RoutineObject, Secret, @@ -67,6 +68,9 @@ def import_element(self, element: ElementType, id: UUID) -> ImportResult: if element == ElementType.component: retrieved_elem.routines = RoutineObject.list(component_id=id) + retrieved_elem.component_objects = ComponentObject.list( + component_id=id + ) plan_import_elems = getattr(self._plan, f"{IMPORT_PREFIX}{element}s") plan_import_elems.append(retrieved_elem) diff --git a/splight_cli/solution/models.py b/splight_cli/solution/models.py index 62e5fdfc..b4e022a1 100644 --- a/splight_cli/solution/models.py +++ b/splight_cli/solution/models.py @@ -5,6 +5,7 @@ from splight_lib.models import ( Alert, Asset, + ComponentObject, File, Function, RoutineObject, @@ -23,6 +24,7 @@ class ElementType(str, Enum): class Component(LibComponent): routines: List[RoutineObject] = [] + component_objects = List[ComponentObject] = [] class PlanSolution(BaseModel): diff --git a/splight_cli/solution/solution.py b/splight_cli/solution/solution.py index 6a46c97b..3f8e2d6a 100644 --- a/splight_cli/solution/solution.py +++ b/splight_cli/solution/solution.py @@ -9,6 +9,7 @@ Alert, Asset, Component, + ComponentObject, File, Function, RoutineObject, @@ -56,6 +57,7 @@ def __init__( self._regex_map = { Component.__name__: [ r"root\['routines'\]", + r"root\['custom_types'\]", r"root\['deployment_capacity'\]", r"root\['deployment_type'\]", ], @@ -66,6 +68,11 @@ def __init__( # NOTE: API returns the DataAddress type but we don't use it r"root\['(?:input|output)'\]\[\d+\]\['value'\]\['type'\]", ], + # TODO: revisar + ComponentObject.__name__: [ + r"root\['fields'\]\[\d+\]\['description'\]", + r"root\['description'\]", + ], File.__name__: [ r"root\['metadata'\]", r"root\['url'\]", @@ -237,12 +244,18 @@ def _plan_components_state(self): for state_component in components_list: self._plan_exec.plan_elem_state(Component, state_component) self._plan_routines_state(state_component) + self._plan_custom_objects_state(state_component) def _plan_routines_state(self, component: Component): """Shows the routines state if the plan were to be applied.""" for routine in component.routines: self._plan_exec.plan_elem_state(RoutineObject, routine) + def _plan_custom_objects_state(self, component: Component): + """Shows the component objects state if the plan were to be applied.""" + for obj in component.component_objects: + self._plan_exec.plan_elem_state(ComponentObject, obj) + def _plan_files_state(self): """Shows the files state if the plan were to be applied.""" files_list = self._state.files @@ -356,7 +369,11 @@ def _apply_components_state(self): updated_routines = self._apply_routines_state( component, Component.model_validate(result.updated_dict) ) + updated_component_objects = self._apply_component_objects_state( + component, Component.model_validate(result.updated_dict) + ) components_list[i].routines = updated_routines + components_list[i].component_objects = updated_component_objects save_yaml(self._state_path, self._state) imported_comp_list = self._state.imported_components @@ -378,6 +395,12 @@ def _apply_components_state(self): not_found_is_exception=True, ) imported_comp_list[i].routines = updated_routines + updated_component_objects = self._apply_component_objects_state( + component, + Component.model_validate(result.updated_dict), + not_found_is_exception=True, + ) + imported_comp_list[i].component_objects = updated_component_objects save_yaml(self._state_path, self._state) def _apply_routines_state( @@ -402,6 +425,28 @@ def _apply_routines_state( ) return routine_list + def _apply_component_objects_state( + self, + component: Component, + updated_component: Component, + not_found_is_exception: bool = False, + ) -> List[ComponentObject]: + """Applies ComponentObject states to the engine.""" + component_object_list = component.component_objects + component_id = updated_component.id + for i in range(len(component_object_list)): + component_object_list[i].component_id = component_id + result = self._apply_exec.apply( + model=ComponentObject, + local_instance=component_object_list[i], + not_found_is_exception=not_found_is_exception, + ) + if result.update: + component_object_list[i] = ComponentObject.model_validate( + result.updated_dict + ) + return component_object_list + def _apply_functions_state(self): """Applies Function states to the engine.""" functions_list = self._state.functions diff --git a/splight_cli/solution/solution_checker.py b/splight_cli/solution/solution_checker.py index 655ec854..3761d1f0 100644 --- a/splight_cli/solution/solution_checker.py +++ b/splight_cli/solution/solution_checker.py @@ -7,6 +7,7 @@ AlertItem, Asset, Attribute, + ComponentObject, File, Function, FunctionItem, @@ -321,6 +322,12 @@ def _update_component( self._update_routine, ) + self._check_elements( + plan_component.component_objects, + state_component.component_objects, + RoutineObject.__name__, + self._update_component_object, + ) return state_component def _update_routine( @@ -349,6 +356,36 @@ def _update_routine( return state_routine.model_validate(state_routine_dict) + def _update_component_object( + self, + plan_component_object: ComponentObject, + state_component_object: ComponentObject, + ) -> ComponentObject: + """Updates a state component_object based on the plan component_object. + + Parameters + ---------- + plan_component_object : ComponentObject + A plan component object. + state_component_object : ComponentObject + A state component object to update. + + Returns + ------- + ComponentObject + The updated state component object. + """ + plan_component_object_dict = plan_component_object.model_dump( + exclude_none=True, + exclude_unset=True, + ) + state_component_object_dict = state_component_object.model_dump() + state_component_object_dict.update(plan_component_object_dict) + + return state_component_object.model_validate( + state_component_object_dict + ) + def _update_function( self, plan_function: Function, state_function: Function ):