File indexing completed on 2024-11-17 05:06:40
0001 import sys 0002 from pathlib import Path 0003 sys.path.append(str(Path(__file__).parent.resolve()) + "/../../site-packages/") 0004 0005 from pathlib import Path 0006 import jinja2 0007 0008 # Template files are read globally so it's contents can be shared between calls 0009 with open(Path(__file__).parent.resolve() / 'cmakelists_root.template', 'r') as f: 0010 CMAKELISTS_ROOT_TEMPLATE = f.read() 0011 with open(Path(__file__).parent.resolve() / 'cmakelists_pkg_group.template', 'r') as f: 0012 CMAKELISTS_PKG_GROUP_TEMPLATE = f.read() 0013 with open(Path(__file__).parent.resolve() / 'cmakelists_pkg.template', 'r') as f: 0014 CMAKELISTS_PKG_TEMPLATE = f.read() 0015 with open(Path(__file__).parent.resolve() / 'headerfile.template', 'r') as f: 0016 HEADER_TEMPLATE = f.read() 0017 with open(Path(__file__).parent.resolve() / 'sourcefile.template', 'r') as f: 0018 SOURCE_TEMPLATE = f.read() 0019 0020 0021 def _writeTemplateFile(template, build_data, output_file): 0022 ''' 0023 Helper function for writing contents from a given template file 0024 ''' 0025 with open(Path(output_file), 'w') as outfile: 0026 outfile.write(jinja2.Template(template).render(build_data)) 0027 0028 0029 def buildPkgGroup(pkg_group, output_dir, user_ctx): 0030 ''' 0031 Ensures the given package group exists in the filesystem 0032 ''' 0033 pkg_group_dir = f'{output_dir}/{pkg_group.name()}' 0034 Path(pkg_group_dir).mkdir(parents=True, exist_ok=True) 0035 0036 user_ctx['root_entities'].append(pkg_group) 0037 0038 build_data = { 0039 'pkgs': pkg_group.children(), 0040 } 0041 0042 _writeTemplateFile(CMAKELISTS_PKG_GROUP_TEMPLATE, build_data, f'{pkg_group_dir}/CMakeLists.txt') 0043 0044 0045 def buildPkg(pkg, output_dir, user_ctx): 0046 ''' 0047 Ensures the given package exists in the filesystem and create its basic structure 0048 ''' 0049 pkg_group = pkg.parent() 0050 if pkg_group: 0051 pkg_dir = f'{output_dir}/{pkg_group.name()}/{pkg.name()}' 0052 else: 0053 pkg_dir = f'{output_dir}/{pkg.name()}' 0054 Path(pkg_dir).mkdir(parents=True, exist_ok=True) 0055 0056 build_data = { 0057 'pkg': pkg, 0058 'deps': [ 0059 dep for dep in pkg.forwardDependencies() 0060 if not _isNonLakosianDependency(dep) 0061 ], 0062 } 0063 0064 _writeTemplateFile(CMAKELISTS_PKG_TEMPLATE, build_data, f'{pkg_dir}/CMakeLists.txt') 0065 if pkg_group is None: 0066 user_ctx['root_entities'].append(pkg) 0067 0068 0069 def _isNonLakosianDependency(entity): 0070 if entity.type() == pycgn.DiagramType.PackageGroup: 0071 return entity.name() == 'non-lakosian group' 0072 if entity.parent(): 0073 return _isNonLakosianDependency(entity.parent()) 0074 return False 0075 0076 0077 def buildComponent(component, output_dir, user_ctx): 0078 ''' 0079 Build the C++ component in the filesystem with header, source and test files 0080 ''' 0081 pkg = component.parent() 0082 assert pkg, f"Package for entity {component.name()} not found." 0083 pkg_group = pkg.parent() 0084 if pkg_group: 0085 pkg_dir = f'{output_dir}/{pkg_group.name()}/{pkg.name()}' 0086 else: 0087 pkg_dir = f'{output_dir}/{pkg.name()}' 0088 component_basename = f'{pkg_dir}/{component.name()}' 0089 0090 build_data = { 0091 'component_name': component.name(), 0092 'package_name': pkg.name(), 0093 'component_fwd_dependencies': [ 0094 dep.name() for dep in component.forwardDependencies() 0095 if not _isNonLakosianDependency(dep) 0096 ], 0097 'should_generate_namespace': pkg.name().isalnum(), 0098 } 0099 0100 _writeTemplateFile(HEADER_TEMPLATE, build_data, component_basename + '.h') 0101 _writeTemplateFile(SOURCE_TEMPLATE, build_data, component_basename + '.cpp') 0102 0103 0104 def beforeProcessEntities(output_dir, user_ctx): 0105 user_ctx['root_entities'] = [] 0106 0107 0108 def buildPhysicalEntity(pycgn_module, entity, output_dir, user_ctx): 0109 ''' 0110 API called from DiagramViewer software. 0111 See software docs for details. 0112 ''' 0113 global pycgn 0114 pycgn = pycgn_module 0115 0116 BUILD_DISPATCH = { 0117 pycgn.DiagramType.PackageGroup: buildPkgGroup, 0118 pycgn.DiagramType.Package: buildPkg, 0119 pycgn.DiagramType.Component: buildComponent 0120 } 0121 run = BUILD_DISPATCH.get(entity.type(), lambda _1, _2, _3: None) 0122 run(entity, output_dir, user_ctx) 0123 0124 0125 def afterProcessEntities(output_dir, user_ctx): 0126 build_data = { 0127 'root_entities': user_ctx['root_entities'], 0128 } 0129 0130 _writeTemplateFile(CMAKELISTS_ROOT_TEMPLATE, build_data, f'{output_dir}/CMakeLists.txt')