user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH 03/18] viewvcs: delay stringification of solver debug log
  2022-08-29  9:26  7% [PATCH 00/18] WWW: patch, tree, git glossary Eric Wong
@ 2022-08-29  9:26  4% ` Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2022-08-29  9:26 UTC (permalink / raw)
  To: meta

This will make future changes easier to work on as we pass more
stuff through $ctx and reduce parameter passing on the Perl stack.
---
 lib/PublicInbox/ViewVCS.pm | 130 +++++++++++++++++--------------------
 1 file changed, 61 insertions(+), 69 deletions(-)

diff --git a/lib/PublicInbox/ViewVCS.pm b/lib/PublicInbox/ViewVCS.pm
index c5d16478..b04a5672 100644
--- a/lib/PublicInbox/ViewVCS.pm
+++ b/lib/PublicInbox/ViewVCS.pm
@@ -37,20 +37,35 @@ my $SHOW_FMT = '--pretty=format:'.join('%n', '%P', '%p', '%H', '%T', '%s',
 	'%an <%ae>  %ai', '%cn <%ce>  %ci', '%b%x00');
 
 sub html_page ($$$) {
-	my ($ctx, $code, $strref) = @_;
+	my ($ctx, $code, $str) = @_;
 	my $wcb = delete $ctx->{-wcb};
 	$ctx->{-upfx} = '../../'; # from "/$INBOX/$OID/s/"
-	my $res = html_oneshot($ctx, $code, $strref);
+	my $res = html_oneshot($ctx, $code, \$str);
 	$wcb ? $wcb->($res) : $res;
 }
 
+sub dbg_log ($) {
+	my ($ctx) = @_;
+	my $log = delete $ctx->{lh} // die 'BUG: already captured debug log';
+	if (!seek($log, 0, 0)) {
+		warn "seek(log): $!";
+		return '<pre>debug log seek error</pre>';
+	}
+	$log = do { local $/; <$log> } // do {
+		warn "readline(log): $!";
+		return '<pre>debug log read error</pre>';
+	};
+	$ctx->{-linkify} //= PublicInbox::Linkify->new;
+	'<pre>debug log:</pre><hr /><pre>'.
+		$ctx->{-linkify}->to_html($log).'</pre>';
+}
+
 sub stream_blob_parse_hdr { # {parse_hdr} for Qspawn
 	my ($r, $bref, $ctx) = @_;
-	my ($res, $logref) = delete @$ctx{qw(-res -logref)};
-	my ($git, $oid, $type, $size, $di) = @$res;
+	my ($git, $oid, $type, $size, $di) = @{$ctx->{-res}};
 	my @cl = ('Content-Length', $size);
-	if (!defined $r) { # error
-		html_page($ctx, 500, $logref);
+	if (!defined $r) { # sysread error
+		html_page($ctx, 500, dbg_log($ctx));
 	} elsif (index($$bref, "\0") >= 0) {
 		[200, [qw(Content-Type application/octet-stream), @cl] ];
 	} else {
@@ -60,17 +75,16 @@ sub stream_blob_parse_hdr { # {parse_hdr} for Qspawn
 				'text/plain; charset=UTF-8', @cl ] ];
 		}
 		if ($r == 0) {
-			warn "premature EOF on $oid $$logref";
-			return html_page($ctx, 500, $logref);
+			my $log = dbg_log($ctx);
+			warn "premature EOF on $oid $log";
+			return html_page($ctx, 500, $log);
 		}
-		@$ctx{qw(-res -logref)} = ($res, $logref);
 		undef; # bref keeps growing
 	}
 }
 
-sub stream_large_blob ($$$$) {
-	my ($ctx, $res, $logref, $fn) = @_;
-	$ctx->{-logref} = $logref;
+sub stream_large_blob ($$) {
+	my ($ctx, $res) = @_;
 	$ctx->{-res} = $res;
 	my ($git, $oid, $type, $size, $di) = @$res;
 	my $cmd = ['git', "--git-dir=$git->{git_dir}", 'cat-file', $type, $oid];
@@ -80,18 +94,16 @@ sub stream_large_blob ($$$$) {
 	$qsp->psgi_return($env, undef, \&stream_blob_parse_hdr, $ctx);
 }
 
-sub show_other_result ($$) {
+sub show_other_result ($$) { # tag, tree, ...
 	my ($bref, $ctx) = @_;
-	my ($qsp_err, $logref) = delete @$ctx{qw(-qsp_err -logref)};
-	if ($qsp_err) {
-		$$logref .= "git show error:$qsp_err";
-		return html_page($ctx, 500, $logref);
+	if (my $qsp_err = delete $ctx->{-qsp_err}) {
+		return html_page($ctx, 500, dbg_log($ctx) .
+				"git show error:$qsp_err");
 	}
 	my $l = PublicInbox::Linkify->new;
 	utf8::decode($$bref);
-	$$bref = '<pre>'. $l->to_html($$bref);
-	$$bref .= '</pre><hr>' . $$logref;
-	html_page($ctx, 200, $bref);
+	html_page($ctx, 200, '<pre>', $l->to_html($$bref), '</pre><hr>',
+		dbg_log($ctx));
 }
 
 sub cmt_title { # git->cat_async callback
@@ -104,10 +116,9 @@ sub cmt_title { # git->cat_async callback
 
 sub show_commit_start { # ->psgi_qx callback
 	my ($bref, $ctx) = @_;
-	my ($qsp_err, $logref) = delete @$ctx{qw(-qsp_err -logref)};
-	if ($qsp_err) {
-		$$logref .= "git show/patch-id error:$qsp_err";
-		return html_page($ctx, 500, $logref);
+	if (my $qsp_err = delete $ctx->{-qsp_err}) {
+		return html_page($ctx, 500, dbg_log($ctx) .
+				"git show/patch-id error:$qsp_err");
 	}
 	my $patchid = (split(/ /, $$bref))[0]; # ignore commit
 	$ctx->{-q_value_html} = "patchid:$patchid" if defined $patchid;
@@ -135,7 +146,7 @@ sub show_commit_start { # ->psgi_qx callback
 
 sub cmt_finalize {
 	my ($ctx) = @_;
-	$ctx->{-linkify} = PublicInbox::Linkify->new;
+	$ctx->{-linkify} //= PublicInbox::Linkify->new;
 	# try to keep author and committer dates lined up
 	my ($au, $co) = delete @$ctx{qw(cmt_au cmt_co)};
 	my $x = length($au) - length($co);
@@ -219,8 +230,8 @@ EOM
 	delete($ctx->{env}->{'qspawn.wcb'})->([200, $res_hdr, [$x]]);
 }
 
-sub show_commit ($$$$) {
-	my ($ctx, $res, $logref, $fn) = @_;
+sub show_commit ($$) {
+	my ($ctx, $res) = @_;
 	my ($git, $oid) = @$res;
 	# patch-id needs two passes, and we use the initial show to ensure
 	# a patch embedded inside the commit message body doesn't get fed
@@ -234,84 +245,67 @@ sub show_commit ($$$$) {
 	my $e = { GIT_DIR => $git->{git_dir} };
 	my $qsp = PublicInbox::Qspawn->new($cmd, $e, { -C => "$ctx->{-tmp}" });
 	$qsp->{qsp_err} = \($ctx->{-qsp_err} = '');
-	$ctx->{-logref} = $logref;
 	$ctx->{env}->{'qspawn.wcb'} = delete $ctx->{-wcb};
 	$ctx->{git} = $git;
 	$qsp->psgi_qx($ctx->{env}, undef, \&show_commit_start, $ctx);
 }
 
-sub show_other ($$$$) {
-	my ($ctx, $res, $logref, $fn) = @_;
+sub show_other ($$) {
+	my ($ctx, $res) = @_;
 	my ($git, $oid, $type, $size) = @$res;
-	if ($size > $MAX_SIZE) {
-		$$logref = "$oid is too big to show\n" . $$logref;
-		return html_page($ctx, 200, $logref);
-	}
+	$size > $MAX_SIZE and return html_page($ctx, 200,
+				"$oid is too big to show\n". dbg_log($ctx));
 	my $cmd = ['git', "--git-dir=$git->{git_dir}",
 		qw(show --encoding=UTF-8 --no-color --no-abbrev), $oid ];
 	my $qsp = PublicInbox::Qspawn->new($cmd);
 	$qsp->{qsp_err} = \($ctx->{-qsp_err} = '');
-	$ctx->{-logref} = $logref;
 	$qsp->psgi_qx($ctx->{env}, undef, \&show_other_result, $ctx);
 }
 
 # user_cb for SolverGit, called as: user_cb->($result_or_error, $uarg)
 sub solve_result {
 	my ($res, $ctx) = @_;
-	my ($log, $hints, $fn) = delete @$ctx{qw(lh hints fn)};
-
-	unless (seek($log, 0, 0)) {
-		warn "seek(log): $!";
-		return html_page($ctx, 500, \'seek error');
-	}
-	$log = do { local $/; <$log> };
-
-	my $l = PublicInbox::Linkify->new;
-	$log = '<pre>debug log:</pre><hr /><pre>' .
-		$l->to_html($log) . '</pre>';
-
-	$res or return html_page($ctx, 404, \$log);
-	ref($res) eq 'ARRAY' or return html_page($ctx, 500, \$log);
+	my $hints = delete $ctx->{hints};
+	$res or return html_page($ctx, 404, dbg_log($ctx));
+	ref($res) eq 'ARRAY' or return html_page($ctx, 500, dbg_log($ctx));
 
 	my ($git, $oid, $type, $size, $di) = @$res;
-	return show_commit($ctx, $res, \$log, $fn) if $type eq 'commit';
-	return show_other($ctx, $res, \$log, $fn) if $type ne 'blob';
+	return show_commit($ctx, $res) if $type eq 'commit';
+	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>)";
 	if ($size > $MAX_SIZE) {
-		return stream_large_blob($ctx, $res, \$log, $fn) if defined $fn;
-		$log = "<pre><b>Too big to show, download available</b>\n" .
-			"$oid $type $size bytes $raw_link</pre>" . $log;
-		return html_page($ctx, 200, \$log);
+		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>
+"$oid $type $size bytes $raw_link</pre>
+EOM
 	}
 
 	my $blob = $git->cat_file($oid);
 	if (!$blob) { # WTF?
 		my $e = "Failed to retrieve generated blob ($oid)";
 		warn "$e ($git->{git_dir})";
-		$log = "<pre><b>$e</b></pre>" . $log;
-		return html_page($ctx, 500, \$log);
+		return html_page($ctx, 500, "<pre><b>$e</b></pre>".dbg_log($ctx))
 	}
 
 	my $bin = index(substr($$blob, 0, $BIN_DETECT), "\0") >= 0;
-	if (defined $fn) {
+	if (defined $ctx->{fn}) {
 		my $h = [ 'Content-Length', $size, 'Content-Type' ];
 		push(@$h, ($bin ? 'application/octet-stream' : 'text/plain'));
 		return delete($ctx->{-wcb})->([200, $h, [ $$blob ]]);
 	}
 
-	if ($bin) {
-		$log = "<pre>$oid $type $size bytes (binary)" .
-			" $raw_link</pre>" . $log;
-		return html_page($ctx, 200, \$log);
-	}
+	$bin and return html_page($ctx, 200,
+				"<pre>$oid $type $size bytes (binary)" .
+				" $raw_link</pre>".dbg_log($ctx));
 
 	# TODO: detect + convert to ensure validity
 	utf8::decode($$blob);
 	my $nl = ($$blob =~ s/\r?\n/\n/sg);
 	my $pad = length($nl);
 
-	$l->linkify_1($$blob);
+	($ctx->{-linkify} //= PublicInbox::Linkify->new)->linkify_1($$blob);
 	my $ok = $hl->do_hl($blob, $path) if $hl;
 	if ($ok) {
 		$blob = $ok;
@@ -320,17 +314,15 @@ sub solve_result {
 	}
 
 	# using some of the same CSS class names and ids as cgit
-	$log = "<pre>$oid $type $size bytes $raw_link</pre>" .
+	html_page($ctx, 200, "<pre>$oid $type $size bytes $raw_link</pre>" .
 		"<hr /><table\nclass=blob>".
 		"<tr><td\nclass=linenumbers><pre>" . join('', map {
 			sprintf("<a id=n$_ href=#n$_>% ${pad}u</a>\n", $_)
 		} (1..$nl)) . '</pre></td>' .
 		'<td><pre> </pre></td>'. # pad for non-CSS users
 		"<td\nclass=lines><pre\nstyle='white-space:pre'><code>" .
-		$l->linkify_2($$blob) .
-		'</code></pre></td></tr></table>' . $log;
-
-	html_page($ctx, 200, \$log);
+		$ctx->{-linkify}->linkify_2($$blob) .
+		'</code></pre></td></tr></table>'.dbg_log($ctx));
 }
 
 # GET /$INBOX/$GIT_OBJECT_ID/s/

^ permalink raw reply related	[relevance 4%]

* [PATCH 00/18] WWW: patch, tree, git glossary
@ 2022-08-29  9:26  7% Eric Wong
  2022-08-29  9:26  4% ` [PATCH 03/18] viewvcs: delay stringification of solver debug log Eric Wong
  0 siblings, 1 reply; 2+ results
From: Eric Wong @ 2022-08-29  9:26 UTC (permalink / raw)
  To: meta

Raw format-patch and tree HTML output now supported for git
output.  I suppose tags can be displayed, too, at some point...

One thing I'm not 100% sure about is adding a git-related
glossary for stuff like trees, commits, etc...  It seems
to bloat the page a bit, but it could be useful in slowly
teaching basic git data concepts to beginners.

I suspect folks who have trouble learning git too focused on the
commands rather than the data concepts.  (IMHO, the same goes
for learning projects based on studying code vs studying
(DB schemas || struct layouts)).

I snuck one speedup in there, hopefully more to come...

Eric Wong (18):
  solver: create tmpdir lazily
  viewvcs: share File::Temp::Dir with solver
  viewvcs: delay stringification of solver debug log
  www: allow html_oneshot to take an array arg
  viewvcs: use array for highlighted blob display
  viewvcs: add patch download link for single-parent commits
  viewvcs: author date links to contemporary messages
  view: speed up /$INBOX/ landing page by 0.5-1.0%
  treewide: ditch inbox->recent method
  view: /$INBOX/: show "messages from $old to $new"
  view: cleanups and reuse for {obuf} preparation
  www: atom: fix "changed" href to nowhere
  www: provide text/help/#search anchor
  solver: early make hints detection more robust
  viewvcs: add tree view
  viewvcs: reduce hash assignments for commit info
  viewvcs: add glossary for commit
  viewvcs: show "blob $OID" rather than "$OID blob"

 lib/PublicInbox/ExtSearch.pm      |   1 -
 lib/PublicInbox/Inbox.pm          |   5 -
 lib/PublicInbox/LeiSavedSearch.pm |   1 -
 lib/PublicInbox/LeiXSearch.pm     |   7 -
 lib/PublicInbox/SolverGit.pm      |  22 +-
 lib/PublicInbox/View.pm           | 101 ++++-----
 lib/PublicInbox/ViewDiff.pm       |  18 +-
 lib/PublicInbox/ViewVCS.pm        | 341 ++++++++++++++++++++----------
 lib/PublicInbox/WWW.pm            |   2 +-
 lib/PublicInbox/WwwAltId.pm       |   6 +-
 lib/PublicInbox/WwwAtomStream.pm  |   1 +
 lib/PublicInbox/WwwStream.pm      |   7 +-
 lib/PublicInbox/WwwText.pm        |   3 +-
 t/convert-compact.t               |   2 +-
 t/indexlevels-mirror.t            |  10 +-
 t/lei_xsearch.t                   |   2 +-
 t/plack.t                         |   2 +-
 t/replace.t                       |   4 +-
 t/solver_git.t                    |   3 +-
 t/v1-add-remove-add.t             |   2 +-
 t/v2-add-remove-add.t             |   2 +-
 21 files changed, 333 insertions(+), 209 deletions(-)

^ permalink raw reply	[relevance 7%]

Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2022-08-29  9:26  7% [PATCH 00/18] WWW: patch, tree, git glossary Eric Wong
2022-08-29  9:26  4% ` [PATCH 03/18] viewvcs: delay stringification of solver debug log Eric Wong

Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).