On 2023-02-02 Th 10:00, Tom Lane wrote:
> Andrew Dunstan <and...@dunslane.net> 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

Reply via email to