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')