From d9e98b8598776f9c429e9a4a76ca98efda31edde Mon Sep 17 00:00:00 2001 From: CLiu13 Date: Tue, 1 Jan 2019 00:52:18 -0500 Subject: [PATCH 01/14] =?UTF-8?q?=E2=9C=A8=20Add=20low-setup=20usage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the ability to use moban in an ad-hoc manner without a config file. This also adds environment variables as a fallback data source if the default/specified data files do not exist. Closes https://github.com/moremoban/moban/issues/133 --- .moban.cd/changelog.yml | 6 +++ .moban.cd/moban.yml | 6 +-- CHANGELOG.rst | 9 ++++ README.rst | 6 ++- docs/conf.py | 4 +- docs/level-1-jinja2-cli/README.rst | 3 +- moban/_version.py | 2 +- moban/mobanfile.py | 28 +++++++++--- moban/plugins.py | 30 +++++++++++-- moban/reporter.py | 11 +++++ setup.py | 8 ++-- .../environ_vars_as_data/test.template | 1 + .../test_command_line_options.py | 45 ++++++++++++++++--- tests/test_engine.py | 14 ++++++ 14 files changed, 146 insertions(+), 27 deletions(-) create mode 100644 tests/fixtures/environ_vars_as_data/test.template diff --git a/.moban.cd/changelog.yml b/.moban.cd/changelog.yml index 708cc62a..569c8631 100644 --- a/.moban.cd/changelog.yml +++ b/.moban.cd/changelog.yml @@ -1,6 +1,12 @@ name: moban organisation: moremoban releases: +- changes: + - action: Updated + details: + - "`#146`: added a low-setup usage mode via environment variables to moban" + date: 3-1-2019 + version: 0.3.7 - changes: - action: Updated details: diff --git a/.moban.cd/moban.yml b/.moban.cd/moban.yml index c7ae2e2b..96a4c863 100644 --- a/.moban.cd/moban.yml +++ b/.moban.cd/moban.yml @@ -3,9 +3,9 @@ organisation: moremoban author: C. W. contact: wangc_2011@hotmail.com license: MIT -version: 0.3.6 -current_version: 0.3.6 -release: 0.3.6 +version: 0.3.7 +current_version: 0.3.7 +release: 0.3.7 branch: master command_line_interface: "moban" entry_point: "moban.main:main" diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 80320369..4e25ef4a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,15 @@ Change log ================================================================================ +0.3.7 - 3-1-2019 +-------------------------------------------------------------------------------- + +Updated +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#. `#146 `_: added a low-setup + usage mode via environment variables to moban + 0.3.6 - 30-12-2018 -------------------------------------------------------------------------------- diff --git a/README.rst b/README.rst index 44b0d0ed..e699b4f4 100644 --- a/README.rst +++ b/README.rst @@ -91,11 +91,13 @@ Usage -cd CONFIGURATION_DIR, --configuration_dir CONFIGURATION_DIR the directory for configuration file lookup -c CONFIGURATION, --configuration CONFIGURATION - the dictionary file + the dictionary file. if not present, moban + will try to use environment vars as data -td [TEMPLATE_DIR [TEMPLATE_DIR ...]], --template_dir [TEMPLATE_DIR [TEMPLATE_DIR ...]] the directories for template file lookup -t TEMPLATE, --template TEMPLATE - the template file + the template file. this overrides any targets + defined in a custom moban file -o OUTPUT, --output OUTPUT the output file --template_type TEMPLATE_TYPE diff --git a/docs/conf.py b/docs/conf.py index 731a5619..b8bd3a7b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,9 +28,9 @@ author = u'C. W.' # The short X.Y version -version = u'0.3.6' +version = u'0.3.7' # The full version, including alpha/beta/rc tags -release = u'0.3.6' +release = u'0.3.7' # -- General configuration --------------------------------------------------- diff --git a/docs/level-1-jinja2-cli/README.rst b/docs/level-1-jinja2-cli/README.rst index 78d29cde..59bb9b1e 100644 --- a/docs/level-1-jinja2-cli/README.rst +++ b/docs/level-1-jinja2-cli/README.rst @@ -2,7 +2,8 @@ Level 1 Jinja2 on command line ================================================================================ `moban` reads data in yaml format, renders a template file in jinja2 format and -outputs it to `moban.output`. By default, it looks for `data.yml` as its data file +outputs it to `moban.output`. By default, it looks for `data.yml` as its data file, +but it will fallback to environment variables if a data file cannot be found Evaluation -------------------------------------------------------------------------------- diff --git a/moban/_version.py b/moban/_version.py index 64fcab11..2c02a9fe 100644 --- a/moban/_version.py +++ b/moban/_version.py @@ -1,2 +1,2 @@ -__version__ = "0.3.6" +__version__ = "0.3.7" __author__ = "C. W." diff --git a/moban/mobanfile.py b/moban/mobanfile.py index ffff7277..1223db29 100644 --- a/moban/mobanfile.py +++ b/moban/mobanfile.py @@ -37,7 +37,23 @@ def find_default_moban_file(): def handle_moban_file_v1(moban_file_configurations, command_line_options): merged_options = None - target = extract_target(command_line_options) + + targets = moban_file_configurations.get(constants.LABEL_TARGETS) + try: + target = extract_target(command_line_options) + except Exception as exception: + if targets: + template = command_line_options.get(constants.LABEL_TEMPLATE) + for t in targets: + found_template = template in t.values() + if found_template: + target = [dict(t)] + if not found_template: + # Warn user if template not defined under targets in moban file + reporter.report_template_not_in_moban_file(template) + else: + raise exception + if constants.LABEL_CONFIG in moban_file_configurations: merged_options = merge( command_line_options, @@ -52,12 +68,14 @@ def handle_moban_file_v1(moban_file_configurations, command_line_options): if requires: handle_requires(requires) - targets = moban_file_configurations.get(constants.LABEL_TARGETS) if targets: + # If template specified via CLI flag `-t: + # 1. Only update the specified template + # 2. Do not copy if target: - # if command line option exists, append its template to targets - # issue 30 - targets += target + targets = target + if constants.LABEL_COPY in moban_file_configurations: + del moban_file_configurations[constants.LABEL_COPY] number_of_templated_files = handle_targets(merged_options, targets) else: number_of_templated_files = 0 diff --git a/moban/plugins.py b/moban/plugins.py index 544dc2a4..fb152886 100644 --- a/moban/plugins.py +++ b/moban/plugins.py @@ -46,7 +46,15 @@ def number_of_templated_files(self): return self.templated_count def render_to_file(self, template_file, data_file, output_file): - data = self.context.get_data(data_file) + try: + data = self.context.get_data(data_file) + except Exception as exception: + # If data file doesn't exist: + # 1. Alert the user of their (potential) mistake + # 2. Attempt to use environment vars as data + reporter.report_error_message(str(exception)) + reporter.report_using_env_vars() + data = os.environ template = self.engine.get_template(template_file) template_abs_path = utils.get_template_path( self.template_dirs, template_file @@ -89,7 +97,15 @@ def _render_with_finding_template_first(self, template_file_index): self.template_dirs, template_file ) for (data_file, output) in data_output_pairs: - data = self.context.get_data(data_file) + try: + data = self.context.get_data(data_file) + except Exception as exception: + # If data file doesn't exist: + # 1. Alert the user of their (potential) mistake + # 2. Attempt to use environment vars as data + reporter.report_error_message(exception) + reporter.report_using_env_vars() + data = os.environ flag = self.apply_template( template_abs_path, template, data, output ) @@ -100,7 +116,15 @@ def _render_with_finding_template_first(self, template_file_index): def _render_with_finding_data_first(self, data_file_index): for (data_file, template_output_pairs) in data_file_index.items(): - data = self.context.get_data(data_file) + try: + data = self.context.get_data(data_file) + except Exception as exception: + # If data file doesn't exist: + # 1. Alert the user of their (potential) mistake + # 2. Attempt to use environment vars as data + reporter.report_error_message(exception) + reporter.report_using_env_vars() + data = os.environ for (template_file, output) in template_output_pairs: template = self.engine.get_template(template_file) template_abs_path = utils.get_template_path( diff --git a/moban/reporter.py b/moban/reporter.py index bdb5bc42..fac242de 100644 --- a/moban/reporter.py +++ b/moban/reporter.py @@ -12,6 +12,8 @@ MESSAGE_COPIED_ALL = "Copied {0} files." MESSAGE_PULLING_REPO = "Updating {0}..." MESSAGE_CLONING_REPO = "Cloning {0}..." +MESSAGE_USING_ENV_VARS = "Attempting to use environment vars as data..." +MESSAGE_TEMPLATE_NOT_IN_MOBAN_FILE = "{0} is not defined in your moban file!" def report_templating(source_file, destination_file): @@ -89,6 +91,15 @@ def report_git_clone(repo): print(MESSAGE_CLONING_REPO.format(colored_repo)) +def report_using_env_vars(): + print(crayons.yellow(MESSAGE_USING_ENV_VARS, bold=True)) + + +def report_template_not_in_moban_file(template): + message = MESSAGE_TEMPLATE_NOT_IN_MOBAN_FILE.format(template) + print(crayons.yellow(message, bold=True)) + + def _format_single(message, count): if count == 1: return message.replace("files", "file") diff --git a/setup.py b/setup.py index 27f65c2e..dbaca9af 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ NAME = 'moban' AUTHOR = 'C. W.' -VERSION = '0.3.6' +VERSION = '0.3.7' EMAIL = 'wangc_2011@hotmail.com' LICENSE = 'MIT' ENTRY_POINTS = { @@ -25,7 +25,7 @@ 'Yet another jinja2 cli command for static text generation' ) URL = 'https://github.com/moremoban/moban' -DOWNLOAD_URL = '%s/archive/0.3.6.tar.gz' % URL +DOWNLOAD_URL = '%s/archive/0.3.7.tar.gz' % URL FILES = ['README.rst', 'CONTRIBUTORS.rst', 'CHANGELOG.rst'] KEYWORDS = [ 'python', @@ -60,8 +60,8 @@ # You do not need to read beyond this line PUBLISH_COMMAND = '{0} setup.py sdist bdist_wheel upload -r pypi'.format( sys.executable) -GS_COMMAND = ('gs moban v0.3.6 ' + - "Find 0.3.6 in changelog for more details") +GS_COMMAND = ('gs moban v0.3.7 ' + + "Find 0.3.7 in changelog for more details") NO_GS_MESSAGE = ('Automatic github release is disabled. ' + 'Please install gease to enable it.') UPLOAD_FAILED_MSG = ( diff --git a/tests/fixtures/environ_vars_as_data/test.template b/tests/fixtures/environ_vars_as_data/test.template new file mode 100644 index 00000000..b9590f82 --- /dev/null +++ b/tests/fixtures/environ_vars_as_data/test.template @@ -0,0 +1 @@ +{{ TEST_ENVIRONMENT_VARIABLE }} \ No newline at end of file diff --git a/tests/integration_tests/test_command_line_options.py b/tests/integration_tests/test_command_line_options.py index e0ee5e9c..2d9647c3 100644 --- a/tests/integration_tests/test_command_line_options.py +++ b/tests/integration_tests/test_command_line_options.py @@ -95,7 +95,7 @@ def tearDown(self): os.unlink(self.config_file) -@raises(IOError) +@raises(Exception) def test_missing_configuration(): test_args = ["moban", "-t", "a.jj2"] with patch.object(sys, "argv", test_args): @@ -146,8 +146,6 @@ def test_single_command_with_a_few_options(self, fake_template_doer): eq_( call_args, [ - ("README.rst.jj2", "data.yaml", "README.rst"), - ("setup.py.jj2", "data.yaml", "setup.py"), ("abc.jj2", "data.yaml", "xyz.output"), ], ) @@ -171,14 +169,11 @@ def test_single_command_with_options(self, fake_template_doer): eq_( call_args, [ - ("README.rst.jj2", "new.yml", "README.rst"), - ("setup.py.jj2", "new.yml", "setup.py"), ("abc.jj2", "new.yml", "xyz.output"), ], ) @raises(Exception) - @patch("moban.plugins.BaseEngine.render_to_files") def test_single_command_without_output_option(self, fake_template_doer): test_args = ["moban", "-t", "abc.jj2"] with patch.object(sys, "argv", test_args): @@ -265,6 +260,44 @@ def tearDown(self): os.unlink(self.data_file) +class TestTemplateOption: + def setUp(self): + self.config_file = "custom-moban.txt" + copyfile( + os.path.join("tests", "fixtures", ".moban.yml"), self.config_file + ) + self.patcher1 = patch( + "moban.plugins.verify_the_existence_of_directories" + ) + self.patcher1.start() + + @patch("moban.plugins.BaseEngine.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): + from moban.main import main + + main() + fake_template_doer.assert_called_with( + "setup.py.jj2", "data.yml", "moban.output" + ) + + @patch("moban.plugins.BaseEngine.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): + from moban.main import main + + main() + fake_template_doer.assert_called_with( + "foo.jj2", "data.yml", "moban.output" + ) + + def tearDown(self): + self.patcher1.stop() + os.unlink(self.config_file) + + @patch("moban.plugins.verify_the_existence_of_directories") def test_duplicated_targets_in_moban_file(fake_verify): config_file = "duplicated.moban.yml" diff --git a/tests/test_engine.py b/tests/test_engine.py index 9d8d46eb..521be93d 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py @@ -99,3 +99,17 @@ def test_nested_global_template_variables(): content = output_file.read() eq_(content, "template: nested.template\ntarget: test.txt\nhere") os.unlink(output) + + +def test_environ_variables_as_data(): + test_var = "TEST_ENVIRONMENT_VARIABLE" + test_value = "foo" + os.environ[test_var] = test_value + output = "test.txt" + path = os.path.join("tests", "fixtures", "environ_vars_as_data") + engine = BaseEngine([path], path, Engine) + engine.render_to_file("test.template", "this_does_not_exist.yml", output) + with open(output, "r") as output_file: + content = output_file.read() + eq_(content, "foo") + os.unlink(output) From 61889f34e9c2f4c7c30fc17d549e89f5476ff656 Mon Sep 17 00:00:00 2001 From: CLiu13 Date: Fri, 4 Jan 2019 13:35:13 -0500 Subject: [PATCH 02/14] =?UTF-8?q?=F0=9F=94=A8=20Code=20refactoring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related to https://github.com/moremoban/moban/pull/146 --- moban/plugins.py | 57 ++++++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/moban/plugins.py b/moban/plugins.py index fb152886..df47c409 100644 --- a/moban/plugins.py +++ b/moban/plugins.py @@ -46,15 +46,7 @@ def number_of_templated_files(self): return self.templated_count def render_to_file(self, template_file, data_file, output_file): - try: - data = self.context.get_data(data_file) - except Exception as exception: - # If data file doesn't exist: - # 1. Alert the user of their (potential) mistake - # 2. Attempt to use environment vars as data - reporter.report_error_message(str(exception)) - reporter.report_using_env_vars() - data = os.environ + data = self.context.get_data(data_file) template = self.engine.get_template(template_file) template_abs_path = utils.get_template_path( self.template_dirs, template_file @@ -97,15 +89,7 @@ def _render_with_finding_template_first(self, template_file_index): self.template_dirs, template_file ) for (data_file, output) in data_output_pairs: - try: - data = self.context.get_data(data_file) - except Exception as exception: - # If data file doesn't exist: - # 1. Alert the user of their (potential) mistake - # 2. Attempt to use environment vars as data - reporter.report_error_message(exception) - reporter.report_using_env_vars() - data = os.environ + data = self.context.get_data(data_file) flag = self.apply_template( template_abs_path, template, data, output ) @@ -116,15 +100,7 @@ def _render_with_finding_template_first(self, template_file_index): def _render_with_finding_data_first(self, data_file_index): for (data_file, template_output_pairs) in data_file_index.items(): - try: - data = self.context.get_data(data_file) - except Exception as exception: - # If data file doesn't exist: - # 1. Alert the user of their (potential) mistake - # 2. Attempt to use environment vars as data - reporter.report_error_message(exception) - reporter.report_using_env_vars() - data = os.environ + data = self.context.get_data(data_file) for (template_file, output) in template_output_pairs: template = self.engine.get_template(template_file) template_abs_path = utils.get_template_path( @@ -207,15 +183,24 @@ def __init__(self, context_dirs): ) def get_data(self, file_name): - file_extension = os.path.splitext(file_name)[1] - if file_extension == ".json": - data = utils.open_json(self.context_dirs, file_name) - elif file_extension in [".yml", ".yaml"]: - data = utils.open_yaml(self.context_dirs, file_name) - utils.merge(data, self.__cached_environ_variables) - else: - raise exceptions.IncorrectDataInput - return data + try: + file_extension = os.path.splitext(file_name)[1] + if file_extension == ".json": + data = utils.open_json(self.context_dirs, file_name) + elif file_extension in [".yml", ".yaml"]: + data = utils.open_yaml(self.context_dirs, file_name) + utils.merge(data, self.__cached_environ_variables) + else: + raise exceptions.IncorrectDataInput + return data + except Exception as exception: + # If data file doesn't exist: + # 1. Alert the user of their (potential) mistake + # 2. Attempt to use environment vars as data + reporter.report_error_message(str(exception)) + reporter.report_using_env_vars() + data = os.environ + return data def make_sure_all_pkg_are_loaded(): From e0290c64b38cc60c1ae93b6c39670e9930247934 Mon Sep 17 00:00:00 2001 From: chfw Date: Sat, 5 Jan 2019 12:37:46 +0000 Subject: [PATCH 03/14] :hammer: add test related content into release tar ball. resolve #148 --- .moban.cd/changelog.yml | 3 ++- CHANGELOG.rst | 5 ++++- MANIFEST.in | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.moban.cd/changelog.yml b/.moban.cd/changelog.yml index 569c8631..c6563382 100644 --- a/.moban.cd/changelog.yml +++ b/.moban.cd/changelog.yml @@ -5,7 +5,8 @@ releases: - action: Updated details: - "`#146`: added a low-setup usage mode via environment variables to moban" - date: 3-1-2019 + - "`#148`: include test related files in the package for package validation when distributing via linux system, i.e. OpenSuse" + date: 6-1-2019 version: 0.3.7 - changes: - action: Updated diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4e25ef4a..e3d12085 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,7 @@ Change log ================================================================================ -0.3.7 - 3-1-2019 +0.3.7 - 6-1-2019 -------------------------------------------------------------------------------- Updated @@ -9,6 +9,9 @@ Updated #. `#146 `_: added a low-setup usage mode via environment variables to moban +#. `#148 `_: include test related + files in the package for package validation when distributing via linux + system, i.e. OpenSuse 0.3.6 - 30-12-2018 -------------------------------------------------------------------------------- diff --git a/MANIFEST.in b/MANIFEST.in index 8a80a6dd..e86ae541 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,6 @@ include README.rst include LICENSE include CHANGELOG.rst -include CONTRIBUTORS.rst \ No newline at end of file +include CONTRIBUTORS.rst +recursive-include tests * +recursive-include docs * From 70c2509e971696034b97bb5fb4165c40ad1a17c5 Mon Sep 17 00:00:00 2001 From: chfw Date: Sat, 5 Jan 2019 17:05:26 +0000 Subject: [PATCH 04/14] :sparkles: change error line to info line. resolves #150 --- moban/plugins.py | 2 +- moban/reporter.py | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/moban/plugins.py b/moban/plugins.py index df47c409..67dbd058 100644 --- a/moban/plugins.py +++ b/moban/plugins.py @@ -197,7 +197,7 @@ def get_data(self, file_name): # If data file doesn't exist: # 1. Alert the user of their (potential) mistake # 2. Attempt to use environment vars as data - reporter.report_error_message(str(exception)) + reporter.report_info_message(str(exception)) reporter.report_using_env_vars() data = os.environ return data diff --git a/moban/reporter.py b/moban/reporter.py index fac242de..40ca6d56 100644 --- a/moban/reporter.py +++ b/moban/reporter.py @@ -49,6 +49,14 @@ def report_error_message(message): print(crayons.white("Error: ", bold=True) + crayons.red(message)) +def report_warning_message(message): + print(crayons.white("Warning: ", bold=True) + crayons.yellow(message)) + + +def report_info_message(message): + print(crayons.white("info: ") + crayons.green(message)) + + def report_up_to_date(): print(crayons.green(MESSAGE_UP_TO_DATE, bold=True)) @@ -92,12 +100,12 @@ def report_git_clone(repo): def report_using_env_vars(): - print(crayons.yellow(MESSAGE_USING_ENV_VARS, bold=True)) + report_warning_message(MESSAGE_USING_ENV_VARS) def report_template_not_in_moban_file(template): message = MESSAGE_TEMPLATE_NOT_IN_MOBAN_FILE.format(template) - print(crayons.yellow(message, bold=True)) + report_warning_message(message) def _format_single(message, count): From d00d1f29fb9329ea6d66f0130c6058a38474922b Mon Sep 17 00:00:00 2001 From: chfw Date: Sat, 5 Jan 2019 17:17:41 +0000 Subject: [PATCH 05/14] :microscope: more test coverage --- .../integration_tests/test_command_line_options.py | 14 ++------------ tests/test_main.py | 14 ++++++++++++++ tests/test_utils.py | 7 +++++++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/tests/integration_tests/test_command_line_options.py b/tests/integration_tests/test_command_line_options.py index 2d9647c3..a4c667c9 100644 --- a/tests/integration_tests/test_command_line_options.py +++ b/tests/integration_tests/test_command_line_options.py @@ -143,12 +143,7 @@ def test_single_command_with_a_few_options(self, fake_template_doer): main() call_args = list(fake_template_doer.call_args[0][0]) - eq_( - call_args, - [ - ("abc.jj2", "data.yaml", "xyz.output"), - ], - ) + eq_(call_args, [("abc.jj2", "data.yaml", "xyz.output")]) @patch("moban.plugins.BaseEngine.render_to_files") def test_single_command_with_options(self, fake_template_doer): @@ -166,12 +161,7 @@ def test_single_command_with_options(self, fake_template_doer): main() call_args = list(fake_template_doer.call_args[0][0]) - eq_( - call_args, - [ - ("abc.jj2", "new.yml", "xyz.output"), - ], - ) + eq_(call_args, [("abc.jj2", "new.yml", "xyz.output")]) @raises(Exception) def test_single_command_without_output_option(self, fake_template_doer): diff --git a/tests/test_main.py b/tests/test_main.py index 3ae6b72b..308e8b64 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -108,6 +108,20 @@ def test_no_third_party_engine( with patch.object(sys, "argv", ["moban"]): main() + @raises(SystemExit) + @patch("os.path.exists") + @patch("moban.main.handle_moban_file") + @patch("moban.reporter.report_error_message") + def test_double_underscore_main( + self, fake_reporter, fake_moban_file, fake_file + ): + fake_file.return_value = True + fake_moban_file.side_effect = exceptions.DirectoryNotFound + from moban.__main__ import main + + with patch.object(sys, "argv", ["moban"]): + main() + class TestExitCodes: def setUp(self): diff --git a/tests/test_utils.py b/tests/test_utils.py index 13176cc7..cd3a4bf8 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -9,6 +9,7 @@ from moban.utils import ( mkdir_p, + open_json, get_repo_name, write_file_out, file_permissions, @@ -169,3 +170,9 @@ def test_get_repo_name(): actual = [get_repo_name(repo) for repo in repos] expected = ["repo", "repo"] eq_(expected, actual) + + +def test_open_json(): + content = open_json(os.path.join("tests", "fixtures"), "child.json") + expected = {"key": "hello world", "pass": "ox"} + eq_(expected, content) From 5635ce1ac0c91180619e48ff2c81a115d7e5dcd2 Mon Sep 17 00:00:00 2001 From: chfw Date: Sat, 5 Jan 2019 17:31:39 +0000 Subject: [PATCH 06/14] :microscope: more test coverage --- moban/reporter.py | 2 +- tests/test_reporter.py | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/moban/reporter.py b/moban/reporter.py index 40ca6d56..bbfbab1e 100644 --- a/moban/reporter.py +++ b/moban/reporter.py @@ -54,7 +54,7 @@ def report_warning_message(message): def report_info_message(message): - print(crayons.white("info: ") + crayons.green(message)) + print(crayons.white("Info: ") + crayons.green(message)) def report_up_to_date(): diff --git a/tests/test_reporter.py b/tests/test_reporter.py index b5757362..5e60daeb 100644 --- a/tests/test_reporter.py +++ b/tests/test_reporter.py @@ -36,6 +36,22 @@ def test_error_message(): eq_(fake_stdout.getvalue(), "Error: something wrong\n") +def test_info_message(): + patcher = patch("sys.stdout", new_callable=StringIO) + fake_stdout = patcher.start() + reporter.report_info_message("for your information") + patcher.stop() + eq_(fake_stdout.getvalue(), "Info: for your information\n") + + +def test_warning_message(): + patcher = patch("sys.stdout", new_callable=StringIO) + fake_stdout = patcher.start() + reporter.report_warning_message("Maybe you wanna know") + patcher.stop() + eq_(fake_stdout.getvalue(), "Warning: Maybe you wanna know\n") + + def test_report_templating(): patcher = patch("sys.stdout", new_callable=StringIO) fake_stdout = patcher.start() @@ -56,3 +72,14 @@ def test_format_single(): message = "1 files" ret = reporter._format_single(message, 1) eq_(ret, "1 file") + + +def test_report_template_not_in_moban_file(): + patcher = patch("sys.stdout", new_callable=StringIO) + fake_stdout = patcher.start() + reporter.report_template_not_in_moban_file("test.jj2") + patcher.stop() + eq_( + fake_stdout.getvalue(), + "Warning: test.jj2 is not defined in your moban file!\n", + ) From cedc96d3219a4f38d46c42fa7a63ca88e0728b02 Mon Sep 17 00:00:00 2001 From: chfw Date: Sat, 5 Jan 2019 17:52:32 +0000 Subject: [PATCH 07/14] :sparkles: add reporting feature so that if moban take no action, user would also see it in console log --- moban/main.py | 1 + moban/plugins.py | 2 ++ tests/test_docs.py | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/moban/main.py b/moban/main.py index a453e19b..17e75722 100644 --- a/moban/main.py +++ b/moban/main.py @@ -165,6 +165,7 @@ def handle_command_line(options): options[constants.LABEL_CONFIG], options[constants.LABEL_OUTPUT], ) + engine.report() HASH_STORE.save_hashes() exit_code = reporter.convert_to_shell_exit_code( engine.number_of_templated_files() diff --git a/moban/plugins.py b/moban/plugins.py index 67dbd058..debdb330 100644 --- a/moban/plugins.py +++ b/moban/plugins.py @@ -46,6 +46,7 @@ def number_of_templated_files(self): return self.templated_count def render_to_file(self, template_file, data_file, output_file): + self.file_count = 1 data = self.context.get_data(data_file) template = self.engine.get_template(template_file) template_abs_path = utils.get_template_path( @@ -56,6 +57,7 @@ def render_to_file(self, template_file, data_file, output_file): ) if flag: reporter.report_templating(template_file, output_file) + self.templated_count += 1 def apply_template(self, template_abs_path, template, data, output_file): rendered_content = self.engine.apply_template( diff --git a/tests/test_docs.py b/tests/test_docs.py index 80c8fdc2..74a919e6 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -120,7 +120,10 @@ def _moban(self, folder, expected): def _raw_moban(self, args, folder, expected, output): os.chdir(os.path.join("docs", folder)) with patch.object(sys, "argv", args): - main() + try: + main() + except SystemExit as e: + pass _verify_content(output, expected) os.unlink(output) From db3a52cb299b6bd4f3eb13968d93dcd5ddfe3f70 Mon Sep 17 00:00:00 2001 From: chfw Date: Sat, 5 Jan 2019 17:59:13 +0000 Subject: [PATCH 08/14] :microscope: verify there is change --- tests/test_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_docs.py b/tests/test_docs.py index 74a919e6..365fc2a4 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -123,7 +123,7 @@ def _raw_moban(self, args, folder, expected, output): try: main() except SystemExit as e: - pass + eq_('1', str(e)) _verify_content(output, expected) os.unlink(output) From 16b9f08165552a735863b6e5c0601e62706083ab Mon Sep 17 00:00:00 2001 From: chfw Date: Sat, 5 Jan 2019 17:59:44 +0000 Subject: [PATCH 09/14] :lipstick: update double to single quote --- tests/test_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_docs.py b/tests/test_docs.py index 365fc2a4..1a4470b4 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -123,7 +123,7 @@ def _raw_moban(self, args, folder, expected, output): try: main() except SystemExit as e: - eq_('1', str(e)) + eq_("1", str(e)) _verify_content(output, expected) os.unlink(output) From b44caa5ce855203f77970f1f8b390abf5c81bf67 Mon Sep 17 00:00:00 2001 From: chfw Date: Sun, 6 Jan 2019 13:27:34 +0000 Subject: [PATCH 10/14] :bug: json data shall override environment data too --- moban/plugins.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/moban/plugins.py b/moban/plugins.py index debdb330..409d3a53 100644 --- a/moban/plugins.py +++ b/moban/plugins.py @@ -191,18 +191,20 @@ def get_data(self, file_name): data = utils.open_json(self.context_dirs, file_name) elif file_extension in [".yml", ".yaml"]: data = utils.open_yaml(self.context_dirs, file_name) - utils.merge(data, self.__cached_environ_variables) else: raise exceptions.IncorrectDataInput + utils.merge(data, self.__cached_environ_variables) return data - except Exception as exception: + except IOError as exception: # If data file doesn't exist: # 1. Alert the user of their (potential) mistake # 2. Attempt to use environment vars as data reporter.report_info_message(str(exception)) reporter.report_using_env_vars() - data = os.environ - return data + return self.__cached_environ_variables + except exceptions.IncorrectDataInput: + reporter.report_using_env_vars() + return self.__cached_environ_variables def make_sure_all_pkg_are_loaded(): From 23220f91e1e1d9f92c666c68fb447e659040b355 Mon Sep 17 00:00:00 2001 From: chfw Date: Sun, 6 Jan 2019 13:31:42 +0000 Subject: [PATCH 11/14] :microscope: test json overidence --- tests/test_context.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_context.py b/tests/test_context.py index c1177b89..1c8284e8 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -18,3 +18,12 @@ def test_environ_variables(): context = Context(os.path.join("tests", "fixtures")) data = context.get_data("simple.yaml") eq_(data[test_var], test_value) + + +def test_json_data_overrides_environ_variables(): + test_var = "TEST_ENVIRONMENT_VARIABLE" + test_value = "am I found" + os.environ[test_var] = test_value + context = Context(os.path.join("tests", "fixtures")) + data = context.get_data("simple.json") + eq_(data[test_var], test_value) From a67bd6cb9fe9989b91cebb8b5a1bad0563b19c0e Mon Sep 17 00:00:00 2001 From: chfw Date: Sun, 6 Jan 2019 13:35:14 +0000 Subject: [PATCH 12/14] :hammer: remove blind exception handler --- moban/plugins.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/moban/plugins.py b/moban/plugins.py index 409d3a53..6d08b1fe 100644 --- a/moban/plugins.py +++ b/moban/plugins.py @@ -199,10 +199,13 @@ def get_data(self, file_name): # If data file doesn't exist: # 1. Alert the user of their (potential) mistake # 2. Attempt to use environment vars as data - reporter.report_info_message(str(exception)) + reporter.report_warning_message(str(exception)) reporter.report_using_env_vars() return self.__cached_environ_variables - except exceptions.IncorrectDataInput: + except exceptions.IncorrectDataInput as exception2: + # If data file is not in the right format + # do the same as above + reporter.report_warning_message(str(exception2)) reporter.report_using_env_vars() return self.__cached_environ_variables From ca1489e1fca85f52a53fc1bd1f69938879752598 Mon Sep 17 00:00:00 2001 From: chfw Date: Sun, 6 Jan 2019 14:07:26 +0000 Subject: [PATCH 13/14] :microscope: test incorrrect data file intput --- tests/test_context.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_context.py b/tests/test_context.py index 1c8284e8..53d03570 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -27,3 +27,12 @@ def test_json_data_overrides_environ_variables(): context = Context(os.path.join("tests", "fixtures")) data = context.get_data("simple.json") eq_(data[test_var], test_value) + + +def test_unknown_data_file(): + test_var = "TEST_ENVIRONMENT_VARIABLE" + test_value = "am I found" + os.environ[test_var] = test_value + context = Context(os.path.join("tests", "fixtures")) + data = context.get_data("unknown.data") + eq_(data[test_var], test_value) From 663b1cfa820236ed0a2e7c890709b534e376e47f Mon Sep 17 00:00:00 2001 From: chfw Date: Sun, 6 Jan 2019 14:29:57 +0000 Subject: [PATCH 14/14] :fire: remove duplicated error handler --- moban/plugins.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/moban/plugins.py b/moban/plugins.py index 6d08b1fe..a258fe2a 100644 --- a/moban/plugins.py +++ b/moban/plugins.py @@ -195,19 +195,13 @@ def get_data(self, file_name): raise exceptions.IncorrectDataInput utils.merge(data, self.__cached_environ_variables) return data - except IOError as exception: + except (IOError, exceptions.IncorrectDataInput) as exception: # If data file doesn't exist: # 1. Alert the user of their (potential) mistake # 2. Attempt to use environment vars as data reporter.report_warning_message(str(exception)) reporter.report_using_env_vars() return self.__cached_environ_variables - except exceptions.IncorrectDataInput as exception2: - # If data file is not in the right format - # do the same as above - reporter.report_warning_message(str(exception2)) - reporter.report_using_env_vars() - return self.__cached_environ_variables def make_sure_all_pkg_are_loaded():