Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,4 @@
intersphinx_mapping.update({
})

master_doc = "index"
master_doc = "index"
5 changes: 5 additions & 0 deletions moban/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
LABEL_SOURCE = "source"
LABEL_DEST = "destination"
LABEL_FORCE_TEMPLATE_TYPE = "force_template_type"
LABEL_TEMPLATE_TYPES = "template_types"

# error messages
ERROR_DATA_FILE_NOT_FOUND = "Both %s and %s does not exist"
Expand Down Expand Up @@ -98,6 +99,10 @@
PYPI_PACKAGE_NAME = "name"
REQUIRE_TYPE = "type"

# Template types
TEMPLATE_TYPES_BASE_TYPE = "base_type"
TEMPLATE_TYPES_OPTIONS = "options"
TEMPLATE_TYPES_FILE_EXTENSIONS = "file_extensions"

# Extension
JINJA_FILTER_EXTENSION = "jinja_filter"
Expand Down
15 changes: 10 additions & 5 deletions moban/jinja2/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def __init__(self):
constants.TEMPLATE_ENGINE_EXTENSION, tags=["jinja2", "jinja", "jj2", "j2"]
)
class Engine(object):
def __init__(self, template_dirs, extensions=None):
def __init__(self, template_dirs, options=None):
"""
Contruct a jinja2 template engine

Expand All @@ -73,10 +73,15 @@ def __init__(self, template_dirs, extensions=None):
extension for extension in JINJA2_THIRD_PARTY_EXTENSIONS
], # get a copy of this global variable
)
if is_extension_list_valid(extensions):
# because it is modified here
env_params["extensions"] += extensions
import_module_of_extension(extensions)
if options:
if "extensions" in options:
extensions = options.pop("extensions")
if is_extension_list_valid(extensions):
# because it is modified here
env_params["extensions"] += extensions
import_module_of_extension(extensions)

env_params.update(options)
self.jj2_environment = Environment(**env_params)
for filter_name, filter_function in FILTERS.get_all():
self.jj2_environment.filters[filter_name] = filter_function
Expand Down
6 changes: 6 additions & 0 deletions moban/mobanfile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ def handle_moban_file_v1(moban_file_configurations, command_line_options):
if extensions:
plugins.ENGINES.register_extensions(extensions)

template_types = moban_file_configurations.get(
constants.LABEL_TEMPLATE_TYPES
)
if template_types:
plugins.ENGINES.register_options(template_types)

if targets:
if target:
targets = target
Expand Down
39 changes: 28 additions & 11 deletions moban/plugins/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,52 @@ class MobanFactory(PluginManager):
def __init__(self):
super(MobanFactory, self).__init__(constants.TEMPLATE_ENGINE_EXTENSION)
self.extensions = {}
self.options_registry = {}

def register_extensions(self, extensions):
self.extensions.update(extensions)

def register_options(self, template_types):
# need the value of 'template_types'
# see test_get_user_defined_engine for help
self.options_registry.update(template_types)

def get_engine(self, template_type, template_dirs, context_dirs):
engine_cls = self.load_me_now(template_type)
engine_extensions = self.extensions.get(template_type)
return MobanEngine(
template_dirs, context_dirs, engine_cls, engine_extensions
)
if template_type in self.options_registry:
custom_engine_spec = self.options_registry[template_type]
engine_cls = self.load_me_now(
custom_engine_spec[constants.TEMPLATE_TYPES_BASE_TYPE]
)
options = custom_engine_spec[constants.TEMPLATE_TYPES_OPTIONS]
else:
engine_cls = self.load_me_now(template_type)
engine_extensions = self.extensions.get(template_type)
options = dict(extensions=engine_extensions)
engine = engine_cls(template_dirs, options)
return MobanEngine(template_dirs, context_dirs, engine)

def get_primary_key(self, template_type):
for key, item in self.options_registry.items():
if template_type in item[constants.TEMPLATE_TYPES_FILE_EXTENSIONS]:
return key

return super(MobanFactory, self).get_primary_key(template_type)

def all_types(self):
return list(self.registry.keys())
return list(self.registry.keys()) + list(self.options_registry.keys())

def raise_exception(self, key):
raise exceptions.NoThirdPartyEngine(key)


class MobanEngine(object):
def __init__(
self, template_dirs, context_dirs, engine_cls, engine_extensions=None
):
def __init__(self, template_dirs, context_dirs, engine):
template_dirs = list(expand_template_directories(template_dirs))
utils.verify_the_existence_of_directories(template_dirs)
context_dirs = expand_template_directory(context_dirs)
self.context = Context(context_dirs)
self.template_dirs = template_dirs
self.engine = engine_cls(self.template_dirs, engine_extensions)
self.engine_cls = engine_cls
self.engine = engine
self.templated_count = 0
self.file_count = 0

Expand Down
10 changes: 10 additions & 0 deletions tests/fixtures/mobanengine/sample_template_type.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
template_types:
custom_jinja:
base_type: jinja2 # use base_type, instead of overrides
file_extensions:
- moban
- new
- demo_file_suffix
options:
extensions:
- jinja2.ext.do
4 changes: 2 additions & 2 deletions tests/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def test_expand_repo_dir(_, __):

def test_default_template_type():
engine = ENGINES.get_engine("jj2", [], "")
assert engine.engine_cls == Engine
assert engine.engine.__class__ == Engine


class FakeEngine:
Expand All @@ -53,7 +53,7 @@ def __init__(self, template_dirs, extensions=None):
@patch("lml.plugin.PluginManager.load_me_now", return_value=FakeEngine)
def test_default_mako_type(_): # fake mako
engine = ENGINES.get_engine("fake", [], "")
assert engine.engine_cls.__name__ == "FakeEngine"
assert engine.engine.__class__ == FakeEngine


@raises(exceptions.NoThirdPartyEngine)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_jinja2_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def test_globals():
test_dict = dict(hello="world")
jinja_global("test", test_dict)
path = os.path.join("tests", "fixtures", "globals")
engine = MobanEngine([path], path, Engine)
engine = MobanEngine([path], path, Engine([path]))
engine.render_to_file("basic.template", "basic.yml", output)
with open(output, "r") as output_file:
content = output_file.read()
Expand Down
33 changes: 33 additions & 0 deletions tests/test_template.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import os

from mock import patch
from nose.tools import eq_

from moban.plugins import ENGINES
from moban.definitions import TemplateTarget
from moban.jinja2.engine import Engine
from moban.data_loaders.yaml import open_yaml

MODULE = "moban.plugins.template"

Expand Down Expand Up @@ -80,3 +83,33 @@ def test_do_templates_with_more_shared_data():
content = f.read()
assert content == "hello world ox"
os.unlink("test")


def test_get_user_defined_engine():
test_fixture = os.path.join(
"tests", "fixtures", "mobanengine", "sample_template_type.yml"
)
template_types = open_yaml(test_fixture)
ENGINES.register_options(template_types["template_types"])
engine = ENGINES.get_engine("custom_jinja", ".", ".")
eq_(engine.engine.__class__, Engine)


def test_custom_file_extension_is_assocated_with_user_defined_engine():
test_fixture = os.path.join(
"tests", "fixtures", "mobanengine", "sample_template_type.yml"
)
template_types = open_yaml(test_fixture)
ENGINES.register_options(template_types["template_types"])
template_type = ENGINES.get_primary_key("demo_file_suffix")
eq_("custom_jinja", template_type)


def test_built_in_jinja2_file_extension_still_works():
test_fixture = os.path.join(
"tests", "fixtures", "mobanengine", "sample_template_type.yml"
)
template_types = open_yaml(test_fixture)
ENGINES.register_options(template_types["template_types"])
template_type = ENGINES.get_primary_key("jj2")
eq_("jinja2", template_type)