MANIFEST | 1 + lib/PublicInbox/LeiMirror.pm | 28 +++++++++++++++++++++------- t/lei-mirror.psgi | 9 +++++++++ t/lei-mirror.t | 6 +++++- diff --git a/MANIFEST b/MANIFEST index 531f8c46dc4b62252ac171abbfc7002f6d8479cc..a22672e713557172af655620bce32a8038cdeb6f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -436,6 +436,7 @@ t/lei-import-nntp.t t/lei-import.t t/lei-index.t t/lei-lcat.t +t/lei-mirror.psgi t/lei-mirror.t t/lei-p2q.t t/lei-q-kw.t diff --git a/lib/PublicInbox/LeiMirror.pm b/lib/PublicInbox/LeiMirror.pm index 39671f902b5514b19657bb7e937a06c935aca76d..fca11ccff037cae4d5b1f4b37e609c36733629fa 100644 --- a/lib/PublicInbox/LeiMirror.pm +++ b/lib/PublicInbox/LeiMirror.pm @@ -200,6 +200,19 @@ undef $on_destroy; # unlock index_cloned_inbox($self, 2); } +# PSGI mount prefixes and manifest.js.gz prefixes don't always align... +sub deduce_epochs ($$) { + my ($m, $path) = @_; + my ($v1_bare, @v2_epochs); + my $path_pfx = ''; + do { + $v1_bare = $m->{$path}; + @v2_epochs = grep(m!\A\Q$path\E/git/[0-9]+\.git\z!, keys %$m); + } while (!defined($v1_bare) && !@v2_epochs && + $path =~ s!\A(/[^/]+)/!/! and $path_pfx .= $1); + ($path_pfx, $v1_bare, @v2_epochs); +} + sub try_manifest { my ($self) = @_; my $uri = URI->new($self->{src}); @@ -229,8 +242,7 @@ my $m = eval { PublicInbox::Config->json->decode($js) }; die "$uri: error decoding `$js': $@" if $@; ref($m) eq 'HASH' or die "$uri unknown type: ".ref($m); - my $v1_bare = $m->{$path}; - my @v2_epochs = grep(m!\A\Q$path\E/git/[0-9]+\.git\z!, keys %$m); + my ($path_pfx, $v1_bare, @v2_epochs) = deduce_epochs($m, $path); if (@v2_epochs) { # It may be possible to have v1 + v2 in parallel someday: $lei->err(<path($_); $uri->clone } @v2_epochs; + @v2_epochs = map { + $uri->path($path_pfx.$_); + $uri->clone + } @v2_epochs; clone_v2($self, \@v2_epochs); - } elsif ($v1_bare) { + } elsif (defined $v1_bare) { clone_v1($self); - } elsif (my @maybe = grep(m!\Q$path\E!, keys %$m)) { - die "E: confused by <$uri>, possible matches:\n@maybe"; } else { - die "E: confused by <$uri>"; + die "E: confused by <$uri>, possible matches:\n\t", + join(', ', sort keys %$m), "\n"; } } diff --git a/t/lei-mirror.psgi b/t/lei-mirror.psgi new file mode 100644 index 0000000000000000000000000000000000000000..6b4bbfecc3e241b6b375191da5172fd0bfc5679e --- /dev/null +++ b/t/lei-mirror.psgi @@ -0,0 +1,9 @@ +use Plack::Builder; +use PublicInbox::WWW; +my $www = PublicInbox::WWW->new; +$www->preload; +builder { + enable 'Head'; + mount '/pfx' => builder { sub { $www->call(@_) } }; + mount '/' => builder { sub { $www->call(@_) } }; +}; diff --git a/t/lei-mirror.t b/t/lei-mirror.t index 80bc6ed5ab135f266addc9e63c9bbd2fc7e276de..65b6068ccb917af1ef7992eed14d6276ecd916af 100644 --- a/t/lei-mirror.t +++ b/t/lei-mirror.t @@ -7,7 +7,8 @@ my $sock = tcp_server(); my ($tmpdir, $for_destroy) = tmpdir(); my $http = 'http://'.tcp_host_port($sock); my ($ro_home, $cfg_path) = setup_public_inboxes; -my $cmd = [ qw(-httpd -W0), "--stdout=$tmpdir/out", "--stderr=$tmpdir/err" ]; +my $cmd = [ qw(-httpd -W0 ./t/lei-mirror.psgi), + "--stdout=$tmpdir/out", "--stderr=$tmpdir/err" ]; my $td = start_script($cmd, { PI_CONFIG => $cfg_path }, { 3 => $sock }); test_lei({ tmpdir => $tmpdir }, sub { my $home = $ENV{HOME}; @@ -42,6 +43,9 @@ like($lei_err, qr/not a directory/, 'non-directory noted'); ok(!-d "$t2-fail", 'destination not created on failure'); lei_ok('ls-external'); unlike($lei_out, qr!\Q$t2-fail\E!, 'not added to ls-external'); + + lei_ok('add-external', "$t1-pfx", '--mirror', "$http/pfx/t1/", + \'--mirror v1 w/ PSGI prefix'); my %phail = ( HTTPS => 'https://public-inbox.org/' . 'phail',