diff --git a/data/ecss-template/ecss-e-st-40c_4_1_software_static_architecture.tmplt b/data/ecss-template/ecss-e-st-40c_4_1_software_static_architecture.tmplt index e4a5689..2843db5 100644 --- a/data/ecss-template/ecss-e-st-40c_4_1_software_static_architecture.tmplt +++ b/data/ecss-template/ecss-e-st-40c_4_1_software_static_architecture.tmplt @@ -1,4 +1,36 @@ <% +import os +import subprocess + +## Generate Interface View diagram +_iv_xml = interface_view_path if interface_view_path else None + +iv_diagram_path = None +if _iv_xml: + _iv_image_filename = "iv_logical_architecture.png" + _original_dir = os.getcwd() + _abs_output_dir = os.path.abspath(output_directory) if output_directory else None + try: + _abs_iv_xml = os.path.abspath(_iv_xml) + _result = subprocess.run( + ["spacecreator.AppImage", "--diagramexporter", + "--interfaceview-path", _abs_iv_xml, + "--image-path", _iv_image_filename], + check=False, + capture_output=True + ) + if _result.returncode == 0 and os.path.exists(_iv_image_filename): + if _abs_output_dir and os.path.exists(_abs_output_dir): + import shutil + shutil.copy2(_iv_image_filename, os.path.join(_abs_output_dir, _iv_image_filename)) + os.remove(_iv_image_filename) + iv_diagram_path = _iv_image_filename + else: + _abs_img = os.path.abspath(_iv_image_filename) + iv_diagram_path = os.path.relpath(_abs_img, _original_dir) + except Exception: + pass + ## Data Initialization # Get all functions @@ -56,6 +88,13 @@ for func in deployed_funcs: The software architecture of ${target_partition_name} consists of ${len(deployed_funcs)} functions deployed onto ${target_node.name} node. The functions use the following implementation technologies: ${",".join([l.value for l in languages])}. +% if iv_diagram_path: + +The logical architecture is presented in the Figure below: + +![Logical architecture](${iv_diagram_path} "Logical architecture") + +% endif The top-level components are as follows: % for func in interface_view.functions: <% diff --git a/templateprocessor/cli.py b/templateprocessor/cli.py index 908bbdc..9dc8ce3 100644 --- a/templateprocessor/cli.py +++ b/templateprocessor/cli.py @@ -219,7 +219,15 @@ def main(): values = get_values_dictionary(args.value) logging.info(f"Instantiating the TemplateInstantiator") - instantiator = TemplateInstantiator(iv, dv, sots, values, args.output) + instantiator = TemplateInstantiator( + iv, + dv, + sots, + values, + args.output, + interface_view_path=args.iv or "", + deployment_view_path=args.dv or "", + ) logging.info(f"Instantiating the Postprocessor") postprocessor = Postprocessor( diff --git a/templateprocessor/templateinstantiator.py b/templateprocessor/templateinstantiator.py index 3ab6d4d..2e3cb9d 100644 --- a/templateprocessor/templateinstantiator.py +++ b/templateprocessor/templateinstantiator.py @@ -21,6 +21,8 @@ class TemplateInstantiator: interface_view: InterfaceView deployment_view: DeploymentView output_directory: str + interface_view_path: str + deployment_view_path: str def __init__( self, @@ -29,12 +31,16 @@ def __init__( system_object_types: Dict[str, SystemObjectType], values: Dict[str, str], output_directory: str = "", + interface_view_path: str = "", + deployment_view_path: str = "", ): self.system_object_types = system_object_types self.interface_view = interface_view self.deployment_view = deployment_view self.values = values self.output_directory = output_directory + self.interface_view_path = interface_view_path + self.deployment_view_path = deployment_view_path def instantiate(self, template: str, context_directory: str) -> str: mako_template = Template(text=template, module_directory=context_directory) @@ -45,6 +51,8 @@ def instantiate(self, template: str, context_directory: str) -> str: "deployment_view": self.deployment_view, "values": self.values, "output_directory": self.output_directory, + "interface_view_path": self.interface_view_path, + "deployment_view_path": self.deployment_view_path, } instantiated_text = str(mako_template.render(**context)) diff --git a/tests/test_templateinstantiator.py b/tests/test_templateinstantiator.py index e11ca52..67de2d3 100644 --- a/tests/test_templateinstantiator.py +++ b/tests/test_templateinstantiator.py @@ -554,3 +554,77 @@ def test_instantiate_template_with_values(self): assert "Version: 2.1.0" in result assert "Author: Test Author" in result assert "Description: Test project description" in result + + def test_interface_view_path_stored(self): + """interface_view_path passed to constructor is stored on the instantiator.""" + iv = self.create_sample_interface_view() + dv = self.create_sample_deployment_view() + so_types = self.create_sample_system_object_types() + + instantiator = TemplateInstantiator( + iv, + dv, + so_types, + {}, + interface_view_path="/path/to/interfaceview.xml", + ) + + assert instantiator.interface_view_path == "/path/to/interfaceview.xml" + + def test_deployment_view_path_stored(self): + """deployment_view_path passed to constructor is stored on the instantiator.""" + iv = self.create_sample_interface_view() + dv = self.create_sample_deployment_view() + so_types = self.create_sample_system_object_types() + + instantiator = TemplateInstantiator( + iv, + dv, + so_types, + {}, + deployment_view_path="/path/to/deploymentview.dv.xml", + ) + + assert instantiator.deployment_view_path == "/path/to/deploymentview.dv.xml" + + def test_interface_view_path_available_in_template(self): + """interface_view_path is accessible as a variable inside templates.""" + iv = self.create_sample_interface_view() + dv = self.create_sample_deployment_view() + so_types = self.create_sample_system_object_types() + + instantiator = TemplateInstantiator( + iv, + dv, + so_types, + {}, + interface_view_path="/some/project/interfaceview.xml", + ) + + template = "IV path: ${interface_view_path}" + + with tempfile.TemporaryDirectory() as tmpdir: + result = instantiator.instantiate(template, tmpdir) + + assert result == "IV path: /some/project/interfaceview.xml" + + def test_deployment_view_path_available_in_template(self): + """deployment_view_path is accessible as a variable inside templates.""" + iv = self.create_sample_interface_view() + dv = self.create_sample_deployment_view() + so_types = self.create_sample_system_object_types() + + instantiator = TemplateInstantiator( + iv, + dv, + so_types, + {}, + deployment_view_path="/some/project/deploymentview.dv.xml", + ) + + template = "DV path: ${deployment_view_path}" + + with tempfile.TemporaryDirectory() as tmpdir: + result = instantiator.instantiate(template, tmpdir) + + assert result == "DV path: /some/project/deploymentview.dv.xml"