Andrew Dunstan <and...@dunslane.net> writes: > I'm intending to add some of the new pgindent features to > pgperltidy. Preparatory to that here's a rewrite of pgperltidy in perl - > no new features yet but it does remove the hardcoded path, and requires > you to pass in one or more files / directories as arguments.
Good idea, here's some comments. > #!/usr/bin/perl > > # Copyright (c) 2023, PostgreSQL Global Development Group > > # src/tools/pgindent/pgperltidy > > use strict; > use warnings; > > use File::Find; > > my $perltidy = $ENV{PERLTIDY} || 'perltidy'; > > my @files; > > die "No directories or files specified" unless @ARGV; It's not really useful to have the file name and line in errors like this, adding a "\n" to the end of the message suppresses that. > sub is_perl_exec > { > my $name = shift; > my $out = `file $name 2>/dev/null`; > return $out =~ /:.*perl[0-9]*\b/i; > } > my $wanted = sub { > > my $name = $File::Find::name; > my ($dev, $ino, $mode, $nlink, $uid, $gid); > > # check it's a plain file and either it has a perl extension (.p[lm]) > # or it's executable and `file` thinks it's a perl script. > > (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)) > && -f _ > && (/\.p[lm]$/ || ((($mode & 0100) == 0100) && is_perl_exec($_))) > && push(@files, $name); > }; The core File::stat and Fcntl modules can make this neater: use File::stat; use Fcntl ':mode'; my $wanted = sub { my $st; push @files, $File::Find::name if $st = lstat($_) && -f $st && (/\.p[lm]$/ || (($st->mode & S_IXUSR) && is_perl_exec($_))); }; > File::Find::find({ wanted => $wanted }, @ARGV); > > my $list = join(" ", @files); > > system "$perltidy --profile=src/tools/pgindent/perltidyrc $list"; It's better to use the list form of system, to avoid shell escaping issues. Also, since this is the last thing in the script we might as well exec it instead: exec $perltidy, '--profile=src/tools/pgindent/perltidyrc', @files; - ilmari