Source code for vsgen.writer

# -*- coding: utf-8 -*-
"""
This module provides a simple multi-threaded writer utility for VSGProjects and VSGSolutions
"""
import os
import sys
import time
import threading
import itertools
import jinja2
import errno


[docs]class VSGJinjaRenderer(object): """ A class defining methods interacting with `Jinja2 <http://jinja.pocoo.org/>`_. """
[docs] def render(self, template, filename, context={}, filters={}): """ Renders a Jinja2 template to text. """ filename = os.path.normpath(filename) path, file = os.path.split(filename) try: os.makedirs(path) except OSError as exception: if exception.errno != errno.EEXIST: raise path, file = os.path.split(template) loader = jinja2.FileSystemLoader(path) env = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True) env.filters.update(filters) template = env.get_template(file) text = template.render(context) with open(filename, 'wt') as f: f.write(text)
[docs]class VSGWritable(object): """ An interface class defining methods necessary for VSGWriter """ __writable_name__ = "Unknown Writable"
[docs] def write(self): """ Interface method to 'write' the object. """ raise NotImplementedError("Should have implemented this")
[docs] def text(self, value): """ Converts a value to text in a way compatible with Python2 and Python 3. :param object value: The value to convert. :return: The value as text. """ return unicode(value) if sys.version_info < (3,) else str(value)
[docs] def upper(self, value): """ Converts a value to upper case text in a way compatible with Python2 and Python 3. :param object value: The value to convert. :return: The value as upper case text. """ return self.text(value).upper()
[docs] def lower(self, value): """ Converts a value to lower case in a way compatible with Python2 and Python 3. :param object value: The value to convert. :return: The value as lower case text. """ return self.text(value).lower()
[docs]class VSGWriteCommand(object): """ The VSGWriteCommand class presents a simple command object to execute the writing methods of a collection of VSGWritable objects. """ def __init__(self, logname, writables, parallel=True): """ Initializes the instance with an default values. :param str logname: The python logger log name. :param list writables: The list of VSGWritable class instances. :param bool parallel: Flag to enable asynchronous writing. """ self._logname = logname self._writables = writables self._parallel = parallel writables_names = set([w.__writable_name__ for w in writables]) if not writables_names: self._message = "Writing no files." elif len(writables_names) == 1: self._message = "Writing {0}{1}".format(next(iter(writables_names)), 's' if len(writables) > 1 else '') else: self._message = "Writing a mixed collection of files." def __enter__(self): """ Enter the runtime context related to this object. """ return self def __exit__(self, exc_type, exc_value, exc_traceback): """ Exit the runtime context related to this object. """ # Only return True to surpress the exception (if any) return False
[docs] def execute(self): """ Executes the command. """ from vsgen.util.logger import VSGLogger VSGLogger.info(self._logname, self._message) start = time.clock() VSGWriter.write(self._writables, self._parallel) end = time.clock() VSGLogger.info(self._logname, "Wrote %s files in %s seconds:", len(self._writables), end - start)
[docs]class VSGWriter(threading.Thread): """ VSGWriter encapsulates the logic needed to write any VSG object to disk. """ def __init__(self, pylist): """ VSGProject encapsulates the logic needed to create a *.pyproject file. :param list pylist: A list of VSG objects[PrProjects, VSGSolutions, etc] """ threading.Thread.__init__(self) if not hasattr(pylist, '__iter__'): self._pylist = [pylist] else: self._pylist = pylist
[docs] def run(self): """ The Thread's execution function. """ for pyitem in self._pylist: pyitem.write()
[docs] @staticmethod def write(pylist, parallel=True): """ Utility method to spawn a VSGWriter for each element in a collection. :param list pylist: A list of VSG objects (PrProjects, VSGSolutions, etc) :param bool parallel: Flag to enable asynchronous writing. """ threads = [VSGWriter(o) for o in pylist] if parallel: for t in threads: t.start() for t in threads: t.join() else: for t in threads: t.run()