unofficial mirror of meta@public-inbox.org
 help / color / mirror / Atom feed
From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH v2 3/3] viewvcs: generate search query for merge commits
Date: Wed,  2 Oct 2024 22:39:02 +0000	[thread overview]
Message-ID: <20241002223902.4139389-4-e@80x24.org> (raw)
In-Reply-To: <20241002194448.4123393-1-e@80x24.org>

Attempt to parse commit titles out of merge commit messages and
generate search queries out of them to find the related emails
for the individual patch(es).

As with all search-related functionality, it's best-effort
and inexact, but seems somewhat successful.
---
 lib/PublicInbox/ViewVCS.pm | 70 ++++++++++++++++++++++++++++----------
 1 file changed, 52 insertions(+), 18 deletions(-)

diff --git a/lib/PublicInbox/ViewVCS.pm b/lib/PublicInbox/ViewVCS.pm
index 49477619..48a16c11 100644
--- a/lib/PublicInbox/ViewVCS.pm
+++ b/lib/PublicInbox/ViewVCS.pm
@@ -154,7 +154,7 @@ sub do_check_async {
 	}
 }
 
-sub cmt_hdr_prep { # psgi_qx cb
+sub cmt_hdr_prep { # psgi_qx cb for "git show" commit output
 	my ($fh, $ctx, $cmt_fin) = @_;
 	return if $ctx->{-qsp_err_h}; # let cmt_fin handle it
 	seek $fh, 0, SEEK_SET;
@@ -221,7 +221,26 @@ sub ibx_url_for {
 	wantarray ? (@ret) : $ret[0];
 }
 
-sub cmt_fin { # OnDestroy cb
+sub prep_merge_titles ($) {
+	my ($in_titles, @s, $t, @lines);
+	chomp(@lines = split /^/ms, $_[0]);
+	for (@lines) {
+		if (/^\* /) { # * branch/name:
+			$in_titles = 1;
+		} elsif ($in_titles) { # commit titles
+			if (s/^  //) { # break up Xapian phrases
+				$t = join " AND\n ", map { qq{s:"$_"} }
+					split /["\x{201c}\x{201d}]+/;
+				push @s, $t if $t ne 's:"..."';
+			} else { # trailing text or trailers?
+				undef $in_titles;
+			}
+		} # else: preamble text
+	}
+	@s ? \@s : undef;
+}
+
+sub cmt_fin { # OnDestroy cb for `git show' commit output
 	my ($ctx) = @_;
 	my ($eh, $ep) = delete @$ctx{qw(-qsp_err_h -qsp_err_p)};
 	if ($eh || $ep) {
@@ -242,7 +261,17 @@ sub cmt_fin { # OnDestroy cb
 		$au =~ s/>/>$x/;
 	}
 	$_ = ascii_html($_) for ($au, $co);
-	my $ibx_url = ibx_url_for($ctx) // $upfx;
+	my ($merge_titles, $ibx_url, $ibx_url_html, $alt);
+	$ibx_url = ibx_url_for($ctx);
+	if (defined $ibx_url) {
+		$ibx_url =~ m!://! or
+			substr($ibx_url, 0, 0, '../../../');
+		$ibx_url_html = ascii_html($ibx_url);
+		$alt = " `$ibx_url_html'";
+	} else {
+		$ibx_url = $ibx_url_html = $upfx;
+		$alt = '';
+	}
 	$au =~ s!(&gt; +)([0-9]{4,}-\S+ \S+)!
 		my ($gt, $t) = ($1, $2);
 		$t =~ tr/ :-//d;
@@ -258,6 +287,7 @@ title="list contemporary emails">$2</a>)
 		$x = qq{ (<a
 href="$f.patch">patch</a>)\n   <a href=#parent>parent</a> $P->[0]};
 	} elsif (@$P > 1) {
+		$merge_titles = 1;
 		$x = qq(\n  <a href=#parents>parents</a> $P->[0]\n);
 		shift @$P;
 		$x .= qq(          $_\n) for @$P;
@@ -275,7 +305,10 @@ committer $co
 
 <b>$title_html</b>
 EOM
-	print $zfh "\n", $ctx->{-linkify}->to_html($bdy) if length($bdy);
+	if (length($bdy)) {
+		print $zfh "\n", $ctx->{-linkify}->to_html($bdy);
+		$merge_titles = prep_merge_titles $bdy if $merge_titles;
+	}
 	undef $bdy; # free memory
 	my $fh = delete $ctx->{patch_fh};
 	if (-s $fh > $MAX_SIZE) {
@@ -293,26 +326,27 @@ EOM
 		# commit?
 		print $zfh '</pre>';
 		my ($rows, $q) = PublicInbox::View::dfqry_text $ctx, $s;
-		if ($rows) {
-			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);
-			} else {
-				$ibx_url = $upfx;
-				$alt = '';
-			}
-			print $zfh <<EOM;
+		print $zfh <<EOM if $rows;
 <hr><form action="$ibx_url"
 id=related><pre>find related emails, including ancestors/descendants/conflicts
 <textarea name=q cols=78 rows=$rows>$q</textarea>
 <input type=submit value="search$alt"
 />\t(<a href="${ibx_url}_/text/help/">help</a>)</pre></form>
 EOM
-		}
+	}
+	if ($merge_titles) {
+		print $zfh <<EOM;
+<hr><form action="$ibx_url" id=merged><pre>find merged patch emails
+<textarea name=q cols=78
+EOM
+		my $nr = scalar @$merge_titles;
+		$merge_titles = ascii_html(join ") OR\n(", @$merge_titles);
+		print $zfh 'rows=', $nr, '>(', $merge_titles, <<EOM;
+)</textarea>
+<input type=submit value="search$alt"
+/></pre></form>
+EOM
+		undef $merge_titles;
 	}
 	chop($x = <<EOM);
 <hr><pre>glossary

  parent reply	other threads:[~2024-10-02 22:39 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-02 19:44 [PATCH] viewvcs: generate search query for merge commits Eric Wong
2024-10-02 22:38 ` [PATCH v2 0/3] viewvcs: commit => query improvements Eric Wong
2024-10-02 22:39 ` [PATCH v2 1/3] viewvcs: close the <pre> tag if no query is extracted Eric Wong
2024-10-02 22:39 ` [PATCH v2 2/3] viewvcs: use wider textarea for search query Eric Wong
2024-10-02 22:39 ` Eric Wong [this message]
2024-10-07  8:29   ` [PATCH v2 3/3] viewvcs: generate search query for merge commits Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241002223902.4139389-4-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).