diff options
-rw-r--r-- | IkiWiki/Plugin/autoindex.pm | 102 | ||||
-rwxr-xr-x | t/autoindex.t | 87 |
2 files changed, 131 insertions, 58 deletions
diff --git a/IkiWiki/Plugin/autoindex.pm b/IkiWiki/Plugin/autoindex.pm index 11595e217..78571b276 100644 --- a/IkiWiki/Plugin/autoindex.pm +++ b/IkiWiki/Plugin/autoindex.pm @@ -7,8 +7,10 @@ use IkiWiki 3.00; use Encode; sub import { + hook(type => "checkconfig", id => "autoindex", call => \&checkconfig); hook(type => "getsetup", id => "autoindex", call => \&getsetup); hook(type => "refresh", id => "autoindex", call => \&refresh); + IkiWiki::loadplugin("transient"); } sub getsetup () { @@ -17,17 +19,47 @@ sub getsetup () { safe => 1, rebuild => 0, }, + autoindex_commit => { + type => "boolean", + example => 1, + default => 1, + description => "commit autocreated index pages", + safe => 1, + rebuild => 0, + }, +} + +sub checkconfig () { + if (! defined $config{autoindex_commit}) { + $config{autoindex_commit} = 1; + } } sub genindex ($) { my $page=shift; my $file=newpagefile($page, $config{default_pageext}); - my $template=template("autoindex.tmpl"); - $template->param(page => $page); - writefile($file, $config{srcdir}, $template->output); - if ($config{rcs}) { - IkiWiki::rcs_add($file); - } + + add_autofile($file, "autoindex", sub { + my $message = sprintf(gettext("creating index page %s"), + $page); + debug($message); + + my $dir = $config{srcdir}; + if (! $config{autoindex_commit}) { + $dir = $IkiWiki::Plugin::transient::transientdir; + } + + my $template = template("autoindex.tmpl"); + $template->param(page => $page); + writefile($file, $dir, $template->output); + + if ($config{rcs} && $config{autoindex_commit}) { + IkiWiki::disable_commit_hook(); + IkiWiki::rcs_add($file); + IkiWiki::rcs_commit_staged(message => $message); + IkiWiki::enable_commit_hook(); + } + }); } sub refresh () { @@ -39,6 +71,7 @@ sub refresh () { my (%pages, %dirs); foreach my $dir ($config{srcdir}, @{$config{underlaydirs}}, $config{underlaydir}) { + next if $dir eq $IkiWiki::Plugin::transient::transientdir; chdir($dir) || next; find({ @@ -66,60 +99,39 @@ sub refresh () { chdir($origdir) || die "chdir $origdir: $!"; } - + + # Compatibility code. + # + # {deleted} contains pages that have been deleted at some point. + # This plugin used to delete from the hash sometimes, but no longer + # does; in [[todo/autoindex_should_use_add__95__autofile]] Joey + # thought the old behaviour was probably a bug. + # + # The effect of listing a page in {deleted} was to avoid re-creating + # it; we migrate these pages to {autofile} which has the same effect. + # However, {autofile} contains source filenames whereas {deleted} + # contains page names. my %deleted; if (ref $wikistate{autoindex}{deleted}) { %deleted=%{$wikistate{autoindex}{deleted}}; + delete $wikistate{autoindex}{deleted}; } elsif (ref $pagestate{index}{autoindex}{deleted}) { - # compatability code + # an even older version %deleted=%{$pagestate{index}{autoindex}{deleted}}; delete $pagestate{index}{autoindex}; } if (keys %deleted) { foreach my $dir (keys %deleted) { - # remove deleted page state if the deleted page is re-added, - # or if all its subpages are deleted - if ($deleted{$dir} && (exists $pages{$dir} || - ! grep /^$dir\/.*/, keys %pages)) { - delete $deleted{$dir}; - } + my $file=newpagefile($dir, $config{default_pageext}); + $wikistate{autoindex}{autofile}{$file} = 1; } - $wikistate{autoindex}{deleted}=\%deleted; } - my @needed; foreach my $dir (keys %dirs) { - if (! exists $pages{$dir} && ! $deleted{$dir} && - grep /^$dir\/.*/, keys %pages) { - if (exists $IkiWiki::pagemtime{$dir}) { - # This page must have just been deleted, so - # don't re-add it. And remember it was - # deleted. - if (! ref $wikistate{autoindex}{deleted}) { - $wikistate{autoindex}{deleted}={}; - } - ${$wikistate{autoindex}{deleted}}{$dir}=1; - } - else { - push @needed, $dir; - } - } - } - - if (@needed) { - if ($config{rcs}) { - IkiWiki::disable_commit_hook(); - } - foreach my $page (@needed) { - genindex($page); - } - if ($config{rcs}) { - IkiWiki::rcs_commit_staged( - message => gettext("automatic index generation"), - ); - IkiWiki::enable_commit_hook(); + if (! exists $pages{$dir} && grep /^$dir\/.*/, keys %pages) { + genindex($dir); } } } diff --git a/t/autoindex.t b/t/autoindex.t index 9bef2415a..b38be8313 100755 --- a/t/autoindex.t +++ b/t/autoindex.t @@ -3,10 +3,11 @@ package IkiWiki; use warnings; use strict; -use Test::More tests => 17; +use Test::More tests => 38; BEGIN { use_ok("IkiWiki"); } BEGIN { use_ok("IkiWiki::Render"); } +BEGIN { use_ok("IkiWiki::Plugin::aggregate"); } BEGIN { use_ok("IkiWiki::Plugin::autoindex"); } BEGIN { use_ok("IkiWiki::Plugin::html"); } BEGIN { use_ok("IkiWiki::Plugin::mdwn"); } @@ -25,6 +26,7 @@ $config{userdir} = "users"; $config{tagbase} = "tags"; $config{default_pageext} = "mdwn"; $config{wiki_file_prune_regexps} = [qr/^\./]; +$config{autoindex_commit} = 0; is(checkconfig(), 1); @@ -32,7 +34,8 @@ is(checkconfig(), 1); %pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks= %destsources=%renderedfiles=%pagecase=%pagestate=(); -# pages that (we claim) were deleted in an earlier pass +# Pages that (we claim) were deleted in an earlier pass. We're using deleted, +# not autofile, to test backwards compat. $wikistate{autoindex}{deleted}{deleted} = 1; $wikistate{autoindex}{deleted}{expunged} = 1; $wikistate{autoindex}{deleted}{reinstated} = 1; @@ -45,29 +48,87 @@ foreach my $page (qw(tags/numbers deleted/bar reinstated reinstated/foo gone/bar writefile("$page.html", "t/tmp", "your ad here"); } +# a directory containing only an internal page shouldn't be indexed +$pagesources{"has_internal/internal"} = "has_internal/internal._aggregated"; +$pagemtime{"has_internal/internal"} = 123456789; +$pagectime{"has_internal/internal"} = 123456789; +writefile("has_internal/internal._aggregated", "t/tmp", "this page is internal"); + +# a directory containing only an attachment should be indexed +$pagesources{"attached/pie.jpg"} = "attached/pie.jpg"; +$pagemtime{"attached/pie.jpg"} = 123456789; +$pagectime{"attached/pie.jpg"} = 123456789; +writefile("attached/pie.jpg", "t/tmp", "I lied, this isn't a real JPEG"); + # "gone" disappeared just before this refresh pass so it still has a mtime $pagemtime{gone} = $pagectime{gone} = 1000000; +my %pages; +my @del; + IkiWiki::Plugin::autoindex::refresh(); -# these pages are still on record as having been deleted, because they have +# this page is still on record as having been deleted, because it has # a reason to be re-created -is($wikistate{autoindex}{deleted}{deleted}, 1); -is($wikistate{autoindex}{deleted}{gone}, 1); +is($wikistate{autoindex}{autofile}{"deleted.mdwn"}, 1); +is($autofiles{"deleted.mdwn"}{plugin}, "autoindex"); +%pages = (); +@del = (); +IkiWiki::gen_autofile("deleted.mdwn", \%pages, \@del); +is_deeply(\%pages, {}) || diag explain \%pages; +is_deeply(\@del, []) || diag explain \@del; ok(! -f "t/tmp/deleted.mdwn"); + +# this page is tried as an autofile, but because it'll be in @del, it's not +# actually created +ok(! exists $wikistate{autoindex}{autofile}{"gone.mdwn"}); +%pages = (); +@del = ("gone.mdwn"); +is($autofiles{"gone.mdwn"}{plugin}, "autoindex"); +IkiWiki::gen_autofile("gone.mdwn", \%pages, \@del); +is_deeply(\%pages, {}) || diag explain \%pages; +is_deeply(\@del, ["gone.mdwn"]) || diag explain \@del; ok(! -f "t/tmp/gone.mdwn"); -# this page does not exist and has no reason to be re-created, so we forget -# about it - it will be re-created if it gains sub-pages -ok(! exists $wikistate{autoindex}{deleted}{expunged}); +# this page does not exist and has no reason to be re-created, but we no longer +# have a special case for that - see +# [[todo/autoindex_should_use_add__95__autofile]] - so it won't be created +# even if it gains subpages later +is($wikistate{autoindex}{autofile}{"expunged.mdwn"}, 1); +ok(! exists $autofiles{"expunged.mdwn"}); ok(! -f "t/tmp/expunged.mdwn"); -# this page was re-created, so it drops off the radar -ok(! exists $wikistate{autoindex}{deleted}{reinstated}); +# a directory containing only an internal page shouldn't be indexed +ok(! exists $wikistate{autoindex}{autofile}{"has_internal.mdwn"}); +ok(! exists $autofiles{"has_internal.mdwn"}); +ok(! -f "t/tmp/has_internal.mdwn"); + +# this page was re-created, but that no longer gets a special case +# (see [[todo/autoindex_should_use_add__95__autofile]]) so it's the same as +# deleted +is($wikistate{autoindex}{autofile}{"reinstated.mdwn"}, 1); +ok(! exists $autofiles{"reinstated.mdwn"}); ok(! -f "t/tmp/reinstated.mdwn"); -# needs creating -ok(! exists $wikistate{autoindex}{deleted}{tags}); -ok(-s "t/tmp/tags.mdwn"); +# needs creating (deferred; part of the autofile mechanism now) +ok(! exists $wikistate{autoindex}{autofile}{"tags.mdwn"}); +%pages = (); +@del = (); +is($autofiles{"tags.mdwn"}{plugin}, "autoindex"); +IkiWiki::gen_autofile("tags.mdwn", \%pages, \@del); +is_deeply(\%pages, {"t/tmp/tags" => 1}) || diag explain \%pages; +is_deeply(\@del, []) || diag explain \@del; +ok(! -s "t/tmp/tags.mdwn"); +ok(-s "t/tmp/.ikiwiki/transient/tags.mdwn"); + +# needs creating because of an attachment +ok(! exists $wikistate{autoindex}{autofile}{"attached.mdwn"}); +%pages = (); +@del = (); +is($autofiles{"attached.mdwn"}{plugin}, "autoindex"); +IkiWiki::gen_autofile("attached.mdwn", \%pages, \@del); +is_deeply(\%pages, {"t/tmp/attached" => 1}) || diag explain \%pages; +is_deeply(\@del, []) || diag explain \@del; +ok(-s "t/tmp/.ikiwiki/transient/attached.mdwn"); 1; |