diff --git a/.moban.cd/changelog.yml b/.moban.cd/changelog.yml index d3d62028..fb80ce80 100644 --- a/.moban.cd/changelog.yml +++ b/.moban.cd/changelog.yml @@ -6,6 +6,7 @@ releases: details: - "`#234`: Define template parameters on the fly inside `targets` section" - "`#180`: No longer two statistics will be shown in v0.4.x. legacy copy targets are injected into a normal targets. cli target is made a clear priority." + - "`#62`: select a group target to run" date: unreleased version: 0.4.2 - changes: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bda431c3..8961f484 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,6 +12,8 @@ Added #. `#180 `_: No longer two statistics will be shown in v0.4.x. legacy copy targets are injected into a normal targets. cli target is made a clear priority. +#. `#62 `_: select a group target + to run 0.4.1 - 28.02.2019 -------------------------------------------------------------------------------- diff --git a/docs/README.rst b/docs/README.rst index 809ef719..b4aff488 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -20,6 +20,8 @@ This section covers the use cases for moban. Please check them out individually. #. `Copy templates as target`_ #. `Group targets by template type`_ #. `Force template type from moban file`_ +#. `User defined template types`_ +#. `Select a group target to run`_ .. _Jinja2 command line: level-1-jinja2-cli .. _Template inheritance: level-2-template-inheritance @@ -38,3 +40,5 @@ This section covers the use cases for moban. Please check them out individually. .. _Copy templates as target: level-15-copy-templates-as-target .. _Group targets by template type: level-16-group-targets-using-template-type .. _Force template type from moban file: level-17-force-template-type-from-moban-file +.. _User defined template types: level-18-user-defined-template-types +.. _Select a group target to run: level-19-moban-a-sub-group-in-targets diff --git a/docs/index.rst b/docs/index.rst index 9273f202..f95acb7c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -32,6 +32,8 @@ examples folder. level-15-copy-templates-as-target/README.rst level-16-group-targets-using-template-type/README.rst level-17-force-template-type-from-moban-file/README.rst + level-18-user-defined-template-types/README.rst + level-19-moban-a-sub-group-in-targets/README.rst In pratice, the following use cases were found interesting to go along with. diff --git a/docs/level-18-user-defined-template-types/README.rst b/docs/level-18-user-defined-template-types/README.rst index b2bdc566..90fc4d08 100644 --- a/docs/level-18-user-defined-template-types/README.rst +++ b/docs/level-18-user-defined-template-types/README.rst @@ -7,7 +7,6 @@ possibilities are: #. associate your own file extensions #. choose your own template engine extensions -#. Evaluation diff --git a/docs/level-19-moban-a-sub-group-in-targets/.moban.yml b/docs/level-19-moban-a-sub-group-in-targets/.moban.yml new file mode 100644 index 00000000..788cf965 --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/.moban.yml @@ -0,0 +1,11 @@ +configuration: + template_dir: + - template-sources + - . +targets: + - a.output: a.template.jj2 + - copy: + - simple.file.copy: file-in-template-sources-folder.txt + - "misc-1-copying/can-create-folder/if-not-exists.txt": file-in-template-sources-folder.txt + - "test-dir": dir-for-copying + - "test-recursive-dir": dir-for-recusive-copying/** diff --git a/docs/level-19-moban-a-sub-group-in-targets/README.rst b/docs/level-19-moban-a-sub-group-in-targets/README.rst new file mode 100644 index 00000000..2b385597 --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/README.rst @@ -0,0 +1,22 @@ +Level 19: select a group target to run +================================================================================ + +Since moban version 0.4.2, you can select a group target to run. +For example, with `copy` target mixed with normal file list: + + + configuration: + template_dir: + - template-sources + targets: + - a.output: a.template.jj2 + - copy: + - simple.file.copy: file-in-template-sources-folder.txt + - "misc-1-copying/can-create-folder/if-not-exists.txt": file-in-template-sources-folder.txt + - "test-dir": dir-for-copying + - "test-recursive-dir": dir-for-recusive-copying/** + +you can do the following things:: + + $ moban -g copy + diff --git a/docs/level-19-moban-a-sub-group-in-targets/a.template.jj2 b/docs/level-19-moban-a-sub-group-in-targets/a.template.jj2 new file mode 100644 index 00000000..6b1b2f0f --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/a.template.jj2 @@ -0,0 +1 @@ +I will not be selected in level 19 diff --git a/docs/level-19-moban-a-sub-group-in-targets/misc-1-copying/can-create-folder/if-not-exists.txt b/docs/level-19-moban-a-sub-group-in-targets/misc-1-copying/can-create-folder/if-not-exists.txt new file mode 100644 index 00000000..16b14f5d --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/misc-1-copying/can-create-folder/if-not-exists.txt @@ -0,0 +1 @@ +test file diff --git a/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-copying/afile.txt b/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-copying/afile.txt new file mode 100644 index 00000000..d3c2168c --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-copying/afile.txt @@ -0,0 +1 @@ +dir for copying diff --git a/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-copying/sub_directory_is_not_copied/becuase_star_star_is_needed.txt b/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-copying/sub_directory_is_not_copied/becuase_star_star_is_needed.txt new file mode 100644 index 00000000..5dccc671 --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-copying/sub_directory_is_not_copied/becuase_star_star_is_needed.txt @@ -0,0 +1 @@ +Please look at .moban.yml diff --git a/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-recusive-copying/fileb.txt b/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-recusive-copying/fileb.txt new file mode 100644 index 00000000..a86a83fc --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-recusive-copying/fileb.txt @@ -0,0 +1 @@ +everything is copied diff --git a/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-recusive-copying/sub_directory_is_copied/because_star_star_is_specified.txt b/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-recusive-copying/sub_directory_is_copied/because_star_star_is_specified.txt new file mode 100644 index 00000000..12982a93 --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/template-sources/dir-for-recusive-copying/sub_directory_is_copied/because_star_star_is_specified.txt @@ -0,0 +1 @@ +dest_directory: source_directory/** diff --git a/docs/level-19-moban-a-sub-group-in-targets/template-sources/file-in-template-sources-folder.txt b/docs/level-19-moban-a-sub-group-in-targets/template-sources/file-in-template-sources-folder.txt new file mode 100644 index 00000000..16b14f5d --- /dev/null +++ b/docs/level-19-moban-a-sub-group-in-targets/template-sources/file-in-template-sources-folder.txt @@ -0,0 +1 @@ +test file diff --git a/moban/constants.py b/moban/constants.py index 920c5e54..94f0bcfa 100644 --- a/moban/constants.py +++ b/moban/constants.py @@ -35,7 +35,7 @@ LABEL_MOBANFILE = "mobanfile" LABEL_FORCE = "force" LABEL_VERSION = "version" - +LABEL_GROUP = "group" DEFAULT_CONFIGURATION_DIRNAME = ".%s.cd" % PROGRAM_NAME DEFAULT_TEMPLATE_DIRNAME = ".%s.td" % PROGRAM_NAME diff --git a/moban/exceptions.py b/moban/exceptions.py index 969ba709..c0ab48b9 100644 --- a/moban/exceptions.py +++ b/moban/exceptions.py @@ -20,3 +20,7 @@ class NoTemplate(Exception): class IncorrectDataInput(Exception): pass + + +class GroupTargetNotFound(Exception): + pass diff --git a/moban/main.py b/moban/main.py index 387b720a..619e0a61 100644 --- a/moban/main.py +++ b/moban/main.py @@ -106,6 +106,9 @@ def create_parser(): parser.add_argument( "-m", "--%s" % constants.LABEL_MOBANFILE, help="custom moban file" ) + parser.add_argument( + "-g", "--%s" % constants.LABEL_GROUP, help="a subset of targets" + ) parser.add_argument( constants.POSITIONAL_LABEL_TEMPLATE, metavar="template", diff --git a/moban/mobanfile/__init__.py b/moban/mobanfile/__init__.py index 5086f8ea..e788eaf9 100644 --- a/moban/mobanfile/__init__.py +++ b/moban/mobanfile/__init__.py @@ -5,12 +5,12 @@ from lml.utils import do_import -import moban.reporter as reporter -import moban.constants as constants +from moban import reporter +from moban import constants from moban import plugins from moban.repo import git_clone from moban.utils import merge, pip_install -from moban.mobanfile.targets import parse_targets +from moban.mobanfile.targets import parse_targets, extract_group_targets from moban.deprecated import deprecated from moban.definitions import GitRequire from moban.plugins.template import expand_template_directories @@ -44,6 +44,10 @@ def handle_moban_file_v1(moban_file_configurations, command_line_options): targets += legacy_copy_targets cli_target = extract_target(command_line_options) + group_target = command_line_options.get(constants.LABEL_GROUP) + if group_target: + # will raise exception when group target not found + targets = extract_group_targets(group_target, targets) if constants.LABEL_CONFIG in moban_file_configurations: merged_options = merge( @@ -68,18 +72,16 @@ def handle_moban_file_v1(moban_file_configurations, command_line_options): if extensions: plugins.ENGINES.register_extensions(extensions) - template_types = merged_options.get( - constants.LABEL_TEMPLATE_TYPES - ) + template_types = merged_options.get(constants.LABEL_TEMPLATE_TYPES) if template_types: plugins.ENGINES.register_options(template_types) if cli_target: number_of_templated_files = handle_targets( - merged_options, [cli_target]) + merged_options, [cli_target] + ) elif targets: - number_of_templated_files = handle_targets( - merged_options, targets) + number_of_templated_files = handle_targets(merged_options, targets) else: number_of_templated_files = 0 @@ -128,7 +130,6 @@ def handle_targets(merged_options, targets): target.set_template_type(primary_template_type) jobs_for_each_engine[primary_template_type].append(target) - print(target) count = 0 for template_type in jobs_for_each_engine.keys(): @@ -168,10 +169,10 @@ def extract_target(options): ) if config: result = { - constants.LABEL_TEMPLATE: template, - constants.LABEL_CONFIG: config, - constants.LABEL_OUTPUT: output, - } + constants.LABEL_TEMPLATE: template, + constants.LABEL_CONFIG: config, + constants.LABEL_OUTPUT: output, + } else: result = {output: template} diff --git a/moban/mobanfile/targets.py b/moban/mobanfile/targets.py index 442e9473..e32c8767 100644 --- a/moban/mobanfile/targets.py +++ b/moban/mobanfile/targets.py @@ -1,11 +1,20 @@ import uuid -from moban import constants +from moban import plugins, reporter, constants, exceptions from moban.definitions import TemplateTarget from moban.mobanfile.templates import handle_template -import moban.plugins as plugins -from moban import reporter + +def extract_group_targets(group, targets): + for target in targets: + if constants.LABEL_OUTPUT in target: + continue + + for group_name, group_targets in target.items(): + if isinstance(group_targets, str) is False and group_name == group: + # grouping by template type feature + return [{group_name: group_targets}] + raise exceptions.GroupTargetNotFound("%s is not found" % group) def parse_targets(options, targets): diff --git a/tests/mobanfile/test_targets.py b/tests/mobanfile/test_targets.py index 98dae8c7..5e70b17c 100644 --- a/tests/mobanfile/test_targets.py +++ b/tests/mobanfile/test_targets.py @@ -1,9 +1,10 @@ import os import uuid -from nose.tools import eq_ +from nose.tools import eq_, raises from moban.mobanfile import targets +from moban.exceptions import GroupTargetNotFound from moban.definitions import TemplateTarget TEMPLATE = "a.jj2" @@ -33,6 +34,25 @@ def test_handling_group_target(): eq_(expected, actual) +def test_extract_group_targets(): + test_targets = [ + {"copy": [{"output": "source"}], "copy1": [{"output1": "source1"}]} + ] + actual = targets.extract_group_targets("copy1", test_targets) + expected = [{"copy1": [{"output1": "source1"}]}] + eq_(expected, actual) + + +@raises(GroupTargetNotFound) +def test_extract_group_targets_not_found(): + test_targets = [ + {"copy": [{"output": "source"}], "copy1": [{"output1": "source1"}]} + ] + actual = targets.extract_group_targets("copy2", test_targets) + expected = [] + eq_(expected, actual) + + class TestImplicitTarget: def test_derive_template_type_from_target_template_file(self): @@ -122,9 +142,15 @@ def test_use_moban_default_template_from_options(self): def test_ad_hoc_type(self): target = dict(template=TEMPLATE, output=OUTPUT) - template_type = [{'base_type': 'jinja2'}, - {'options': [{'block_end_string': '*))'}, - {'block_start_string': '((*'}]}] + template_type = [ + {"base_type": "jinja2"}, + { + "options": [ + {"block_end_string": "*))"}, + {"block_start_string": "((*"}, + ] + }, + ] options = dict( configuration=CONFIGURATION, template_type=template_type, @@ -133,6 +159,7 @@ def test_ad_hoc_type(self): actual = list(targets._handle_explicit_target(options, target)) file_extension = uuid.uuid4().hex - expected = [TemplateTarget(TEMPLATE, CONFIGURATION, OUTPUT, - file_extension)] + expected = [ + TemplateTarget(TEMPLATE, CONFIGURATION, OUTPUT, file_extension) + ] eq_(actual, expected) diff --git a/tests/test_docs.py b/tests/test_docs.py index 44e4c664..6df7320c 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -237,6 +237,7 @@ def test_level_17_force_template_type_from_moban_file(self): def test_level_18_user_defined_template_types(self): from datetime import datetime + expected = "{date}\n".format(date=datetime.now().strftime("%Y-%m-%d")) folder = "level-18-user-defined-template-types" @@ -244,6 +245,24 @@ def test_level_18_user_defined_template_types(self): _verify_content("b.output", "shijie\n") + def test_level_19_without_group_target(self): + expected = "test file\n" + + folder = "level-19-moban-a-sub-group-in-targets" + self._raw_moban(["moban"], folder, expected, "simple.file") + _verify_content("a.output", "I will not be selected in level 19\n") + os.unlink("a.output") + + def test_level_19_with_group_target(self): + expected = "test file\n" + + folder = "level-19-moban-a-sub-group-in-targets" + self._raw_moban( + ["moban", "-g", "copy"], folder, expected, "simple.file" + ) + # make sure only copy target is executed + eq_(False, os.path.exists("a.output")) + def test_misc_1(self): expected = "test file\n"