about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2022-11-28 05:32:23 +0000
committerEric Wong <e@80x24.org>2022-11-28 23:38:59 +0000
commite7e3993a2c19b65b23e7d83c2c33ae8ce9f64035 (patch)
treea620b9ee9fa1a298cb0ce86ad0a298e67e0ad0b2 /lib/PublicInbox
parent3f36a5060302417a24a1fbacd8860a620298485c (diff)
downloadpublic-inbox-e7e3993a2c19b65b23e7d83c2c33ae8ce9f64035.tar.gz
It's part of grokmirror, and useful for keeping compatibility.
We can make use of File::Spec->abs2rel here to ensure our
symlinks are relative and the entire mirror can be copied
as a whole.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/LeiMirror.pm26
1 files changed, 25 insertions, 1 deletions
diff --git a/lib/PublicInbox/LeiMirror.pm b/lib/PublicInbox/LeiMirror.pm
index fc5bc88d..47db9ccd 100644
--- a/lib/PublicInbox/LeiMirror.pm
+++ b/lib/PublicInbox/LeiMirror.pm
@@ -664,6 +664,7 @@ sub up_fp_done {
         push @{$self->{chg}->{fp_mismatch}}, $self->{-key};
 }
 
+# modifies the to-be-written manifest entry, and sets values from it, too
 sub update_ent {
         my ($self) = @_;
         my $key = $self->{-key} // die 'BUG: no -key';
@@ -694,7 +695,26 @@ sub update_ent {
                 }
                 start_cmd($self, $cmd, { 2 => $self->{lei}->{2} }) if $cmd;
         }
-
+        if (my $symlinks = $self->{-ent}->{symlinks}) {
+                my $top = File::Spec->rel2abs($self->{dst});
+                for my $p (@$symlinks) {
+                        my $ln = "$top/$p";
+                        $ln =~ tr!/!/!s;
+                        my (undef, $dn, $bn) = File::Spec->splitpath($ln);
+                        File::Path::mkpath($dn);
+                        my $tgt = "$top/$key";
+                        $tgt = File::Spec->abs2rel($tgt, $dn);
+                        if (lstat($ln)) {
+                                if (-l _) {
+                                        next if readlink($ln) eq $tgt;
+                                        unlink($ln) or die "unlink($ln): $!";
+                                } else {
+                                        push @{$self->{chg}->{badlink}}, $p;
+                                }
+                        }
+                        symlink($tgt, $ln) or die "symlink($tgt, $ln): $!";
+                }
+        }
         $new = $self->{-ent}->{owner} // return;
         $cur = $self->{-local_manifest}->{$key}->{owner} // "\0";
         return if $cur eq $new;
@@ -1059,6 +1079,10 @@ W: The above fingerprints may never match without --prune
 EOM
         }
         dump_manifest($m => $ft) if delete($self->{chg}->{manifest}) || $mis;
+        my $bad = delete $self->{chg}->{badlink};
+        warn(<<EOM, map { ("\t", $_, "\n") } @$bad) if $bad;
+W: The following exist and have not been converted to symlinks
+EOM
         ft_rename($ft, $manifest, 0666);
 }