aboutsummaryrefslogtreecommitdiff
path: root/src/tools/add_commit_links.pl
blob: 64a5783297220bcc848dcd1ab578d317e9dcef53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#! /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 $file: $!\n";
	open(my $tfh, '>', $tmpfile) || die "could not open file $tmpfile: $!\n";

	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;[[:xdigit:]]+">&sect;</ulink>\s*$});

		if ($in_comment && m/\[([[:xdigit:]]+)\]/)
		{
			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
				{
					print
					  "hashes found but no matching text found for placement on line $lineno\n";
					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);
}