scripts: add Perl script to add links to release notes
authorBruce Momjian <[email protected]>
Mon, 16 Sep 2024 17:26:37 +0000 (13:26 -0400)
committerBruce Momjian <[email protected]>
Mon, 16 Sep 2024 17:26:37 +0000 (13:26 -0400)
Reported-by: jian he
Discussion: https://postgr.es/m/[email protected]

Backpatch-through: 12

src/tools/RELEASE_CHANGES
src/tools/add_commit_links.pl [new file with mode: 0755]

index 0f30f85ec71fa8a944beeca07b1c00613a7b1c0e..94c5a0f3bfbb3d18605dd4584bcbe01813d8e34b 100644 (file)
@@ -10,6 +10,7 @@ For All Releases (major, minor, beta, RC)
    o update doc/src/sgml/release-NN.sgml in relevant branches
    o run spellchecker on result
    o add SGML markup
+   o run src/tools/add_commit_links.pl
 
 * Update timezone data to match latest IANA timezone database and new
   Windows releases, if any (see src/timezone/README)
diff --git a/src/tools/add_commit_links.pl b/src/tools/add_commit_links.pl
new file mode 100755 (executable)
index 0000000..ebfc97e
--- /dev/null
@@ -0,0 +1,136 @@
+#! /usr/bin/perl
+
+#################################################################
+# add_commit_links.pl -- add commit links to the release notes
+#
+# Copyright (c) 2024, PostgreSQL Global Development Group
+#
+# src/tools/add_commit_links.pl
+#################################################################
+
+#
+# This script adds commit links to the release notes.
+#
+# Usage: cd to top of source tree and issue
+#  src/tools/add_commit_links.pl release_notes_file
+#
+# The script can add links for release note items that lack them, and update
+# those that have them.  The script is sensitive to the release note file being
+# in a specific format:
+#
+#  * File name contains the major version number preceded by a dash
+#    and followed by a period
+#  * Commit text is generated by src/tools/git_changelog
+#  * SGML comments around commit text start in the first column
+#  * The commit item title ends with an attribution that ends with
+#    a closing parentheses
+#  * previously added URL link text is unmodified
+#  * a "<para>" follows the commit item title
+#
+# The major version number is used to select the commit hash for minor
+# releases.  An error will be generated if valid commits are found but
+# no proper location for the commit links is found.
+
+use strict;
+use warnings FATAL => 'all';
+
+sub process_file
+{
+   my $file = shift;
+
+   my $in_comment = 0;
+   my $prev_line_ended_with_paren = 0;
+   my $prev_leading_space = '';
+   my $lineno = 0;
+
+   my @hashes = ();
+
+   my $tmpfile = $file . '.tmp';
+
+   # Get major version number from the file name.
+   $file =~ m/-(\d+)\./;
+   my $major_version = $1;
+
+   open(my $fh, '<', $file) || die "could not open file %s: $!\n", $file;
+   open(my $tfh, '>', $tmpfile) || die "could not open file %s: $!\n",
+     $tmpfile;
+
+   while (<$fh>)
+   {
+       $lineno++;
+
+       $in_comment = 1 if (m/^<!--/);
+
+       # skip over commit links because we will add them below
+       next
+         if (!$in_comment &&
+           m{^\s*<ulink url="&commit_baseurl;[\da-f]+">&sect;</ulink>\s*$});
+
+       if ($in_comment && m/\[([\da-f]+)\]/)
+       {
+           my $hash = $1;
+
+           # major release item
+           (!m/^Branch:/) && push(@hashes, $hash);
+
+           # minor release item
+           m/^Branch:/ &&
+             defined($major_version) &&
+             m/_${major_version}_/ &&
+             push(@hashes, $hash);
+       }
+
+       if (!$in_comment && m{</para>})
+       {
+           if (@hashes)
+           {
+               if ($prev_line_ended_with_paren)
+               {
+                   for my $hash (@hashes)
+                   {
+                       print({$tfh}
+                             "$prev_leading_space<ulink url=\"&commit_baseurl;$hash\">&sect;</ulink>\n"
+                       );
+                   }
+                   @hashes = ();
+               }
+               else
+               {
+                   printf(
+                       "hashes found but no matching text found for placement on line %s\n",
+                       $lineno);
+                   exit(1);
+               }
+           }
+       }
+
+       print({$tfh} $_);
+
+       $prev_line_ended_with_paren = m/\)\s*$/;
+
+       m/^(\s*)/;
+       $prev_leading_space = $1;
+
+       $in_comment = 0 if (m/^-->/);
+   }
+
+   close($fh);
+   close($tfh);
+
+   rename($tmpfile, $file) || die "could not rename %s to %s: $!\n",
+     $tmpfile,
+     $file;
+
+   return;
+}
+
+if (@ARGV == 0)
+{
+   printf(STDERR "Usage: %s release_notes_file [...]\n", $0);
+   exit(1);
+}
+
+for my $file (@ARGV)
+{
+   process_file($file);
+}