pgindent: more ways to find files to indent
authorAndrew Dunstan <[email protected]>
Wed, 8 Feb 2023 22:01:54 +0000 (17:01 -0500)
committerAndrew Dunstan <[email protected]>
Wed, 8 Feb 2023 22:01:54 +0000 (17:01 -0500)
A new --commit option will add all the files in a commit to the file
list. The option can be specified more than once.

Also, if a directory is given on the command line, all the files in that
directory tree will be added to the file list.

Per suggestions from Robert Haas

Reviewed by Jelte Fennema

Discussion: https://postgr.es/m/CA+TgmoY59Ksso81RNLArNxj0a7xaqV_F_u7gSMHbgdc2kG5Vpw@mail.gmail.com

src/tools/pgindent/pgindent

index 56640e576add7c94b30b94ce323c7bbe7975698a..34fb7d604de48cdba7100a729b323c9438de5b50 100755 (executable)
@@ -23,12 +23,14 @@ my $devnull = File::Spec->devnull;
 
 my ($typedefs_file, $typedef_str, $code_base,
    @excludes,      $indent,      $build,
-   $show_diff,     $silent_diff, $help);
+   $show_diff,     $silent_diff, $help,
+   @commits,);
 
 $help = 0;
 
 my %options = (
    "help"               => \$help,
+   "commit=s"           => \@commits,
    "typedefs=s"         => \$typedefs_file,
    "list-of-typedefs=s" => \$typedef_str,
    "code-base=s"        => \$code_base,
@@ -44,6 +46,9 @@ usage() if $help;
 usage("Cannot have both --silent-diff and --show-diff")
   if $silent_diff && $show_diff;
 
+usage("Cannot use --commit with --code-base or command line file list")
+  if (@commits && ($code_base || @ARGV));
+
 run_build($code_base) if ($build);
 
 # command line option wins, then environment (which is how --build sets it) ,
@@ -53,8 +58,9 @@ $typedefs_file ||= $ENV{PGTYPEDEFS};
 # build mode sets PGINDENT
 $indent ||= $ENV{PGINDENT} || $ENV{INDENT} || "pg_bsd_indent";
 
-# no non-option arguments given. so do everything in the current directory
-$code_base ||= '.' unless @ARGV;
+# if no non-option arguments or commits are given, default to looking in the
+# current directory
+$code_base ||= '.' unless (@ARGV || @commits);
 
 my $sourcedir = locate_sourcedir();
 
@@ -388,6 +394,7 @@ Usage:
 pgindent [OPTION]... [FILE]...
 Options:
    --help                  show this message and quit
+    --commit=gitref         use files modified by the named commit
    --typedefs=FILE         file containing a list of typedefs
    --list-of-typedefs=STR  string containing typedefs, space separated
    --code-base=DIR         path to the base of PostgreSQL source code
@@ -396,7 +403,7 @@ Options:
    --build                 build the pg_bsd_indent program
    --show-diff             show the changes that would be made
    --silent-diff           exit with status 2 if any changes would be made
-The --excludes option can be given more than once.
+The --excludes and --commit options can be given more than once.
 EOF
    if ($help)
    {
@@ -412,27 +419,38 @@ EOF
 
 # main
 
-# get the list of files under code base, if it's set
-File::Find::find(
-   {
-       wanted => sub {
-           my ($dev, $ino, $mode, $nlink, $uid, $gid);
-           (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))
-             && -f _
-             && /^.*\.[ch]\z/s
-             && push(@files, $File::Find::name);
-       }
-   },
-   $code_base) if $code_base;
-
 $filtered_typedefs_fh = load_typedefs();
 
 check_indent();
 
-# any non-option arguments are files to be processed
-push(@files, @ARGV);
+build_clean($code_base) if $build;
+
+my $wanted = sub
+{
+   my ($dev, $ino, $mode, $nlink, $uid, $gid);
+   (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))
+     && -f _
+     && /^.*\.[ch]\z/s
+     && push(@files, $File::Find::name);
+};
+
+# get the list of files under code base, if it's set
+File::Find::find({wanted => $wanted }, $code_base) if $code_base;
+
+# any non-option arguments are files or directories to be processed
+File::Find::find({wanted => $wanted}, @ARGV) if @ARGV;
+
+# process named commits by comparing each with their immediate ancestor
+foreach my $commit (@commits)
+{
+   my $prev="$commit~";
+   my @affected=`git diff-tree --no-commit-id --name-only -r $commit $prev`;
+   die "git error" if $?;
+   chomp(@affected);
+   push(@files,@affected);
+}
 
-# the exclude list applies to command line arguments as well as found files
+# remove excluded files from the file list
 process_exclude();
 
 foreach my $source_filename (@files)
@@ -481,6 +499,4 @@ foreach my $source_filename (@files)
    }
 }
 
-build_clean($code_base) if $build;
-
 exit 0;