On 2023-02-02 Th 10:00, Tom Lane wrote:
> Andrew Dunstan <[email protected]> writes:
>> Sure. There's probably some work that could still be done in this area
>> too, such as making pgperltidy work similarly to how we've now make
>> pgindent work.
> Perhaps. But before we commit to that, I'd like to see some tweaks to the
> pgperltidy rules to make it less eager to revisit the formatting of lines
> close to a change. Its current behavior will induce a lot of "git blame"
> noise if we apply these same procedures to Perl code.
I haven't done anything about that yet, but I have reworked the script
so it's a lot more like pgindent, with --show-diff and --silent-diff
modes, and allowing a list of files to be indented on the command line.
Non-perl files are filtered out from such a list.
>
> (Should I mention reformat-dat-files?)
If you want I can add those flags there too.
>
>> There's also a question of timing. Possibly the best time would be when
>> we next fork the tree.
> Yeah. We have generally not wanted to do a mass indent except
> when there's a minimum amount of pending patches, ie after the last
> CF of a cycle. What I'd suggest is that we plan on doing a mass
> indent and then switch over to the new rules, right after the March
> CF closes. That gives us a couple months to nail down and test out
> the new procedures before they go live.
>
>
WFM. Of course then we're not waiting for the developer meeting.
cheers
andrew
--
Andrew Dunstan
EDB: https://www.enterprisedb.com
diff --git a/src/tools/pgindent/pgperltidy b/src/tools/pgindent/pgperltidy
index 5e704119eb..388c113526 100755
--- a/src/tools/pgindent/pgperltidy
+++ b/src/tools/pgindent/pgperltidy
@@ -1,12 +1,162 @@
-#!/bin/sh
+#!/usr/bin/perl
# src/tools/pgindent/pgperltidy
-set -e
+use strict;
+use warnings;
-# set this to override default perltidy program:
-PERLTIDY=${PERLTIDY:-perltidy}
+use Getopt::Long;
+use FindBin;
+use File::Find;
+use Perl::Tidy;
-. src/tools/perlcheck/find_perl_files
+# we require this exact version. See README.
+die "wrong perltidy version $Perl::Tidy::VERSION"
+ unless $Perl::Tidy::VERSION eq '20170521';
+
+# make sure we're in the source root if we need to look for files
+chdir "$FindBin::RealBin/../../.." unless @ARGV;
+
+my ($show_diff, $silent_diff, $help);
+
+$help = 0;
+
+my %options = (
+ "help" => \$help,
+ "show-diff" => \$show_diff,
+ "silent-diff" => \$silent_diff,);
+GetOptions(%options) || usage("bad command line argument");
+
+usage() if $help;
+
+my @files;
+
+# get the filtered list of files
+if (@ARGV)
+{
+ filter_perl_files();
+}
+else
+{
+ File::Find::find(\&wanted, ".");
+}
+
+# process according to the command switches
+if ($silent_diff || $show_diff)
+{
+ indent_files_diff();
+}
+else
+{
+ indent_files_in_place();
+}
+
+exit 0;
+
+# non-destructive perltidy mode
+sub indent_files_diff
+{
+ my $diff_found = 0;
+ foreach my $file (@files)
+ {
+ my $error_flag = Perl::Tidy::perltidy(
+ source => $file,
+ destination => "$file.tdy",
+ perltidyrc => "$FindBin::RealBin/perltidyrc",
+ );
+ if ($error_flag)
+ {
+ unlink "$file.tdy";
+ die "pgperltidy error!";
+ }
+ my $diff = `diff -ud -F '^sub ' $file $file.tdy 2>&1`;
+ unlink "$file.tdy";
+ next unless $diff;
+ exit 2 if ($silent_diff);
+ $diff_found = 1;
+ print $diff;
+ }
+}
+
+# destructive perltidy in place
+# expects that the perltidyrc will have --backup-and-modify-in-place
+sub indent_files_in_place
+{
+ foreach my $file (@files)
+ {
+ my $error_flag = Perl::Tidy::perltidy(
+ source => $file,
+ perltidyrc => "$FindBin::RealBin/perltidyrc",
+ );
+ if ($error_flag)
+ {
+ die "pgperltidy error!";
+ }
+ }
+}
+
+# subroutine for use with File::Find::find
+sub wanted
+{
+ my $mode;
+
+ ($mode = (lstat($_))[2]) &&
+ -f _ &&
+ (/^.*\.p[lm]\z/s ||
+ (!/^.*\.dat\z/s && (($mode & 0100) == 0100) &&
+ `file $_ 2>/dev/null` =~/:.*perl[0-9]*$/i)) &&
+ push(@files, $File::Find::name);
+}
+
+# Similar but filtering files specified in @ARGV
+sub filter_perl_files
+{
+ while (my $file = shift @ARGV)
+ {
+ if (! -f $file)
+ {
+ die "can't find $file";
+ }
+ # ignore .dat files in case they are found
+ next if $file =~ /\.dat$/;
+ if ($file =~ /\.p[lm]\z/)
+ {
+ # file has an explicit perl extension, nothing more to test
+ push @files, $file;
+ next;
+ }
+ my $mode = (lstat(_))[2];
+ # check if it's executable by owner
+ next unless (($mode & 0100) == 0100);
+ # check if `file` says it's a perl file
+ if (`file $file 2>/dev/null` =~/:.*perl[0-9]*$/i)
+ {
+ push @files, $file;
+ }
+ }
+}
+
+
+sub usage
+{
+ my $message = shift;
+ my $helptext = <<'EOF';
+Usage:
+pgperltidy [OPTION]... [FILE]...
+Options:
+ --help show this message and quit
+ --show-diff show the changes that would be made
+ --silent-diff exit with status 2 if any changes would be made
+EOF
+ if ($help)
+ {
+ print $helptext;
+ exit 0;
+ }
+ else
+ {
+ print STDERR "$message\n", $helptext;
+ exit 1;
+ }
+}
-find_perl_files | xargs $PERLTIDY --profile=src/tools/pgindent/perltidyrc