Source code for l2tscaffolder.lib.mapping_helper

# -*- coding: utf-8 -*-
"""Helper methods for mapping."""
import os
import jinja2

from l2tscaffolder.lib import code_formatter


[docs]class MappingHelper: """Mapping helper for scaffolders.""" _DEFAULT_PATH_FORMATTER = '.style.yapf' _DEFAULT_PATH_TEMPLATE = 'templates' def __init__(self, template_path: str='', formatter_path: str=''): """Initializes the mapping helper class. Args: template_path (Optional[str]): file path to the templates diretory, relative to the path to the tool. If none provided will use the default path. formatter_path (Optional[str]): file path of the formatter, relative to the path to the tool. If none provided will use the default path. """ super(MappingHelper, self).__init__() # TODO: Improve this, this is flaky. self._tool_path = os.path.dirname( os.path.dirname(os.path.realpath(__file__))) if not template_path: template_path = self._DEFAULT_PATH_TEMPLATE # TODO: Check if the project has a YAPF config file and use that instead of # falling back to a default one. if not formatter_path: formatter_path = self._DEFAULT_PATH_FORMATTER full_template_path = os.path.join(self._tool_path, template_path) self._template_path = full_template_path template_loader = jinja2.FileSystemLoader(self._template_path) # TODO: Check if autoescape can be set to True due to potential XSS issues. self._template_environment = jinja2.Environment( autoescape=False, loader=template_loader, trim_blocks=False) full_formatter_path = os.path.join(self._tool_path, formatter_path) self.formatter = code_formatter.CodeFormatter(full_formatter_path) def _RemoveWhitespaceAtEndOfLine(self, template: str) -> str: """Removes blanks at the end of lines. This is for those parts that are ignored with yapf. Args: template (str): template to remove end-of-line whitespace from. Returns: str: template without end-of-line whitespace. """ while template.find(' \n') != -1: template = template.replace(' \n', '\n') return template def _RemoveEscapeError(self, template: str) -> str: """Removes the escape error. Because jinja template variable is first escaped and then word wrapped, the escaped backslash can be split and can result in an EOL. The escaped backslash will be placed on the next line. This is a workaround and can be removed if yapf supports unicode string formatting and it is also changed in the jinja2 template, and only works with 8 spaces. Args: template (str): the resulting template as a python file string Returns: str: the template without escape (eol) errors """ to_be_replaced = '\\\'\n u\'\\' to_be_replaced_with = '\'\n u\'\\\\' return template.replace(to_be_replaced, to_be_replaced_with) def _RemoveYapfComment(self, template: str) -> str: """Removes the yapf comment line. The line as well as the new line will be removed. The yapf comment has to be at the end of the line, or on its own line. Args: template (str): template to remove yapf comments from. Returns: str: template with yapf comments removed. """ return template.replace('# yapf: disable\n', '').replace( '# yapf: enable\n', '')
[docs] def GenerateClassName(self, scaffolder_name: str) -> str: """Generates a class name from the scaffolder name for file generation. Args: scaffolder_name (str): name of the scaffolder Returns: str: name of the class """ return scaffolder_name.replace('_', ' ').title().replace(' ', '')
[docs] def RenderTemplate(self, template_filename: str, context: dict) -> str: """Renders the template with the context to return a string. Args: template_filename (str): the name of the template context (dict): the context of the template as a dictionary Returns: str: the rendered template as a string """ template = self._template_environment.get_template( template_filename).render(context) template = self._RemoveEscapeError(template) formatted = self.formatter.Format(template)[0] formatted = self._RemoveYapfComment(formatted) formatted = self._RemoveWhitespaceAtEndOfLine(formatted) return formatted