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