Add sphinx.util.fileutil.copy_asset()

This commit is contained in:
Takeshi KOMIYA 2016-06-27 11:54:42 +09:00
parent 17cd06f237
commit 07ddff9933
2 changed files with 80 additions and 2 deletions

View File

@ -10,7 +10,9 @@
"""
import os
import codecs
from sphinx.util.osutil import copyfile
import posixpath
from docutils.utils import relative_path
from sphinx.util.osutil import copyfile, ensuredir, walk
def copy_asset_file(source, destination, context={}, renderer=None):
@ -37,3 +39,34 @@ def copy_asset_file(source, destination, context={}, renderer=None):
fdst.write(renderer.render_string(fsrc.read(), context))
else:
copyfile(source, destination)
def copy_asset(source, destination, excluded=lambda path: False, context={}, renderer=None):
"""Copy asset files to destination recursively.
On copying, it expands the template variables if the asset is a template file.
:param source: The path to source file or directory
:param destination: The path to destination directory
:param excluded: The matcher to determine the given path should be copied or not
:param context: The template variables
:param renderer: The template engine
"""
ensuredir(destination)
if os.path.isfile(source):
copy_asset_file(source, destination, context, renderer)
return
for root, dirs, files in walk(source):
reldir = relative_path(source, root)
for dir in dirs[:]:
if excluded(posixpath.join(reldir, dir)):
dirs.remove(dir)
else:
ensuredir(posixpath.join(destination, reldir, dir))
for filename in files:
if not excluded(posixpath.join(reldir, filename)):
copy_asset_file(posixpath.join(root, filename),
posixpath.join(destination, reldir),
context, renderer)

View File

@ -8,7 +8,7 @@
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.fileutil import copy_asset, copy_asset_file
from sphinx.jinja2glue import BuiltinTemplateLoader
from mock import Mock
@ -56,3 +56,48 @@ def test_copy_asset_file(tmpdir):
copy_asset_file(src, subdir, {'var1': 'template'}, renderer)
assert (subdir / 'asset.txt').exists()
assert (subdir / 'asset.txt').text() == '# template data'
@with_tempdir
def test_copy_asset(tmpdir):
renderer = DummyTemplateLoader()
# prepare source files
source = (tmpdir / 'source')
source.makedirs()
(source / 'index.rst').write_text('index.rst')
(source / 'foo.rst_t').write_text('{{var1}}.rst')
(source / '_static').makedirs()
(source / '_static' / 'basic.css').write_text('basic.css')
(source / '_templates').makedirs()
(source / '_templates' / 'layout.html').write_text('layout.html')
(source / '_templates' / 'sidebar.html_t').write_text('sidebar: {{var2}}')
# copy a single file
assert not (tmpdir / 'test1').exists()
copy_asset(source / 'index.rst', tmpdir / 'test1')
assert (tmpdir / 'test1').exists()
assert (tmpdir / 'test1/index.rst').exists()
# copy directories
destdir = tmpdir / 'test2'
copy_asset(source, destdir, context=dict(var1='bar', var2='baz'), renderer=renderer)
assert (destdir / 'index.rst').exists()
assert (destdir / 'foo.rst').exists()
assert (destdir / 'foo.rst').text() == 'bar.rst'
assert (destdir / '_static' / 'basic.css').exists()
assert (destdir / '_templates' / 'layout.html').exists()
assert (destdir / '_templates' / 'sidebar.html').exists()
assert (destdir / '_templates' / 'sidebar.html').text() == 'sidebar: baz'
# copy with exclusion
def excluded(path):
return ('sidebar.html' in path or 'basic.css' in path)
destdir = tmpdir / 'test3'
copy_asset(source, destdir, excluded, renderer=renderer)
assert (destdir / 'index.rst').exists()
assert (destdir / 'foo.rst').exists()
assert not (destdir / '_static' / 'basic.css').exists()
assert (destdir / '_templates' / 'layout.html').exists()
assert not (destdir / '_templates' / 'sidebar.html').exists()