fix other 2 cases of conflicting destdir files
[ikiwiki.git] / IkiWiki.pm
index 85b5424863e5836af0b9d1e0dba2ef0fb73abb87..fa49b2c340fe9b40f46db39a42c0d084b1fcd4f1 100644 (file)
@@ -823,6 +823,17 @@ sub prep_writefile ($$) {
                if (-l "$destdir/$test") {
                        error("cannot write to a symlink ($test)");
                }
+               if (-f _ && $test ne $file) {
+                       # Remove conflicting file.
+                       foreach my $p (keys %renderedfiles, keys %oldrenderedfiles) {
+                               foreach my $f (@{$renderedfiles{$p}}, @{$oldrenderedfiles{$p}}) {
+                                       if ($f eq $test) {
+                                               unlink("$destdir/$test");
+                                               last;
+                                       }
+                               }
+                       }
+               }
                $test=dirname($test);
        }
 
@@ -876,11 +887,12 @@ sub will_render ($$;$) {
        my $dest=shift;
        my $clear=shift;
 
-       # Important security check.
+       # Important security check for independently created files.
        if (-e "$config{destdir}/$dest" && ! $config{rebuild} &&
            ! grep { $_ eq $dest } (@{$renderedfiles{$page}}, @{$oldrenderedfiles{$page}}, @{$wikistate{editpage}{previews}})) {
                my $from_other_page=0;
-               foreach my $p (keys %renderedfiles) {
+               # Expensive, but rarely runs.
+               foreach my $p (keys %renderedfiles, keys %oldrenderedfiles) {
                        if (grep {
                                $_ eq $dest ||
                                dirname($_) eq $dest
@@ -894,6 +906,19 @@ sub will_render ($$;$) {
                        unless $from_other_page;
        }
 
+       # If $dest exists as a directory, remove conflicting files in it
+       # rendered from other pages.
+       if (-d _) {
+               foreach my $p (keys %renderedfiles, keys %oldrenderedfiles) {
+                       foreach my $f (@{$renderedfiles{$p}}, @{$oldrenderedfiles{$p}}) {
+                               if ($f eq dirname($dest) || dirname($f) eq $dest) {
+                                       unlink("$config{destdir}/$f");
+                                       rmdir(dirname("$config{destdir}/$f"));
+                               }
+                       }
+               }
+       }
+
        if (! $clear || $cleared{$page}) {
                $renderedfiles{$page}=[$dest, grep { $_ ne $dest } @{$renderedfiles{$page}}];
        }