From 13d29a8583649f9cacd70ee8d20cb8dcdc68ad71 Mon Sep 17 00:00:00 2001 From: Jason McIntosh Date: Sun, 21 Jun 2026 20:09:22 -0400 Subject: [PATCH 1/2] Point index.html symlink at recent.html by basename (#54) The docroot/index.html symlink was created with recent_file's full path as its target. When the docroot was named by a relative path, that target ("docroot/recent.html") resolved to docroot/docroot/recent.html from inside the docroot, leaving index.html dangling. Even with an absolute path the link was non-portable, breaking if the tree moved. index.html sits beside recent.html in the docroot, so link to it by basename. The relative sibling target is correct for absolute and relative configs alike and survives the tree being moved. Adds t/index_symlink.t asserting the link targets "recent.html" and resolves. Co-Authored-By: Claude Opus 4.8 --- lib/Plerd.pm | 5 ++++- t/index_symlink.t | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 t/index_symlink.t diff --git a/lib/Plerd.pm b/lib/Plerd.pm index eba0ec5..dd6bf1b 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -562,7 +562,10 @@ sub publish_recent_page { $self->publication_directory, "index.html.$$.tmp" ); $temp_link->remove if -e $temp_link || -l $temp_link; - if ( symlink $self->recent_file, $temp_link ) { + # Link to recent.html by basename: index.html sits beside it in the docroot, + # so a relative sibling target stays correct whether the docroot is named by + # an absolute or relative path, and survives the whole tree being moved. + if ( symlink $self->recent_file->basename, $temp_link ) { rename "$temp_link", "$index_file" or warn "Couldn't move the index.html symlink into place: $!\n"; } diff --git a/t/index_symlink.t b/t/index_symlink.t new file mode 100644 index 0000000..9df7af3 --- /dev/null +++ b/t/index_symlink.t @@ -0,0 +1,47 @@ +use warnings; +use strict; +use Test::More; +use Path::Class::Dir; +use Path::Class::File; +use URI; + +use FindBin; +use lib "$FindBin::Bin/../lib"; + +use_ok( 'Plerd' ); +use Plerd::Init; + +# Regression test for GitHub issue #54: the docroot/index.html symlink must +# point at its sibling "recent.html" by basename, not at a path that includes +# the docroot directory. A target like "docroot/recent.html" resolves to +# docroot/docroot/recent.html from inside docroot and leaves index.html broken. + +my $blog_dir = Path::Class::Dir->new( "$FindBin::Bin/index_symlink_blog" ); +$blog_dir->rmtree; +Plerd::Init::initialize( $blog_dir->stringify, 0 ); + +Path::Class::File->new( $blog_dir, 'source', '2021-01-01-hello.md' )->spew( + iomode => '>:encoding(utf8)', + "title: Hello\n\nBody.\n", +); + +my $plerd = Plerd->new( + path => $blog_dir->stringify, + title => 'Test Blog', + author_name => 'Nobody', + author_email => 'nobody@example.com', + base_uri => URI->new( 'http://blog.example.com/' ), +); + +$plerd->publish_all; + +my $index = Path::Class::File->new( $blog_dir, 'docroot', 'index.html' ); + +ok( -l $index, 'docroot/index.html is a symlink.' ); +is( readlink( "$index" ), 'recent.html', + 'index.html points at its sibling recent.html by basename.' ); +ok( -e $index, 'index.html resolves to an existing file.' ); + +$blog_dir->rmtree; + +done_testing(); From d890b18aaa392ad9346718d8125f72b76cc37604 Mon Sep 17 00:00:00 2001 From: Jason McIntosh Date: Mon, 22 Jun 2026 10:53:07 -0400 Subject: [PATCH 2/2] Drop explanatory comment on the index.html symlink target (#54) Per review, remove the three-line comment added above the symlink call. Co-Authored-By: Claude Opus 4.8 --- lib/Plerd.pm | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/Plerd.pm b/lib/Plerd.pm index dd6bf1b..31ac8e3 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -562,9 +562,6 @@ sub publish_recent_page { $self->publication_directory, "index.html.$$.tmp" ); $temp_link->remove if -e $temp_link || -l $temp_link; - # Link to recent.html by basename: index.html sits beside it in the docroot, - # so a relative sibling target stays correct whether the docroot is named by - # an absolute or relative path, and survives the whole tree being moved. if ( symlink $self->recent_file->basename, $temp_link ) { rename "$temp_link", "$index_file" or warn "Couldn't move the index.html symlink into place: $!\n";