Skip to content

Commit 66eed0d

Browse files
Improve code readability and perltidy
1 parent f888736 commit 66eed0d

1 file changed

Lines changed: 145 additions & 97 deletions

File tree

PGBuild/Modules/ABICompCheck.pm

Lines changed: 145 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,25 @@ is constructed dynamically by scanning all the .so files directly under the C<in
3333
3434
=item 3.
3535
36-
The module identifies a baseline reference for comparison. This can be:
36+
The module identifies a baseline reference for comparison by using the following precedence order:
3737
3838
=over
3939
4040
=item *
4141
42-
The most recent tag on the branch (e.g., REL_16_1), if found and not older than the branch point.
42+
The tag specified for the current branch in the animal's configuration file using C<tag_for_branch>.
4343
4444
=item *
4545
46-
The first commit of the current branch, if no suitable tag is found or if the latest tag predates the branch.
46+
A custom commit/tag specified in C<pgsql/.abi-compliance-history> file.
47+
48+
=item *
49+
50+
The most recent tag on the branch (e.g., REL_16_1), if found and not older than the branch point.
4751
4852
=item *
4953
50-
A custom commit/tag specified in C<pgsql/.abi-compliance-history> file (this overrides the automatic selection).
54+
The first commit of the current branch as the last fallback, if no suitable tag is found or if the latest tag predates the branch.
5155
5256
=back
5357
@@ -75,7 +79,7 @@ directory.
7579
7680
It uses C<abidw> to generate XML representations of the ABI for key binaries
7781
(the C<postgres> executable and all shared libraries found directly under the
78-
installation's C<lib> directory) from this baseline build. These are stored for
82+
installation's C<lib> directory) from this baseline build. These are stored for
7983
future runs.
8084
8185
=back
@@ -131,7 +135,7 @@ An array reference containing flags to pass to C<abidw>. Defaults to:
131135
A hash reference mapping branch names to their corresponding tags or tag
132136
patterns for ABI comparison. Supports exact tag names or patterns (e.g.,
133137
'REL_17_*'). If a pattern matches multiple tags, the first one is used. Defaults
134-
to empty hash, which means automatic tag selection for all branches.
138+
to an empty hash, which means automatic tag selection for all branches.
135139
136140
=back
137141
@@ -152,7 +156,7 @@ ABI policy for minor releases.
152156
153157
=item *
154158
155-
Debug information is required in the build to be able to use this module
159+
Debug information is required in the build to be able to use this module.
156160
157161
=item *
158162
@@ -296,7 +300,7 @@ sub setup
296300
mkdir $abi_compare_root
297301
unless -d $abi_compare_root;
298302

299-
# could even set up several of these (e.g. for different branches)
303+
# Store module configuration for later use in hooks.
300304
my $self = {
301305
buildroot => $buildroot,
302306
pgbranch => $branch,
@@ -313,6 +317,118 @@ sub setup
313317
return;
314318
}
315319

320+
# Determine the comparison reference from the animal's config file.
321+
sub _get_comparison_ref_from_config
322+
{
323+
my $self = shift;
324+
my $tag_pattern = $self->{tag_for_branch}->{ $self->{pgbranch} };
325+
my @tags = run_log(qq{git -C ./pgsql tag --list '$tag_pattern'})
326+
; # get the list of tags based on the tag pattern provided in config
327+
chomp(@tags);
328+
329+
unless (@tags)
330+
{
331+
emit
332+
"Specified tag pattern '$tag_pattern' for branch '$self->{pgbranch}' does not match any tags.";
333+
return '';
334+
}
335+
336+
# If multiple tags match, use the first one.
337+
return $tags[0];
338+
}
339+
340+
# Determine the comparison reference from the .abi-compliance-history file.
341+
sub _get_comparison_ref_from_history_file
342+
{
343+
my $self = shift;
344+
345+
# this function reads the .abi-compliance-history file and returns the first valid line
346+
# that is not a comment(starting with a '#' symbol) or empty line, assumes it to be a commit SHA
347+
# and verifies if it actually exists in the git history
348+
open my $fh, '<', "pgsql/.abi-compliance-history"
349+
or die "Cannot open pgsql/.abi-compliance-history: $!";
350+
while (my $line = <$fh>)
351+
{
352+
next if $line =~ /^\s*#/ || $line =~ /^\s*$/;
353+
$line =~ s/\s*#.*//;
354+
$line =~ s/^\s+|\s+$//g;
355+
356+
# Check that the commit SHA actually exists.
357+
my $exit_status =
358+
system(qq{git -C ./pgsql cat-file -e $line^{commit} 2>/dev/null});
359+
if ($exit_status != 0)
360+
{
361+
die
362+
"Wrong or non-existent commit/tag '$line' found in .abi-compliance-history";
363+
}
364+
close $fh;
365+
return $line;
366+
}
367+
return '';
368+
}
369+
370+
# Determine the default comparison reference by finding the latest tag or the
371+
# first commit of the branch.
372+
sub _get_default_comparison_ref
373+
{
374+
my $self = shift;
375+
376+
# Find the most recent tag on the branch, or fallback to first commit of branch
377+
378+
my $pgbranch = $self->{pgbranch};
379+
my $comparison_ref = '';
380+
381+
# If no specific tag is configured, find the most recent tag on the branch.
382+
emit "Finding latest tag for branch $pgbranch";
383+
my $baseline =
384+
run_log(qq{git -C ./pgsql describe --tags --abbrev=0 2>/dev/null});
385+
chomp $baseline;
386+
387+
# Default to the latest tag if found.
388+
if ($baseline)
389+
{
390+
# Find the first commit of the current branch.
391+
my $first_commit =
392+
run_log(qq{git -C ./pgsql merge-base master bf_$pgbranch});
393+
die "git merge-base failed: $?" if $?;
394+
chomp $first_commit;
395+
396+
# Check if the latest tag is an ancestor of the first commit of the branch.
397+
# If it is, it's likely a tag from a previous branch, so we should
398+
# use the first commit of the current branch as the baseline instead.
399+
my $is_ancestor = system(
400+
qq{git -C ./pgsql merge-base --is-ancestor $baseline $first_commit 2>/dev/null}
401+
);
402+
403+
if ($is_ancestor == 0)
404+
{
405+
# The tag is an ancestor of the branch point, so it's too old.
406+
# Use the first commit of the branch as the baseline.
407+
$comparison_ref = $first_commit;
408+
emit
409+
"Latest tag '$baseline' is older than branch point. Using first branch commit '$comparison_ref' as baseline.";
410+
}
411+
else
412+
{
413+
# The tag is on the current branch, so use it.
414+
$comparison_ref = $baseline;
415+
emit "Using latest tag '$comparison_ref' as baseline.";
416+
}
417+
}
418+
else
419+
{
420+
# As a fallback, find the first commit of the current branch.
421+
# This is not ideal as it might be too old for a meaningful ABI comparison.
422+
$comparison_ref =
423+
run_log(qq{git -C ./pgsql merge-base master bf_$pgbranch});
424+
die "git merge-base failed: $?" if $?;
425+
chomp $comparison_ref;
426+
emit
427+
"No tags found. Using first branch commit '$comparison_ref' as baseline.";
428+
}
429+
return $comparison_ref;
430+
}
431+
316432
# Main function - runs after PostgreSQL installation to perform ABI comparison
317433
sub installcheck
318434
{
@@ -344,98 +460,28 @@ sub installcheck
344460
my $tag_for_branch = $self->{tag_for_branch} || {};
345461
my $comparison_ref = '';
346462

347-
# find the tag to compare with for the branch
463+
# Determine the baseline reference for comparison, in order of precedence:
464+
# 1. Animal-specific config
465+
# 2. .abi-compliance-history file
466+
# 3. Default (latest tag or first commit of the branch)
348467
if (exists $tag_for_branch->{$pgbranch})
349468
{
350-
my $tag_pattern = $tag_for_branch->{$pgbranch};
351-
my @tags = run_log(qq{git -C ./pgsql tag --list '$tag_pattern'})
352-
; # get the list of tags based on the tag pattern provided in config
353-
chomp(@tags);
354-
355-
unless (@tags)
356-
{
357-
emit
358-
"Specified tag pattern '$tag_pattern' for branch '$pgbranch' does not match any tags.";
359-
return;
360-
}
361-
362-
# use the first tag from the list in case of regex
469+
$comparison_ref = $self->_get_comparison_ref_from_config();
363470
emit
364-
"Using $tags[0] as the baseline tag for branch $pgbranch based on pattern '$tag_pattern'";
365-
$comparison_ref = $tags[0];
471+
"Using $comparison_ref as the baseline tag based on the animal config"
472+
if $comparison_ref;
366473
}
367-
else
474+
elsif (-f "pgsql/.abi-compliance-history")
368475
{
369-
# If no specific tag is configured, find the most recent tag on the branch.
370-
emit "Finding latest tag for branch $pgbranch";
371-
my $baseline = run_log(qq{git -C ./pgsql describe --tags --abbrev=0 2>/dev/null});
372-
chomp $baseline;
373-
374-
# Default to the latest tag if found.
375-
if ($baseline)
376-
{
377-
# Find the first commit of the current branch.
378-
my $first_commit =
379-
run_log(qq{git -C ./pgsql merge-base master bf_$pgbranch});
380-
die "git merge-base failed: $?" if $?;
381-
chomp $first_commit;
382-
383-
# Check if the latest tag is an ancestor of the first commit of the branch.
384-
# If it is, it's likely a tag from a previous branch, so we should
385-
# use the first commit of the current branch as the baseline instead.
386-
my $is_ancestor = system(qq{git -C ./pgsql merge-base --is-ancestor $baseline $first_commit 2>/dev/null});
387-
388-
if ($is_ancestor == 0)
389-
{
390-
# The tag is an ancestor of the branch point, so it's too old.
391-
# Use the first commit of the branch as the baseline.
392-
$comparison_ref = $first_commit;
393-
emit "Latest tag '$baseline' is older than branch point. Using first branch commit '$comparison_ref' as baseline.";
394-
}
395-
else
396-
{
397-
# The tag is on the current branch, so use it.
398-
$comparison_ref = $baseline;
399-
emit "Using latest tag '$comparison_ref' as baseline.";
400-
}
401-
}
402-
else
403-
{
404-
# As a fallback, find the first commit of the current branch.
405-
# This is not ideal as it might be too old for a meaningful ABI comparison.
406-
$comparison_ref =
407-
run_log(qq{git -C ./pgsql merge-base master bf_$pgbranch});
408-
die "git merge-base failed: $?" if $?;
409-
chomp $comparison_ref;
410-
emit "No tags found. Using first branch commit '$comparison_ref' as baseline.";
411-
}
412-
413-
# Allow overriding the baseline via .abi-compliance-history file.
414-
if (-f "pgsql/.abi-compliance-history")
415-
{
416-
open my $fh, '<', "pgsql/.abi-compliance-history"
417-
or die "Cannot open pgsql/.abi-compliance-history: $!";
418-
while (my $line = <$fh>)
419-
{
420-
next if $line =~ /^\s*#/ || $line =~ /^\s*$/;
421-
$line =~ s/\s*#.*//;
422-
$line =~ s/^\s+|\s+$//g;
423-
# Check that the commit/tag actually exists.
424-
my $exit_status = system(qq{git -C ./pgsql cat-file -e $line^{commit} 2>/dev/null});
425-
if ($exit_status != 0)
426-
{
427-
die
428-
"Wrong or non-existent commit/tag '$line' found in .abi-compliance-history";
429-
}
430-
$comparison_ref = $line;
431-
emit
432-
"Overriding baseline with '$comparison_ref' from .abi-compliance-history";
433-
last;
434-
}
435-
close $fh;
436-
}
476+
$comparison_ref = $self->_get_comparison_ref_from_history_file();
477+
emit "Using baseline '$comparison_ref' from .abi-compliance-history"
478+
if $comparison_ref;
437479
}
438480

481+
# Fallback to default if no ref is found from config or history file
482+
$comparison_ref = $self->_get_default_comparison_ref()
483+
unless $comparison_ref;
484+
439485
# Get the previous tag from the latest_tag file for current branch if it exists.
440486
my $baseline_tag_file = "$abi_compare_loc/latest_tag";
441487
my $previous_tag = '';
@@ -533,7 +579,10 @@ sub installcheck
533579
# Add binaries comparison status to output at the start
534580
if ($success_binaries && @$success_binaries)
535581
{
536-
push(@saveout, "Binaries compared: \n".join("\n", sort @$success_binaries)."\n\n");
582+
push(@saveout,
583+
"Binaries compared: \n"
584+
. join("\n", sort @$success_binaries)
585+
. "\n\n");
537586
}
538587

539588
# Add comparison results to output
@@ -976,8 +1025,7 @@ sub _compare_and_log_abi_diff
9761025
my $abi_compare_root = $self->{abi_compare_root};
9771026
my $pgbranch = $self->{pgbranch};
9781027

979-
emit
980-
"Comparing ABI between baseline tag $latest_tag and it's latest commit";
1028+
emit "Comparing ABI between baseline $latest_tag and the latest commit";
9811029

9821030
# Set up directories for comparison
9831031
my $tag_xml_dir = "$abi_compare_root/$pgbranch/$latest_tag/xmls";
@@ -1002,7 +1050,7 @@ sub _compare_and_log_abi_diff
10021050
if (-e $tag_file && -e $branch_file)
10031051
{
10041052
push(@success_binaries, $value);
1005-
1053+
10061054
# Run abidiff to compare ABI XML files
10071055
my $log_file = "$log_dir/$key-$latest_tag.log";
10081056
my $exit_status = $self->_log_command_output(

0 commit comments

Comments
 (0)