From 7dd2cd0abf5830f76eb865007086bcc98254bd91 Mon Sep 17 00:00:00 2001 From: chfw Date: Wed, 11 Jul 2018 18:33:46 +0100 Subject: [PATCH 1/5] :sparkles: allow copy a directory without its subdirectories. #32 --- moban/copier.py | 28 +++++++++++++++++++++++++--- tests/test_copier.py | 11 +++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/moban/copier.py b/moban/copier.py index 5e02fd22..8f6e7de0 100644 --- a/moban/copier.py +++ b/moban/copier.py @@ -17,9 +17,18 @@ def copy_files(self, file_list): self._file_count += 1 src_path = self._get_src_file(src) if src_path is None: - reporter.report_error_message( - "{0} cannot be found".format(src) - ) + if src.endswith('**'): + src_path = self._get_src_file(src[:-3]) + if src_path: + self._do_copy_dir_recursively(src[:-3], src_path, dest) + else: + reporter.report_error_message( + "{0} cannot be found".format(src) + ) + else: + reporter.report_error_message( + "{0} cannot be found".format(src) + ) elif os.path.isdir(src_path): self._do_copy_dir(src, src_path, dest) elif HASH_STORE.are_two_file_different(src_path, dest): @@ -43,6 +52,19 @@ def _get_src_file(self, src): return None def _do_copy_dir(self, source, actual_source_path, dest): + new_file_pair = [] + for file_name in os.listdir(actual_source_path): + real_src_file = os.path.join(actual_source_path, file_name) + if os.path.isfile(real_src_file): + src_file_under_dir = os.path.join(source, file_name) + dest_file_under_dir = os.path.join(dest, file_name) + new_file_pair.append( + {dest_file_under_dir: src_file_under_dir} + ) + if len(new_file_pair) > 0: + self.copy_files(new_file_pair) + + def _do_copy_dir_recursively(self, source, actual_source_path, dest): new_file_pair = [] for file_name in os.listdir(actual_source_path): src_file_under_dir = os.path.join(source, file_name) diff --git a/tests/test_copier.py b/tests/test_copier.py index b00cbf2a..365f64b9 100644 --- a/tests/test_copier.py +++ b/tests/test_copier.py @@ -61,5 +61,16 @@ def test_copy_dir(reporter): file_list = [{test_dir: "copier-directory"}] copier.copy_files(file_list) copier.copy_files(file_list) # not called the second time + eq_(reporter.call_count, 1) + shutil.rmtree(test_dir) + + +@patch("moban.reporter.report_copying") +def test_copy_dir_recusively(reporter): + test_dir = "/tmp/copy-a-directory" + copier = Copier([os.path.join("tests", "fixtures")]) + file_list = [{test_dir: "copier-directory/**"}] + copier.copy_files(file_list) + copier.copy_files(file_list) # not called the second time eq_(reporter.call_count, 2) shutil.rmtree(test_dir) From 7dc4b44fa835bd632722f1f8d397602d516172ee Mon Sep 17 00:00:00 2001 From: chfw Date: Wed, 11 Jul 2018 18:40:52 +0100 Subject: [PATCH 2/5] :books: pump version number --- .moban.cd/changelog.yml | 6 ++++++ .moban.cd/moban.yml | 4 ++-- CHANGELOG.rst | 9 +++++++++ docs/conf.py | 2 +- moban/_version.py | 2 +- setup.py | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/.moban.cd/changelog.yml b/.moban.cd/changelog.yml index 163dea0b..f6c7f274 100644 --- a/.moban.cd/changelog.yml +++ b/.moban.cd/changelog.yml @@ -1,6 +1,12 @@ name: moban organisation: moremoban releases: +- changes: + - action: Added + details: + - "`#32`: option 1 copy a directory without its subdirectories." + date: pending release + version: 0.2.4 - changes: - action: Added details: diff --git a/.moban.cd/moban.yml b/.moban.cd/moban.yml index effc4a8d..09551632 100644 --- a/.moban.cd/moban.yml +++ b/.moban.cd/moban.yml @@ -3,8 +3,8 @@ organisation: moremoban author: C. W. contact: wangc_2011@hotmail.com license: MIT -version: 0.2.3 -current_version: 0.2.3 +version: 0.2.4 +current_version: 0.2.4 release: 0.2.3 branch: master command_line_interface: "moban" diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a6af8ce0..7799ebda 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,15 @@ Change log ================================================================================ +0.2.4 - pending release +-------------------------------------------------------------------------------- + +Added +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#. `#32 `_: option 1 copy a + directory without its subdirectories. + 0.2.3 - 10-07-2018 -------------------------------------------------------------------------------- diff --git a/docs/conf.py b/docs/conf.py index 0a99972e..c338d841 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,7 +30,7 @@ # The short X.Y version version = u'0.2.3' # The full version, including alpha/beta/rc tags -release = u'0.2.3' +release = u'0.2.4' # -- General configuration --------------------------------------------------- diff --git a/moban/_version.py b/moban/_version.py index 989d5b6f..bf2a9d1f 100644 --- a/moban/_version.py +++ b/moban/_version.py @@ -1,2 +1,2 @@ -__version__ = "0.2.3" +__version__ = "0.2.4" __author__ = "C. W." diff --git a/setup.py b/setup.py index 5429ff35..4a594c10 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ NAME = 'moban' AUTHOR = 'C. W.' -VERSION = '0.2.3' +VERSION = '0.2.4' EMAIL = 'wangc_2011@hotmail.com' LICENSE = 'MIT' ENTRY_POINTS = { From 3787d657655f74004b771cad1190ed39d25886d9 Mon Sep 17 00:00:00 2001 From: chfw Date: Thu, 12 Jul 2018 08:17:21 +0100 Subject: [PATCH 3/5] :books: update documentation --- docs/misc-1-copying-templates/.moban.yml | 2 ++ docs/misc-1-copying-templates/README.rst | 22 +++++++++++++++++++ .../dir-for-copying/afile.txt | 1 + .../becuase_star_star_is_needed.txt | 1 + .../dir-for-recusive-copying/fileb.txt | 1 + .../because_star_star_is_specified.txt | 1 + moban/copier.py | 5 +++-- 7 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 docs/misc-1-copying-templates/template-sources/dir-for-copying/afile.txt create mode 100644 docs/misc-1-copying-templates/template-sources/dir-for-copying/sub_directory_is_not_copied/becuase_star_star_is_needed.txt create mode 100644 docs/misc-1-copying-templates/template-sources/dir-for-recusive-copying/fileb.txt create mode 100644 docs/misc-1-copying-templates/template-sources/dir-for-recusive-copying/sub_directory_is_copied/because_star_star_is_specified.txt diff --git a/docs/misc-1-copying-templates/.moban.yml b/docs/misc-1-copying-templates/.moban.yml index 095e52b8..71d8a3f2 100644 --- a/docs/misc-1-copying-templates/.moban.yml +++ b/docs/misc-1-copying-templates/.moban.yml @@ -4,3 +4,5 @@ configuration: 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/misc-1-copying-templates/README.rst b/docs/misc-1-copying-templates/README.rst index 3e112b1c..42b43c7e 100644 --- a/docs/misc-1-copying-templates/README.rst +++ b/docs/misc-1-copying-templates/README.rst @@ -4,4 +4,26 @@ Misc 1: copying templates With `.moban.yml`, you can copy templates to your destination. +Please be aware that, your templates and template folder have to be inside +declared template folders. It does not copy any file or folder. + +Here is example moban file for copying:: + + configuration: + template_dir: + - template-sources + 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/** + + +template copy does: + + +#. copies any template inside pre-declared template directory to anywhere. moban will + create directory if needed. +#. copies any directory to anywhere. If "**" is followed, moban attempts to do + recursive copying. diff --git a/docs/misc-1-copying-templates/template-sources/dir-for-copying/afile.txt b/docs/misc-1-copying-templates/template-sources/dir-for-copying/afile.txt new file mode 100644 index 00000000..d3c2168c --- /dev/null +++ b/docs/misc-1-copying-templates/template-sources/dir-for-copying/afile.txt @@ -0,0 +1 @@ +dir for copying diff --git a/docs/misc-1-copying-templates/template-sources/dir-for-copying/sub_directory_is_not_copied/becuase_star_star_is_needed.txt b/docs/misc-1-copying-templates/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/misc-1-copying-templates/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/misc-1-copying-templates/template-sources/dir-for-recusive-copying/fileb.txt b/docs/misc-1-copying-templates/template-sources/dir-for-recusive-copying/fileb.txt new file mode 100644 index 00000000..a86a83fc --- /dev/null +++ b/docs/misc-1-copying-templates/template-sources/dir-for-recusive-copying/fileb.txt @@ -0,0 +1 @@ +everything is copied diff --git a/docs/misc-1-copying-templates/template-sources/dir-for-recusive-copying/sub_directory_is_copied/because_star_star_is_specified.txt b/docs/misc-1-copying-templates/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/misc-1-copying-templates/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/moban/copier.py b/moban/copier.py index 8f6e7de0..24f87f9f 100644 --- a/moban/copier.py +++ b/moban/copier.py @@ -18,12 +18,13 @@ def copy_files(self, file_list): src_path = self._get_src_file(src) if src_path is None: if src.endswith('**'): - src_path = self._get_src_file(src[:-3]) + source_dir = src[:-3] + src_path = self._get_src_file(source_dir) if src_path: self._do_copy_dir_recursively(src[:-3], src_path, dest) else: reporter.report_error_message( - "{0} cannot be found".format(src) + "{0} cannot be found".format(source_dir) ) else: reporter.report_error_message( From 13c7071cb0016dc5011082bfb9a9c5ef2f2adac3 Mon Sep 17 00:00:00 2001 From: chfw Date: Thu, 12 Jul 2018 08:31:59 +0100 Subject: [PATCH 4/5] :hammer: code refactoring --- moban/copier.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/moban/copier.py b/moban/copier.py index 24f87f9f..15750177 100644 --- a/moban/copier.py +++ b/moban/copier.py @@ -14,14 +14,13 @@ def __init__(self, template_dirs): def copy_files(self, file_list): for dest, src in _iterate_list_of_dicts(file_list): - self._file_count += 1 src_path = self._get_src_file(src) if src_path is None: if src.endswith('**'): source_dir = src[:-3] src_path = self._get_src_file(source_dir) if src_path: - self._do_copy_dir_recursively(src[:-3], src_path, dest) + self._copy_dir_recursively(src[:-3], src_path, dest) else: reporter.report_error_message( "{0} cannot be found".format(source_dir) @@ -31,9 +30,10 @@ def copy_files(self, file_list): "{0} cannot be found".format(src) ) elif os.path.isdir(src_path): - self._do_copy_dir(src, src_path, dest) + self._copy_dir(src, src_path, dest) elif HASH_STORE.are_two_file_different(src_path, dest): - self._do_copy(src_path, dest) + self._increment_file_count() + self._copy(src_path, dest) def number_of_copied_files(self): return self._count @@ -52,11 +52,12 @@ def _get_src_file(self, src): else: return None - def _do_copy_dir(self, source, actual_source_path, dest): + def _copy_dir(self, source, actual_source_path, dest): new_file_pair = [] for file_name in os.listdir(actual_source_path): real_src_file = os.path.join(actual_source_path, file_name) if os.path.isfile(real_src_file): + self._increment_file_count() src_file_under_dir = os.path.join(source, file_name) dest_file_under_dir = os.path.join(dest, file_name) new_file_pair.append( @@ -65,9 +66,10 @@ def _do_copy_dir(self, source, actual_source_path, dest): if len(new_file_pair) > 0: self.copy_files(new_file_pair) - def _do_copy_dir_recursively(self, source, actual_source_path, dest): + def _copy_dir_recursively(self, source, actual_source_path, dest): new_file_pair = [] for file_name in os.listdir(actual_source_path): + self._increment_file_count() src_file_under_dir = os.path.join(source, file_name) dest_file_under_dir = os.path.join(dest, file_name) new_file_pair.append( @@ -75,7 +77,7 @@ def _do_copy_dir_recursively(self, source, actual_source_path, dest): ) self.copy_files(new_file_pair) - def _do_copy(self, src_path, dest): + def _copy(self, src_path, dest): dest_folder = os.path.dirname(dest) if dest_folder: utils.mkdir_p(dest_folder) @@ -83,6 +85,9 @@ def _do_copy(self, src_path, dest): shutil.copy(src_path, dest) self._count = self._count + 1 + def _increment_file_count(self): + self._file_count += 1 + def _iterate_list_of_dicts(list_of_dict): for adict in list_of_dict: From b586fbf71e089d844ac9569228dae8996c77fa4f Mon Sep 17 00:00:00 2001 From: chfw Date: Thu, 12 Jul 2018 18:25:52 +0100 Subject: [PATCH 5/5] :microscope: better test coverage --- tests/test_copier.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_copier.py b/tests/test_copier.py index 365f64b9..68d1b6b2 100644 --- a/tests/test_copier.py +++ b/tests/test_copier.py @@ -65,6 +65,15 @@ def test_copy_dir(reporter): shutil.rmtree(test_dir) +@patch("moban.reporter.report_error_message") +def test_copy_dir_with_error(reporter): + test_dir = "/tmp/copy-a-directory" + copier = Copier([os.path.join("tests", "fixtures")]) + file_list = [{test_dir: "copier-directory-not-exist"}] + copier.copy_files(file_list) + eq_(reporter.call_count, 1) + + @patch("moban.reporter.report_copying") def test_copy_dir_recusively(reporter): test_dir = "/tmp/copy-a-directory" @@ -74,3 +83,12 @@ def test_copy_dir_recusively(reporter): copier.copy_files(file_list) # not called the second time eq_(reporter.call_count, 2) shutil.rmtree(test_dir) + + +@patch("moban.reporter.report_error_message") +def test_copy_dir_recusively_with_error(reporter): + test_dir = "/tmp/copy-a-directory" + copier = Copier([os.path.join("tests", "fixtures")]) + file_list = [{test_dir: "copier-directory-not-exist/**"}] + copier.copy_files(file_list) + eq_(reporter.call_count, 1)