From 08332c109b0faa05c2e06c39d020dcd56a9a6c10 Mon Sep 17 00:00:00 2001 From: chfw Date: Sun, 24 Feb 2019 21:48:35 +0000 Subject: [PATCH 01/14] :hammer: code refactoring --- moban/plugins/__init__.py | 4 +-- moban/plugins/template.py | 8 ++--- .../test_command_line_options.py | 34 +++++++++---------- tests/mobanfile/test_mobanfile.py | 2 +- tests/test_engine.py | 6 ++-- tests/test_jinja2_extensions.py | 4 +-- tests/test_template.py | 4 +-- 7 files changed, 31 insertions(+), 31 deletions(-) diff --git a/moban/plugins/__init__.py b/moban/plugins/__init__.py index 0fcc020c..9458e5ed 100644 --- a/moban/plugins/__init__.py +++ b/moban/plugins/__init__.py @@ -1,5 +1,5 @@ from lml.loader import scan_plugins_regex -from moban.plugins.template import TemplateFactory +from moban.plugins.template import MobanFactory from moban import constants @@ -11,7 +11,7 @@ ] -ENGINES = TemplateFactory() +ENGINES = MobanFactory() def make_sure_all_pkg_are_loaded(): diff --git a/moban/plugins/template.py b/moban/plugins/template.py index 9595ea1d..a069d921 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -12,9 +12,9 @@ log = logging.getLogger(__name__) -class TemplateFactory(PluginManager): +class MobanFactory(PluginManager): def __init__(self): - super(TemplateFactory, self).__init__( + super(MobanFactory, self).__init__( constants.TEMPLATE_ENGINE_EXTENSION ) self.extensions = {} @@ -25,7 +25,7 @@ def register_extensions(self, extensions): 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 TemplateEngine( + return MobanEngine( template_dirs, context_dirs, engine_cls, engine_extensions ) @@ -36,7 +36,7 @@ def raise_exception(self, key): raise exceptions.NoThirdPartyEngine(key) -class TemplateEngine(object): +class MobanEngine(object): def __init__( self, template_dirs, context_dirs, engine_cls, engine_extensions=None ): diff --git a/tests/integration_tests/test_command_line_options.py b/tests/integration_tests/test_command_line_options.py index aea42b2e..6cbe3fe6 100644 --- a/tests/integration_tests/test_command_line_options.py +++ b/tests/integration_tests/test_command_line_options.py @@ -18,7 +18,7 @@ def setUp(self): ) self.patcher1.start() - @patch("moban.plugins.template.TemplateEngine.render_to_file") + @patch("moban.plugins.template.MobanEngine.render_to_file") def test_custom_options(self, fake_template_doer): test_args = [ "moban", @@ -39,7 +39,7 @@ def test_custom_options(self, fake_template_doer): "a.jj2", "config.yaml", "moban.output" ) - @patch("moban.plugins.template.TemplateEngine.render_to_file") + @patch("moban.plugins.template.MobanEngine.render_to_file") def test_minimal_options(self, fake_template_doer): test_args = ["moban", "-c", self.config_file, "-t", "a.jj2"] with patch.object(sys, "argv", test_args): @@ -73,7 +73,7 @@ def setUp(self): ) self.patcher1.start() - @patch("moban.plugins.template.TemplateEngine.render_to_file") + @patch("moban.plugins.template.MobanEngine.render_to_file") def test_default_options(self, fake_template_doer): test_args = ["moban", "-t", "a.jj2"] with patch.object(sys, "argv", test_args): @@ -84,7 +84,7 @@ def test_default_options(self, fake_template_doer): "a.jj2", "data.yml", "moban.output" ) - @patch("moban.plugins.template.TemplateEngine.render_string_to_file") + @patch("moban.plugins.template.MobanEngine.render_string_to_file") def test_string_template(self, fake_template_doer): string_template = "{{HELLO}}" test_args = ["moban", string_template] @@ -133,7 +133,7 @@ def setUp(self): ) self.patcher1.start() - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_single_command(self, fake_template_doer): test_args = ["moban"] with patch.object(sys, "argv", test_args): @@ -152,7 +152,7 @@ def test_single_command(self, fake_template_doer): ) @raises(Exception) - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_single_command_with_missing_output(self, fake_template_doer): test_args = ["moban", "-t", "README.rst.jj2"] with patch.object(sys, "argv", test_args): @@ -160,7 +160,7 @@ def test_single_command_with_missing_output(self, fake_template_doer): main() - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_single_command_with_a_few_options(self, fake_template_doer): test_args = ["moban", "-t", "README.rst.jj2", "-o", "xyz.output"] with patch.object(sys, "argv", test_args): @@ -173,7 +173,7 @@ def test_single_command_with_a_few_options(self, fake_template_doer): [TemplateTarget("README.rst.jj2", "data.yaml", "xyz.output")], ) - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_single_command_with_options(self, fake_template_doer): test_args = [ "moban", @@ -223,7 +223,7 @@ def setUp(self): ) self.patcher1.start() - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_single_command(self, fake_template_doer): test_args = ["moban"] with patch.object(sys, "argv", test_args): @@ -261,7 +261,7 @@ def setUp(self): ) self.patcher1.start() - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_single_command(self, fake_template_doer): test_args = ["moban", "-m", self.config_file] with patch.object(sys, "argv", test_args): @@ -296,7 +296,7 @@ def setUp(self): ) self.patcher1.start() - @patch("moban.plugins.template.TemplateEngine.render_to_file") + @patch("moban.plugins.template.MobanEngine.render_to_file") def test_template_option_override_moban_file(self, fake_template_doer): test_args = ["moban", "-t", "setup.py.jj2"] with patch.object(sys, "argv", test_args): @@ -307,7 +307,7 @@ def test_template_option_override_moban_file(self, fake_template_doer): "setup.py.jj2", "data.yml", "moban.output" ) - @patch("moban.plugins.template.TemplateEngine.render_to_file") + @patch("moban.plugins.template.MobanEngine.render_to_file") def test_template_option_not_in_moban_file(self, fake_template_doer): test_args = ["moban", "-t", "foo.jj2"] with patch.object(sys, "argv", test_args): @@ -340,7 +340,7 @@ def setUp(self): self.config_file = ".moban.yml" @raises(SystemExit) - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_no_configuration(self, fake_template_doer): with open(self.config_file, "w") as f: f.write("") @@ -351,7 +351,7 @@ def test_no_configuration(self, fake_template_doer): main() @raises(SystemExit) - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_no_configuration_2(self, fake_template_doer): with open(self.config_file, "w") as f: f.write("not: related") @@ -362,7 +362,7 @@ def test_no_configuration_2(self, fake_template_doer): main() @raises(SystemExit) - @patch("moban.plugins.template.TemplateEngine.render_to_files") + @patch("moban.plugins.template.MobanEngine.render_to_files") def test_no_targets(self, fake_template_doer): with open(self.config_file, "w") as f: f.write("configuration: test") @@ -395,7 +395,7 @@ def test_single_command(self, _): from moban.main import main with patch( - "moban.plugins.template.TemplateEngine.render_to_files" + "moban.plugins.template.MobanEngine.render_to_files" ) as fake: main() call_args = list(fake.call_args[0][0]) @@ -420,7 +420,7 @@ def setUp(self): with open(self.config_file, "w") as f: f.write("hello: world") - @patch("moban.plugins.template.TemplateEngine.render_to_file") + @patch("moban.plugins.template.MobanEngine.render_to_file") def test_mako_option(self, fake_template_doer): test_args = ["moban", "-t", "a.mako"] with patch.object(sys, "argv", test_args): diff --git a/tests/mobanfile/test_mobanfile.py b/tests/mobanfile/test_mobanfile.py index 2cffe17c..0786108d 100644 --- a/tests/mobanfile/test_mobanfile.py +++ b/tests/mobanfile/test_mobanfile.py @@ -112,7 +112,7 @@ def test_is_repo(): eq_(expected, actual) -@patch("moban.plugins.template.TemplateEngine.render_to_files") +@patch("moban.plugins.template.MobanEngine.render_to_files") def test_handle_targets(fake_renderer): from moban.mobanfile import handle_targets diff --git a/tests/test_engine.py b/tests/test_engine.py index 5b45e6a3..086851a1 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py @@ -13,7 +13,7 @@ import_module_of_extension, ) from moban.plugins.context import Context -from moban.plugins.template import TemplateEngine, expand_template_directories +from moban.plugins.template import MobanEngine, expand_template_directories USER_HOME = os.path.join("user", "home", ".moban", "repos") @@ -63,12 +63,12 @@ def test_unknown_template_type(): @raises(exceptions.DirectoryNotFound) def test_non_existent_tmpl_directries(): - TemplateEngine("abc", "tests", Engine) + MobanEngine("abc", "tests", Engine) @raises(exceptions.DirectoryNotFound) def test_non_existent_config_directries(): - TemplateEngine("tests", "abc", Engine) + MobanEngine("tests", "abc", Engine) @raises(exceptions.DirectoryNotFound) diff --git a/tests/test_jinja2_extensions.py b/tests/test_jinja2_extensions.py index e2eba845..05e4a2eb 100644 --- a/tests/test_jinja2_extensions.py +++ b/tests/test_jinja2_extensions.py @@ -3,7 +3,7 @@ from nose.tools import eq_ from moban.jinja2.engine import Engine -from moban.plugins.template import TemplateEngine +from moban.plugins.template import MobanEngine from moban.jinja2.extensions import jinja_global @@ -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 = TemplateEngine([path], path, Engine) + engine = MobanEngine([path], path, Engine) engine.render_to_file("basic.template", "basic.yml", output) with open(output, "r") as output_file: content = output_file.read() diff --git a/tests/test_template.py b/tests/test_template.py index f00940f9..360c37a8 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -8,7 +8,7 @@ MODULE = "moban.plugins.template" -@patch(MODULE + ".TemplateEngine._render_with_finding_data_first") +@patch(MODULE + ".MobanEngine._render_with_finding_data_first") def test_do_templates_1(_do_templates_with_more_shared_data): jobs = [ TemplateTarget("1.template", "data.yml", "1.output"), @@ -31,7 +31,7 @@ def test_do_templates_1(_do_templates_with_more_shared_data): _do_templates_with_more_shared_data.assert_called_with(expected) -@patch(MODULE + ".TemplateEngine._render_with_finding_template_first") +@patch(MODULE + ".MobanEngine._render_with_finding_template_first") def test_do_templates_2(_do_templates_with_more_shared_templates): jobs = [ TemplateTarget("1.template", "data1.yml", "1.output"), From 78e4467612a11d51a959afafdd662c2d7c1472e5 Mon Sep 17 00:00:00 2001 From: chfw Date: Sun, 24 Feb 2019 21:50:02 +0000 Subject: [PATCH 02/14] :lipstick: reformat code --- moban/plugins/template.py | 4 +--- moban/repo.py | 2 +- tests/mobanfile/test_templates.py | 6 ++++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/moban/plugins/template.py b/moban/plugins/template.py index a069d921..3224ae59 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -14,9 +14,7 @@ class MobanFactory(PluginManager): def __init__(self): - super(MobanFactory, self).__init__( - constants.TEMPLATE_ENGINE_EXTENSION - ) + super(MobanFactory, self).__init__(constants.TEMPLATE_ENGINE_EXTENSION) self.extensions = {} def register_extensions(self, extensions): diff --git a/moban/repo.py b/moban/repo.py index 8e04ce5e..36da0582 100644 --- a/moban/repo.py +++ b/moban/repo.py @@ -36,7 +36,7 @@ def get_repo_name(repo_url): try: repo = giturlparse.parse(repo_url) name = repo.repo - if name.endswith('/'): + if name.endswith("/"): name = name[:-1] return name except AttributeError: diff --git a/tests/mobanfile/test_templates.py b/tests/mobanfile/test_templates.py index 1379f88e..02479212 100644 --- a/tests/mobanfile/test_templates.py +++ b/tests/mobanfile/test_templates.py @@ -59,8 +59,10 @@ def test_listing_dir_recusively(self): None, ), ] - eq_(sorted(expected, key=lambda x: x[0]), - sorted(results, key=lambda x: x[0])) + eq_( + sorted(expected, key=lambda x: x[0]), + sorted(results, key=lambda x: x[0]), + ) @patch("moban.reporter.report_error_message") def test_listing_dir_recusively_with_error(self, reporter): From ddd64c9350b66e5844e004850b800a809a97da97 Mon Sep 17 00:00:00 2001 From: chfw Date: Mon, 25 Feb 2019 08:36:54 +0000 Subject: [PATCH 03/14] :fire: remove MobanEngine's reference to the engine class --- moban/plugins/template.py | 1 - tests/test_engine.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/moban/plugins/template.py b/moban/plugins/template.py index 3224ae59..e178fd30 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -44,7 +44,6 @@ def __init__( 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.templated_count = 0 self.file_count = 0 diff --git a/tests/test_engine.py b/tests/test_engine.py index 086851a1..62ed8bb2 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py @@ -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: @@ -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) From 9a9dcc95a07f640b5963b959534365faf33ff44b Mon Sep 17 00:00:00 2001 From: chfw Date: Mon, 25 Feb 2019 21:21:31 +0000 Subject: [PATCH 04/14] :hammer: refactoring the code and un-bury engine instance --- moban/plugins/template.py | 7 ++++--- tests/test_jinja2_extensions.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/moban/plugins/template.py b/moban/plugins/template.py index e178fd30..776ccc1c 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -23,8 +23,9 @@ def register_extensions(self, extensions): 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) + engine = engine_cls(template_dirs, engine_extensions) return MobanEngine( - template_dirs, context_dirs, engine_cls, engine_extensions + template_dirs, context_dirs, engine ) def all_types(self): @@ -36,14 +37,14 @@ def raise_exception(self, key): class MobanEngine(object): def __init__( - self, template_dirs, context_dirs, engine_cls, engine_extensions=None + 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 = engine self.templated_count = 0 self.file_count = 0 diff --git a/tests/test_jinja2_extensions.py b/tests/test_jinja2_extensions.py index 05e4a2eb..f9009fcb 100644 --- a/tests/test_jinja2_extensions.py +++ b/tests/test_jinja2_extensions.py @@ -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() From eab156a657a701d2b1dc6ec95c0b952949fb3b2b Mon Sep 17 00:00:00 2001 From: chfw Date: Mon, 25 Feb 2019 21:46:01 +0000 Subject: [PATCH 05/14] :sparkles: initial prototype, not tested. #235 --- moban/jinja2/engine.py | 16 +++++++++++----- moban/plugins/template.py | 21 ++++++++++++++++++--- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/moban/jinja2/engine.py b/moban/jinja2/engine.py index e51af380..21d59d44 100644 --- a/moban/jinja2/engine.py +++ b/moban/jinja2/engine.py @@ -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 @@ -73,10 +73,16 @@ 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 options.get('extensions'): + if is_extension_list_valid(options['extensions']): + # because it is modified here + env_params["extensions"] += options['extensions'] + import_module_of_extension(options['extensions']) + + if 'extensions' in options: + options.pop('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 diff --git a/moban/plugins/template.py b/moban/plugins/template.py index 776ccc1c..53561701 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -16,14 +16,29 @@ 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): + 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) - engine = engine_cls(template_dirs, engine_extensions) + try: + engine_cls = self.load_me_now(template_type) + engine_extensions = self.extensions.get(template_type) + options = dict(extensions=engine_extensions) + except exceptions.NoThirdPartyEngine: + if template_type not in self.options_registry: + raise + else: + custom_engine_spec = self.options_registry[template_type] + engine_cls = self.load_me_now(custom_engine_spec.base_type) + # TODO: + # support other jinja2 options + options = custom_engine_spec['options'] + engine = engine_cls(template_dirs, options) return MobanEngine( template_dirs, context_dirs, engine ) From 21fa2a6984031b1006806e5a4583afdc0859d3a7 Mon Sep 17 00:00:00 2001 From: chfw Date: Mon, 25 Feb 2019 22:22:55 +0000 Subject: [PATCH 06/14] :books: fix doc build --- .moban.d/custom_conf.py.jj2 | 3 +++ docs/conf.py | 42 ++++++++----------------------------- mobanfile | 2 +- 3 files changed, 13 insertions(+), 34 deletions(-) create mode 100644 .moban.d/custom_conf.py.jj2 diff --git a/.moban.d/custom_conf.py.jj2 b/.moban.d/custom_conf.py.jj2 new file mode 100644 index 00000000..f9ecacdb --- /dev/null +++ b/.moban.d/custom_conf.py.jj2 @@ -0,0 +1,3 @@ +{% include "docs/conf.py_t" %} + +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode'] \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index d8039acd..fe594daf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,8 +1,3 @@ -# -*- coding: utf-8 -*- -DESCRIPTION = ( - 'Yet another jinja2 cli command for static text generation' + - '' -) # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full @@ -23,7 +18,7 @@ project = 'moban' copyright = '2017-2019 Onni Software Ltd. and its contributors' -author = 'Onni Software Ltd.' +author = 'C. W.' # The short X.Y version version = '0.4.1' # The full version, including alpha/beta/rc tags @@ -34,17 +29,16 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode',] +extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ['templates'] -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: # -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'en' +# source_suffix = ['.rst', '.md'] +source_suffix = '' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -62,23 +56,5 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# -- Extension configuration ------------------------------------------------- -# -- Options for intersphinx extension --------------------------------------- - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} -# TODO: html_theme not configurable upstream -html_theme = 'default' - -# TODO: DESCRIPTION not configurable upstream -texinfo_documents = [ - ('index', 'moban', - 'moban Documentation', - 'Onni Software Ltd.', 'moban', - DESCRIPTION, - 'Miscellaneous'), -] -intersphinx_mapping.update({ -}) +html_static_path = ['static'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode'] \ No newline at end of file diff --git a/mobanfile b/mobanfile index 9ba1533f..2360459b 100644 --- a/mobanfile +++ b/mobanfile @@ -9,7 +9,7 @@ targets: - setup.py: setup.py - moban/__init__.py: __init__.py.jj2 - moban/_version.py: _version.py.jj2 - - docs/conf.py: conf.py.jj2 + - docs/conf.py: custom_conf.py.jj2 - .travis.yml: travis.yml - requirements.txt: requirements.txt.jj2 - .gitignore: moban_gitignore.jj2 From 78d7aa5fbba821732f9556a2cfeea3a380f3a933 Mon Sep 17 00:00:00 2001 From: chfw Date: Mon, 25 Feb 2019 22:34:09 +0000 Subject: [PATCH 07/14] :bug: fix docs build --- .moban.d/custom_conf.py.jj2 | 4 ++-- docs/conf.py | 44 +++++++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/.moban.d/custom_conf.py.jj2 b/.moban.d/custom_conf.py.jj2 index f9ecacdb..b4d9fd82 100644 --- a/.moban.d/custom_conf.py.jj2 +++ b/.moban.d/custom_conf.py.jj2 @@ -1,3 +1,3 @@ -{% include "docs/conf.py_t" %} +{% include "conf.py.jj2" %} -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode'] \ No newline at end of file +master_doc = "index" \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index fe594daf..f9800022 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +DESCRIPTION = ( + 'Yet another jinja2 cli command for static text generation' + + '' +) # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full @@ -18,7 +23,7 @@ project = 'moban' copyright = '2017-2019 Onni Software Ltd. and its contributors' -author = 'C. W.' +author = 'Onni Software Ltd.' # The short X.Y version version = '0.4.1' # The full version, including alpha/beta/rc tags @@ -29,16 +34,17 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [] +extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode',] # Add any paths that contain templates here, relative to this directory. -templates_path = ['templates'] +templates_path = ['_templates'] -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. # -# source_suffix = ['.rst', '.md'] -source_suffix = '' +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -56,5 +62,25 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['static'] -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode'] \ No newline at end of file +html_static_path = ['_static'] + +# -- Extension configuration ------------------------------------------------- +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} +# TODO: html_theme not configurable upstream +html_theme = 'default' + +# TODO: DESCRIPTION not configurable upstream +texinfo_documents = [ + ('index', 'moban', + 'moban Documentation', + 'Onni Software Ltd.', 'moban', + DESCRIPTION, + 'Miscellaneous'), +] +intersphinx_mapping.update({ +}) + +master_doc = "index" \ No newline at end of file From a8d2bab1805d2dcd4a420d60fe40cf5a249b57e6 Mon Sep 17 00:00:00 2001 From: chfw Date: Tue, 26 Feb 2019 07:11:10 +0000 Subject: [PATCH 08/14] :hammer: refactoring. user define template takes precedence --- moban/plugins/template.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/moban/plugins/template.py b/moban/plugins/template.py index 53561701..f385d9fb 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -25,26 +25,21 @@ def register_options(self, template_types): self.options_registry.update(template_types) def get_engine(self, template_type, template_dirs, context_dirs): - try: + if template_type in self.options_registry: + custom_engine_spec = self.options_registry[template_type] + engine_cls = self.load_me_now(custom_engine_spec.base_type) + options = custom_engine_spec['options'] + else: engine_cls = self.load_me_now(template_type) engine_extensions = self.extensions.get(template_type) options = dict(extensions=engine_extensions) - except exceptions.NoThirdPartyEngine: - if template_type not in self.options_registry: - raise - else: - custom_engine_spec = self.options_registry[template_type] - engine_cls = self.load_me_now(custom_engine_spec.base_type) - # TODO: - # support other jinja2 options - options = custom_engine_spec['options'] engine = engine_cls(template_dirs, options) return MobanEngine( template_dirs, context_dirs, engine ) 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) From e130cc6eac050d117b28cb65b7857f23921a1e91 Mon Sep 17 00:00:00 2001 From: chfw Date: Tue, 26 Feb 2019 07:25:24 +0000 Subject: [PATCH 09/14] :microscope: test user define engine --- moban/plugins/template.py | 4 +++- tests/fixtures/mobanengine/sample_template_type.yml | 10 ++++++++++ tests/test_template.py | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/mobanengine/sample_template_type.yml diff --git a/moban/plugins/template.py b/moban/plugins/template.py index f385d9fb..caa79176 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -22,12 +22,14 @@ 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): if template_type in self.options_registry: custom_engine_spec = self.options_registry[template_type] - engine_cls = self.load_me_now(custom_engine_spec.base_type) + engine_cls = self.load_me_now(custom_engine_spec['base_type']) options = custom_engine_spec['options'] else: engine_cls = self.load_me_now(template_type) diff --git a/tests/fixtures/mobanengine/sample_template_type.yml b/tests/fixtures/mobanengine/sample_template_type.yml new file mode 100644 index 00000000..6895f58f --- /dev/null +++ b/tests/fixtures/mobanengine/sample_template_type.yml @@ -0,0 +1,10 @@ +template_types: + custom_jinja: + base_type: jinja2 # use base_type, instead of overrides + file_extensions: + - jj2 + - jj + - xyz + options: + extensions: + - jinja2.ext.do \ No newline at end of file diff --git a/tests/test_template.py b/tests/test_template.py index 360c37a8..92ba5589 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -4,6 +4,9 @@ from moban.plugins import ENGINES from moban.definitions import TemplateTarget +from moban.data_loaders.yaml import open_yaml +from moban.jinja2.engine import Engine +from nose.tools import eq_ MODULE = "moban.plugins.template" @@ -80,3 +83,12 @@ 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) From 4b51d5f499bbfa5be8265b7f4ff7ab0cfb7648ac Mon Sep 17 00:00:00 2001 From: chfw Date: Tue, 26 Feb 2019 08:24:47 +0000 Subject: [PATCH 10/14] :sparkles: associate user defined file extensions with user defined template engine name, i.e. custom_jinja for jinja2, custom_handlebars for handlebars, #235 --- moban/plugins/template.py | 7 +++++++ .../mobanengine/sample_template_type.yml | 6 +++--- tests/test_template.py | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/moban/plugins/template.py b/moban/plugins/template.py index caa79176..89743120 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -40,6 +40,13 @@ def get_engine(self, template_type, template_dirs, context_dirs): 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['file_extensions']: + return key + + return super(MobanFactory, self).get_primary_key(template_type) + def all_types(self): return list(self.registry.keys()) + list(self.options_registry.keys()) diff --git a/tests/fixtures/mobanengine/sample_template_type.yml b/tests/fixtures/mobanengine/sample_template_type.yml index 6895f58f..5c5226d7 100644 --- a/tests/fixtures/mobanengine/sample_template_type.yml +++ b/tests/fixtures/mobanengine/sample_template_type.yml @@ -2,9 +2,9 @@ template_types: custom_jinja: base_type: jinja2 # use base_type, instead of overrides file_extensions: - - jj2 - - jj - - xyz + - moban + - new + - demo_file_suffix options: extensions: - jinja2.ext.do \ No newline at end of file diff --git a/tests/test_template.py b/tests/test_template.py index 92ba5589..4eb445eb 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -92,3 +92,21 @@ def test_get_user_defined_engine(): 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) From 0a9fe63d75e30f0fda7a0d59d32131d4ca491ef0 Mon Sep 17 00:00:00 2001 From: chfw Date: Tue, 26 Feb 2019 18:01:09 +0000 Subject: [PATCH 11/14] :sparkles: take template types from moban file. related to #233 --- moban/constants.py | 5 +++++ moban/mobanfile/__init__.py | 5 +++++ moban/plugins/template.py | 7 ++++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/moban/constants.py b/moban/constants.py index f113c83a..0f4d3869 100644 --- a/moban/constants.py +++ b/moban/constants.py @@ -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" @@ -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" diff --git a/moban/mobanfile/__init__.py b/moban/mobanfile/__init__.py index dcab849c..9b069a95 100644 --- a/moban/mobanfile/__init__.py +++ b/moban/mobanfile/__init__.py @@ -62,6 +62,11 @@ 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.ENINGES.register_options(template_types) + if targets: if target: targets = target diff --git a/moban/plugins/template.py b/moban/plugins/template.py index 89743120..9a1c1c56 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -29,8 +29,9 @@ def register_options(self, template_types): def get_engine(self, template_type, template_dirs, context_dirs): if template_type in self.options_registry: custom_engine_spec = self.options_registry[template_type] - engine_cls = self.load_me_now(custom_engine_spec['base_type']) - options = custom_engine_spec['options'] + 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) @@ -42,7 +43,7 @@ def get_engine(self, template_type, template_dirs, context_dirs): def get_primary_key(self, template_type): for key, item in self.options_registry.items(): - if template_type in item['file_extensions']: + if template_type in item[constants.TEMPLATE_TYPES_FILE_EXTENSIONS]: return key return super(MobanFactory, self).get_primary_key(template_type) From eec8e10c04202366d6c5ac4f04ec113d05b9f74e Mon Sep 17 00:00:00 2001 From: chfw Date: Tue, 26 Feb 2019 18:46:10 +0000 Subject: [PATCH 12/14] :hammer: address the feedback --- moban/jinja2/engine.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/moban/jinja2/engine.py b/moban/jinja2/engine.py index 21d59d44..7a2028af 100644 --- a/moban/jinja2/engine.py +++ b/moban/jinja2/engine.py @@ -74,14 +74,13 @@ def __init__(self, template_dirs, options=None): ], # get a copy of this global variable ) if options: - if options.get('extensions'): - if is_extension_list_valid(options['extensions']): + if 'extensions' in options: + extensions = options.pop('extensions') + if is_extension_list_valid(extensions): # because it is modified here - env_params["extensions"] += options['extensions'] - import_module_of_extension(options['extensions']) + env_params["extensions"] += extensions + import_module_of_extension(extensions) - if 'extensions' in options: - options.pop('extensions') env_params.update(options) self.jj2_environment = Environment(**env_params) for filter_name, filter_function in FILTERS.get_all(): From 2b1fd6ac1da57027468ca9bcecb9ede795e37a18 Mon Sep 17 00:00:00 2001 From: chfw Date: Tue, 26 Feb 2019 18:48:01 +0000 Subject: [PATCH 13/14] :bug: fix typos and add line feed --- moban/mobanfile/__init__.py | 2 +- tests/fixtures/mobanengine/sample_template_type.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/moban/mobanfile/__init__.py b/moban/mobanfile/__init__.py index 9b069a95..132be2e7 100644 --- a/moban/mobanfile/__init__.py +++ b/moban/mobanfile/__init__.py @@ -65,7 +65,7 @@ def handle_moban_file_v1(moban_file_configurations, command_line_options): template_types = moban_file_configurations.get( constants.LABEL_TEMPLATE_TYPES) if template_types: - plugins.ENINGES.register_options(template_types) + plugins.ENGINES.register_options(template_types) if targets: if target: diff --git a/tests/fixtures/mobanengine/sample_template_type.yml b/tests/fixtures/mobanengine/sample_template_type.yml index 5c5226d7..60eeb617 100644 --- a/tests/fixtures/mobanengine/sample_template_type.yml +++ b/tests/fixtures/mobanengine/sample_template_type.yml @@ -7,4 +7,4 @@ template_types: - demo_file_suffix options: extensions: - - jinja2.ext.do \ No newline at end of file + - jinja2.ext.do From af3bcc38c9232ab2cd44cdb4e9f11c660be2a99b Mon Sep 17 00:00:00 2001 From: chfw Date: Tue, 26 Feb 2019 18:48:28 +0000 Subject: [PATCH 14/14] :lipstick: beautify the code --- docs/conf.py | 2 +- moban/constants.py | 8 ++++---- moban/jinja2/engine.py | 4 ++-- moban/mobanfile/__init__.py | 3 ++- moban/plugins/template.py | 11 ++++------- tests/test_template.py | 29 ++++++++++++++++------------- 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index f9800022..3e4e6c8c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -83,4 +83,4 @@ intersphinx_mapping.update({ }) -master_doc = "index" \ No newline at end of file +master_doc = "index" diff --git a/moban/constants.py b/moban/constants.py index 0f4d3869..920c5e54 100644 --- a/moban/constants.py +++ b/moban/constants.py @@ -64,7 +64,7 @@ LABEL_SOURCE = "source" LABEL_DEST = "destination" LABEL_FORCE_TEMPLATE_TYPE = "force_template_type" -LABEL_TEMPLATE_TYPES = 'template_types' +LABEL_TEMPLATE_TYPES = "template_types" # error messages ERROR_DATA_FILE_NOT_FOUND = "Both %s and %s does not exist" @@ -100,9 +100,9 @@ REQUIRE_TYPE = "type" # Template types -TEMPLATE_TYPES_BASE_TYPE = 'base_type' -TEMPLATE_TYPES_OPTIONS = 'options' -TEMPLATE_TYPES_FILE_EXTENSIONS = 'file_extensions' +TEMPLATE_TYPES_BASE_TYPE = "base_type" +TEMPLATE_TYPES_OPTIONS = "options" +TEMPLATE_TYPES_FILE_EXTENSIONS = "file_extensions" # Extension JINJA_FILTER_EXTENSION = "jinja_filter" diff --git a/moban/jinja2/engine.py b/moban/jinja2/engine.py index 7a2028af..0d525f0d 100644 --- a/moban/jinja2/engine.py +++ b/moban/jinja2/engine.py @@ -74,8 +74,8 @@ def __init__(self, template_dirs, options=None): ], # get a copy of this global variable ) if options: - if 'extensions' in options: - extensions = options.pop('extensions') + if "extensions" in options: + extensions = options.pop("extensions") if is_extension_list_valid(extensions): # because it is modified here env_params["extensions"] += extensions diff --git a/moban/mobanfile/__init__.py b/moban/mobanfile/__init__.py index 132be2e7..c4a2d3d9 100644 --- a/moban/mobanfile/__init__.py +++ b/moban/mobanfile/__init__.py @@ -63,7 +63,8 @@ def handle_moban_file_v1(moban_file_configurations, command_line_options): plugins.ENGINES.register_extensions(extensions) template_types = moban_file_configurations.get( - constants.LABEL_TEMPLATE_TYPES) + constants.LABEL_TEMPLATE_TYPES + ) if template_types: plugins.ENGINES.register_options(template_types) diff --git a/moban/plugins/template.py b/moban/plugins/template.py index 9a1c1c56..0a9f08e1 100644 --- a/moban/plugins/template.py +++ b/moban/plugins/template.py @@ -30,16 +30,15 @@ def get_engine(self, template_type, template_dirs, context_dirs): 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]) + 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 - ) + return MobanEngine(template_dirs, context_dirs, engine) def get_primary_key(self, template_type): for key, item in self.options_registry.items(): @@ -56,9 +55,7 @@ def raise_exception(self, key): class MobanEngine(object): - def __init__( - self, template_dirs, context_dirs, engine - ): + 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) diff --git a/tests/test_template.py b/tests/test_template.py index 4eb445eb..d9b9d2b3 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -1,12 +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.data_loaders.yaml import open_yaml from moban.jinja2.engine import Engine -from nose.tools import eq_ +from moban.data_loaders.yaml import open_yaml MODULE = "moban.plugins.template" @@ -87,26 +87,29 @@ def test_do_templates_with_more_shared_data(): def test_get_user_defined_engine(): test_fixture = os.path.join( - "tests", "fixtures", "mobanengine", "sample_template_type.yml") + "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', ".", ".") + 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") + "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) + 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") + "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) + ENGINES.register_options(template_types["template_types"]) + template_type = ENGINES.get_primary_key("jj2") + eq_("jinja2", template_type)