diff --git a/docs/settings.rst b/docs/settings.rst index d021bcb0..70341a3f 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -602,7 +602,10 @@ Setting name (default value) What does it do? `THEME_STATIC_PATHS`. Default is `theme`. `THEME_STATIC_PATHS` (``['static']``) Static theme paths you want to copy. Default value is `static`, but if your theme has - other static paths, you can put them here. + other static paths, you can put them here. If files + or directories with the same names are included in + the paths defined in this settings, they will be + progressively overwritten. `CSS_FILE` (``'main.css'``) Specify the CSS file you want to load. ================================================ ===================================================== diff --git a/pelican/generators.py b/pelican/generators.py index 26fa40ea..d695c7c8 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -544,7 +544,7 @@ class StaticGenerator(Generator): """Copy all the paths from source to destination""" for path in paths: copy(path, source, os.path.join(output_path, destination), - final_path, overwrite=True) + final_path) def generate_context(self): self.staticfiles = [] diff --git a/pelican/tests/test_pelican.py b/pelican/tests/test_pelican.py index d6c0d8e9..e829e1a5 100644 --- a/pelican/tests/test_pelican.py +++ b/pelican/tests/test_pelican.py @@ -92,3 +92,23 @@ class TestPelican(LoggedTestCase): mute(True)(pelican.run)() dcmp = dircmp(self.temp_path, os.path.join(OUTPUT_PATH, 'custom')) self.assertFilesEqual(recursiveDiff(dcmp)) + + def test_theme_static_paths_copy(self): + # the same thing with a specified set of settings should work + settings = read_settings(path=SAMPLE_CONFIG, override={ + 'PATH': INPUT_PATH, + 'OUTPUT_PATH': self.temp_path, + 'THEME_STATIC_PATHS': [os.path.join(SAMPLES_PATH, 'very'), + os.path.join(SAMPLES_PATH, 'kinda'), + os.path.join(SAMPLES_PATH, 'theme_standard')] + }) + pelican = Pelican(settings=settings) + mute(True)(pelican.run)() + theme_output = os.path.join(self.temp_path, 'theme') + extra_path = os.path.join(theme_output, 'exciting', 'new', 'files') + + for file in ['a_stylesheet', 'a_template']: + self.assertTrue(os.path.exists(os.path.join(theme_output, file))) + + for file in ['wow!', 'boom!', 'bap!', 'zap!']: + self.assertTrue(os.path.exists(os.path.join(extra_path, file))) diff --git a/pelican/utils.py b/pelican/utils.py index 054c1f40..d306de65 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -256,7 +256,7 @@ def slugify(value, substitutions=()): return value.decode('ascii') -def copy(path, source, destination, destination_path=None, overwrite=False): +def copy(path, source, destination, destination_path=None): """Copy path from origin to destination. The function is able to copy either files or directories. @@ -265,8 +265,6 @@ def copy(path, source, destination, destination_path=None, overwrite=False): :param source: the source dir :param destination: the destination dir :param destination_path: the destination path (optional) - :param overwrite: whether to overwrite the destination if already exists - or not """ if not destination_path: destination_path = path @@ -275,16 +273,24 @@ def copy(path, source, destination, destination_path=None, overwrite=False): destination_ = os.path.abspath( os.path.expanduser(os.path.join(destination, destination_path))) + def recurse(source, destination): + for entry in os.listdir(source): + entry_path = os.path.join(source, entry) + if os.path.isdir(entry_path): + entry_dest = os.path.join(destination, entry) + if os.path.exists(entry_dest): + if not os.path.isdir(entry_dest): + raise IOError('Failed to copy {0} a directory.' + .format(entry_dest)) + recurse(entry_path, entry_dest) + else: + shutil.copytree(entry_path, entry_dest) + else: + shutil.copy(entry_path, destination) + + if os.path.isdir(source_): - try: - shutil.copytree(source_, destination_) - logger.info('copying %s to %s' % (source_, destination_)) - except OSError: - if overwrite: - shutil.rmtree(destination_) - shutil.copytree(source_, destination_) - logger.info('replacement of %s with %s' % (source_, - destination_)) + recurse(source_, destination_) elif os.path.isfile(source_): dest_dir = os.path.dirname(destination_) diff --git a/samples/kinda/exciting/new/files/zap! b/samples/kinda/exciting/new/files/zap! new file mode 100644 index 00000000..e69de29b diff --git a/samples/kinda/exciting/old b/samples/kinda/exciting/old new file mode 100644 index 00000000..e69de29b diff --git a/samples/theme_standard/a_stylesheet b/samples/theme_standard/a_stylesheet new file mode 100644 index 00000000..e69de29b diff --git a/samples/theme_standard/a_template b/samples/theme_standard/a_template new file mode 100644 index 00000000..e69de29b diff --git a/samples/very/exciting/new/files/bap! b/samples/very/exciting/new/files/bap! new file mode 100644 index 00000000..e69de29b diff --git a/samples/very/exciting/new/files/boom! b/samples/very/exciting/new/files/boom! new file mode 100644 index 00000000..e69de29b diff --git a/samples/very/exciting/new/files/wow! b/samples/very/exciting/new/files/wow! new file mode 100644 index 00000000..e69de29b