Source code for flow.template

# Copyright (c) 2018 The Regents of the University of Michigan
# All rights reserved.
# This software is licensed under the BSD 3-Clause License.
"""FlowProject module templates.

These templates can be initialized via the init() function defined
in this module and the main 'flow' command line interface.
"""
import errno
import logging
import os
import sys

import jinja2

logger = logging.getLogger(__name__)


TEMPLATES = {
    "minimal": [
        ("project.py", "project_minimal.pyt"),
    ],
    "example": [
        ("project.py", "project_example.pyt"),
    ],
    "testing": [
        ("project.py", "project_testing.pyt"),
    ],
}


[docs] def init(alias=None, template=None, path=None): """Initialize a templated :class:`~.FlowProject` module. Parameters ---------- alias : str Python identifier used as a file name for the template output. Uses ``"project"`` if None. (Default value = None) template : str Name of the template to use. Built-in templates are: * ``"minimal"`` * ``"example"`` * ``"testing"`` Uses ``"minimal"`` if None. (Default value = None) path : str Directory where the output file is placed. Uses the current working directory if None. (Default value = None) Returns ------- list List of file names created. """ if alias is None: alias = "project" elif not alias.isidentifier(): raise ValueError( f"The alias '{alias}' is not a valid Python identifier and therefore " "cannot be used as a FlowProject alias." ) if template is None: template = "minimal" if os.path.splitext(alias)[1]: raise RuntimeError("Please provide a name without suffix!") project_class_name = alias.capitalize() if not project_class_name.endswith("Project"): project_class_name += "Project" template_environment = jinja2.Environment( loader=jinja2.ChoiceLoader( [ jinja2.FileSystemLoader("templates"), jinja2.PackageLoader("flow", "templates"), ] ), trim_blocks=True, lstrip_blocks=True, ) context = {} context["alias"] = alias context["project_class_name"] = project_class_name # render all templates codes = {} for fn, fn_template in TEMPLATES[template]: fn_ = fn.format(alias=alias) # some of the filenames may depend on the alias template = template_environment.get_template(fn_template) codes[fn_] = template.render(**context) # create files files_created = [] for fn, code in codes.items(): try: if path is not None: fn = os.path.join(path, fn) with open(fn, "x") as fw: fw.write(code + "\n") except OSError as error: error_message = ( f"Error while creating FlowProject module with name '{alias}': " ) if error.errno == errno.EEXIST: error_message += f"a file named '{fn}' already exists!" else: error_message += f"'{error}'." raise OSError(error_message) else: files_created.append(fn) print(f"Created file '{fn}'.", file=sys.stderr) return files_created