sub html_page ($$;@) {
my ($ctx, $code) = @_[0, 1];
my $wcb = delete $ctx->{-wcb};
- $ctx->{-upfx} = '../../'; # from "/$INBOX/$OID/s/"
+ $ctx->{-upfx} //= '../../'; # from "/$INBOX/$OID/s/"
my $res = html_oneshot($ctx, $code, @_[2..$#_]);
$wcb ? $wcb->($res) : $res;
}
warn "readline(log): $!";
return '<pre>debug log read error</pre>';
};
+ return '' if $log eq '';
$ctx->{-linkify} //= PublicInbox::Linkify->new;
"<hr><pre>debug log:\n\n".
$ctx->{-linkify}->to_html($log).'</pre>';
cmt_finalize($ctx);
}
+sub do_cat_async {
+ my ($ctx, $cb, @oids) = @_;
+ # favor git(1) over Gcf2 (libgit2) for SHA-256 support
+ $ctx->{git}->cat_async($_, $cb, $ctx) for @oids;
+ if ($ctx->{env}->{'pi-httpd.async'}) {
+ PublicInbox::GitAsyncCat::watch_cat($ctx->{git});
+ } else { # synchronous, generic PSGI
+ $ctx->{git}->cat_async_wait;
+ }
+}
+
sub show_commit_start { # ->psgi_qx callback
my ($bref, $ctx) = @_;
if (my $qsp_err = delete $ctx->{-qsp_err}) {
return cmt_finalize($ctx) if !$P;
@{$ctx->{-cmt_P}} = split(/ /, $P);
@{$ctx->{-cmt_p}} = split(/ /, $p); # abbreviated
- if ($ctx->{env}->{'pi-httpd.async'}) {
- for (@{$ctx->{-cmt_P}}) {
- ibx_async_cat($ctx, $_, \&cmt_title, $ctx);
- }
- } else { # synchronous
- for (@{$ctx->{-cmt_P}}) {
- $ctx->{git}->cat_async($_, \&cmt_title, $ctx);
- }
- $ctx->{git}->cat_async_wait;
- }
+ do_cat_async($ctx, \&cmt_title, @{$ctx->{-cmt_P}});
}
sub ibx_url_for {
my ($ctx) = @_;
$ctx->{ibx} and return; # fall back to $upfx
- $ctx->{git} or return;
+ $ctx->{git} or die 'BUG: no {git}';
if (my $ALL = $ctx->{www}->{pi_cfg}->ALL) {
- return $ALL->base_url // $ALL->base_url($ctx->{env});
- } elsif (my $ibx_names = $ctx->{git}->{ibx_names}) {
+ if (defined(my $u = $ALL->base_url($ctx->{env}))) {
+ return wantarray ? ($u) : $u;
+ }
+ }
+ my @ret;
+ if (my $ibx_names = $ctx->{git}->{ibx_names}) {
my $by_name = $ctx->{www}->{pi_cfg}->{-by_name};
for my $name (@$ibx_names) {
my $ibx = $by_name->{$name} // do {
next;
};
$ibx->isrch // next;
- return defined($ibx->{url}) ?
- prurl($ctx->{env}, $ibx->{url}) :
- "../../../$name/";
+ my $u = defined($ibx->{url}) ?
+ prurl($ctx->{env}, $ibx->{url}) : $name;
+ $u .= '/' if substr($u, -1) ne '/';
+ push @ret, $u;
}
}
- undef;
+ wantarray ? (@ret) : $ret[0];
}
sub cmt_finalize {
my $ibx_url = ibx_url_for($ctx);
my $alt;
if (defined $ibx_url) {
+ $alt = " `$ibx_url'";
+ $ibx_url =~ m!://! or
+ substr($ibx_url, 0, 0, '../../../');
$ibx_url = ascii_html($ibx_url);
- $alt = ' '.$ibx_url;
} else {
$ibx_url = $upfx;
$alt = '';
my @ent = split(/\0/, $$bref);
my $qp = delete $ctx->{qp};
my $l = $ctx->{-linkify} //= PublicInbox::Linkify->new;
- my $pfx = $qp->{b};
+ my $pfx = $ctx->{-path} // $qp->{b}; # {-path} is from RepoTree
$$bref = "<pre><a href=#tree>tree</a> $ctx->{tree_oid}";
+ # $REPO/tree/$path already sets {-upfx}
+ my $upfx = $ctx->{-upfx} //= '../../';
if (defined $pfx) {
- if ($pfx eq '') {
+ $pfx =~ s!/+\z!!s;
+ if (my $t = $ctx->{-obj}) {
+ my $t = ascii_html($t);
+ $$bref .= <<EOM
+\n\$ git ls-tree -l $t # shows similar output on the CLI
+EOM
+ } elsif ($pfx eq '') {
$$bref .= " (root)\n";
} else {
my $x = ascii_html($pfx);
if ($m eq 'd') { $n .= '/' }
elsif ($m eq 'x') { $n = "<b>$n</b>" }
elsif ($m eq 'l') { $n = "<i>$n</i>" }
- $$bref .= qq(\n$m\t$sz\t<a\nhref="../../$oid/s/?$q">$n</a>);
+ $$bref .= qq(\n$m\t$sz\t<a\nhref="$upfx$oid/s/?$q">$n</a>);
}
$$bref .= dbg_log($ctx);
$$bref .= <<EOM;
html_page($ctx, 200, $$bref);
}
-sub show_tree ($$) {
+sub show_tree ($$) { # also used by RepoTree
my ($ctx, $res) = @_;
my ($git, $oid, undef, $size) = @$res;
$size > $MAX_SIZE and return html_page($ctx, 200,
my ($ctx, $res) = @_;
my ($git, $oid) = @$res;
$ctx->{git} = $git;
- if ($ctx->{env}->{'pi-httpd.async'}) {
- ibx_async_cat($ctx, $oid, \&show_tag_result, $ctx);
- } else { # synchronous (generic PSGI)
- $git->cat_async($oid, \&show_tag_result, $ctx);
- $git->cat_async_wait;
- }
+ do_cat_async($ctx, \&show_tag_result, $oid);
}
# user_cb for SolverGit, called as: user_cb->($result_or_error, $uarg)
return show_tree($ctx, $res) if $type eq 'tree';
return show_tag($ctx, $res) if $type eq 'tag';
return show_other($ctx, $res) if $type ne 'blob';
- my $path = to_filename($di->{path_b} // $hints->{path_b} // 'blob');
- my $raw_link = "(<a\nhref=$path>raw</a>)";
+ my $paths = $ctx->{-paths} //= do {
+ my $path = to_filename($di->{path_b}//$hints->{path_b}//'blob');
+ my $raw_more = qq[(<a\nhref="$path">raw</a>)];
+ [ $path, $raw_more ];
+ };
+
if ($size > $MAX_SIZE) {
return stream_large_blob($ctx, $res) if defined $ctx->{fn};
return html_page($ctx, 200, <<EOM . dbg_log($ctx));
<pre><b>Too big to show, download available</b>
-blob $oid $size bytes $raw_link</pre>
+blob $oid $size bytes $paths->[1]</pre>
EOM
}
- @{$ctx->{-paths}} = ($path, $raw_link);
bless $ctx, 'PublicInbox::WwwStream'; # for DESTROY
$ctx->{git} = $git;
- if ($ctx->{env}->{'pi-httpd.async'}) {
- ibx_async_cat($ctx, $oid, \&show_blob, $ctx);
- } else { # synchronous
- $git->cat_async($oid, \&show_blob, $ctx);
- $git->cat_async_wait;
- }
+ do_cat_async($ctx, \&show_blob, $oid);
}
sub show_blob { # git->cat_async callback
return delete($ctx->{-wcb})->([200, $h, [ $$blob ]]);
}
- my ($path, $raw_link) = @{delete $ctx->{-paths}};
+ my ($path, $raw_more) = @{delete $ctx->{-paths}};
$bin and return html_page($ctx, 200,
"<pre>blob $oid $size bytes (binary)" .
- " $raw_link</pre>".dbg_log($ctx));
+ " $raw_more</pre>".dbg_log($ctx));
# TODO: detect + convert to ensure validity
utf8::decode($$blob);
}
# using some of the same CSS class names and ids as cgit
- my $x = "<pre>blob $oid $size bytes $raw_link</pre>" .
+ my $x = "<pre>blob $oid $size bytes $raw_more</pre>" .
"<hr /><table\nclass=blob>".
"<tr><td\nclass=linenumbers><pre>";
# scratchpad in this loop is faster here than `printf $zfh':