properly handle symlinks as relative to the output dir
the code meant to make symlinks relative to the output directory, but only actually succeeded at it for targets in the root of the output directory; since we already check that the target is not breaking out of the instance, we can generate the output symlink relative to itself and fix the subdirred-symlink behavior Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
parent
8c75947088
commit
88b678931e
@ -177,6 +177,10 @@ class StaticSiteGenerator(object):
|
||||
def symlink_to_relative_dest(self, base_dir: str, source: str) -> str:
|
||||
"""Given a symlink, make sure it points to something inside the instance and provide its real destination.
|
||||
|
||||
This is made to be relative to the location of the symlink in all
|
||||
circumstances, in order to avoid breaking out of the instance or output
|
||||
dirs.
|
||||
|
||||
Args:
|
||||
base_dir: the full absolute path of the instance's pages dir, which the symlink destination must be in.
|
||||
source: the symlink to check
|
||||
@ -185,8 +189,8 @@ class StaticSiteGenerator(object):
|
||||
"""
|
||||
if not os.path.realpath(source).startswith(base_dir):
|
||||
raise ValueError(f"symlink destination {os.path.realpath(source)} is outside the instance!")
|
||||
# this symlink points to realpath inside base_dir, so relative to base_dir, the symlink dest is...
|
||||
return os.path.relpath(os.path.realpath(source), base_dir)
|
||||
# this symlink points to realpath inside base_dir, so relative to the source, the symlink dest is...
|
||||
return os.path.relpath(os.path.realpath(source), os.path.dirname(source))
|
||||
|
||||
|
||||
def build():
|
||||
|
1
tests/instance/pages/subdir/relative-symlink-to-parent.md
Symbolic link
1
tests/instance/pages/subdir/relative-symlink-to-parent.md
Symbolic link
@ -0,0 +1 @@
|
||||
../more-metadata.md
|
@ -52,6 +52,23 @@ def test_file_copy_symlink():
|
||||
assert os.path.islink(os.path.join(tmpdir, 'symlink-to-foo.txt'))
|
||||
|
||||
|
||||
def test_file_copy_subdir_symlink():
|
||||
"""Test the ability to sync a symlink in a subdirectory to the output dir."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
src_dir = os.path.join(HERE, 'instance')
|
||||
generator = ssg.StaticSiteGenerator(src_dir, tmpdir)
|
||||
# need to make the subdirectory as if the generator already did
|
||||
os.mkdir(os.path.join(tmpdir, 'subdir'))
|
||||
generator.build_file_in_destination(os.path.join(instance_dir, 'pages'), 'subdir',
|
||||
'relative-symlink-to-parent.md', tmpdir)
|
||||
# need to copy the destination for os.path.exists to be happy with this
|
||||
generator.build_file_in_destination(os.path.join(instance_dir, 'pages'), '', 'more-metadata.md', tmpdir)
|
||||
logger.warning("created symlink %s",
|
||||
os.readlink(os.path.join(tmpdir, 'subdir', 'relative-symlink-to-parent.md')))
|
||||
assert os.path.islink(os.path.join(tmpdir, 'subdir', 'relative-symlink-to-parent.md'))
|
||||
assert os.path.exists(os.path.join(tmpdir, 'subdir', 'relative-symlink-to-parent.md'))
|
||||
|
||||
|
||||
def test_file_copy_symlink_of_markdown_also_has_html_symlink():
|
||||
"""Test the ability to sync source and generated symlinks to the output dir."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
|
Loading…
x
Reference in New Issue
Block a user