Blame build-aux/gitlog-to-changelog

Packit 709fb3
eval '(exit $?0)' && eval 'exec perl -wS "$0" "$@"'
Packit 709fb3
  & eval 'exec perl -wS "$0" $argv:q'
Packit 709fb3
    if 0;
Packit 709fb3
# Convert git log output to ChangeLog format.
Packit 709fb3
Packit 709fb3
my $VERSION = '2016-03-22 21:49'; # UTC
Packit 709fb3
# The definition above must lie within the first 8 lines in order
Packit 709fb3
# for the Emacs time-stamp write hook (at end) to update it.
Packit 709fb3
# If you change this file with Emacs, please let the write hook
Packit 709fb3
# do its job.  Otherwise, update this string manually.
Packit 709fb3
Packit 709fb3
# Copyright (C) 2008-2017 Free Software Foundation, Inc.
Packit 709fb3
Packit 709fb3
# This program is free software: you can redistribute it and/or modify
Packit 709fb3
# it under the terms of the GNU General Public License as published by
Packit 709fb3
# the Free Software Foundation, either version 3 of the License, or
Packit 709fb3
# (at your option) any later version.
Packit 709fb3
Packit 709fb3
# This program is distributed in the hope that it will be useful,
Packit 709fb3
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 709fb3
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 709fb3
# GNU General Public License for more details.
Packit 709fb3
Packit 709fb3
# You should have received a copy of the GNU General Public License
Packit 709fb3
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit 709fb3
Packit 709fb3
# Written by Jim Meyering
Packit 709fb3
Packit 709fb3
use strict;
Packit 709fb3
use warnings;
Packit 709fb3
use Getopt::Long;
Packit 709fb3
use POSIX qw(strftime);
Packit 709fb3
Packit 709fb3
(my $ME = $0) =~ s|.*/||;
Packit 709fb3
Packit 709fb3
# use File::Coda; # http://meyering.net/code/Coda/
Packit 709fb3
END {
Packit 709fb3
  defined fileno STDOUT or return;
Packit 709fb3
  close STDOUT and return;
Packit 709fb3
  warn "$ME: failed to close standard output: $!\n";
Packit 709fb3
  $? ||= 1;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
sub usage ($)
Packit 709fb3
{
Packit 709fb3
  my ($exit_code) = @_;
Packit 709fb3
  my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
Packit 709fb3
  if ($exit_code != 0)
Packit 709fb3
    {
Packit 709fb3
      print $STREAM "Try '$ME --help' for more information.\n";
Packit 709fb3
    }
Packit 709fb3
  else
Packit 709fb3
    {
Packit 709fb3
      print $STREAM <
Packit 709fb3
Usage: $ME [OPTIONS] [ARGS]
Packit 709fb3
Packit 709fb3
Convert git log output to ChangeLog format.  If present, any ARGS
Packit 709fb3
are passed to "git log".  To avoid ARGS being parsed as options to
Packit 709fb3
$ME, they may be preceded by '--'.
Packit 709fb3
Packit 709fb3
OPTIONS:
Packit 709fb3
Packit 709fb3
   --amend=FILE FILE maps from an SHA1 to perl code (i.e., s/old/new/) that
Packit 709fb3
                  makes a change to SHA1's commit log text or metadata.
Packit 709fb3
   --append-dot append a dot to the first line of each commit message if
Packit 709fb3
                  there is no other punctuation or blank at the end.
Packit 709fb3
   --no-cluster never cluster commit messages under the same date/author
Packit 709fb3
                  header; the default is to cluster adjacent commit messages
Packit 709fb3
                  if their headers are the same and neither commit message
Packit 709fb3
                  contains multiple paragraphs.
Packit 709fb3
   --srcdir=DIR the root of the source tree, from which the .git/
Packit 709fb3
                  directory can be derived.
Packit 709fb3
   --since=DATE convert only the logs since DATE;
Packit 709fb3
                  the default is to convert all log entries.
Packit 709fb3
   --until=DATE convert only the logs older than DATE.
Packit 709fb3
   --ignore-matching=PAT ignore commit messages whose first lines match PAT.
Packit 709fb3
   --ignore-line=PAT ignore lines of commit messages that match PAT.
Packit 709fb3
   --format=FMT set format string for commit subject and body;
Packit 709fb3
                  see 'man git-log' for the list of format metacharacters;
Packit 709fb3
                  the default is '%s%n%b%n'
Packit 709fb3
   --strip-tab  remove one additional leading TAB from commit message lines.
Packit 709fb3
   --strip-cherry-pick  remove data inserted by "git cherry-pick";
Packit 709fb3
                  this includes the "cherry picked from commit ..." line,
Packit 709fb3
                  and the possible final "Conflicts:" paragraph.
Packit 709fb3
   --help       display this help and exit
Packit 709fb3
   --version    output version information and exit
Packit 709fb3
Packit 709fb3
EXAMPLE:
Packit 709fb3
Packit 709fb3
  $ME --since=2008-01-01 > ChangeLog
Packit 709fb3
  $ME -- -n 5 foo > last-5-commits-to-branch-foo
Packit 709fb3
Packit 709fb3
SPECIAL SYNTAX:
Packit 709fb3
Packit 709fb3
The following types of strings are interpreted specially when they appear
Packit 709fb3
at the beginning of a log message line.  They are not copied to the output.
Packit 709fb3
Packit 709fb3
  Copyright-paperwork-exempt: Yes
Packit 709fb3
    Append the "(tiny change)" notation to the usual "date name email"
Packit 709fb3
    ChangeLog header to mark a change that does not require a copyright
Packit 709fb3
    assignment.
Packit 709fb3
  Co-authored-by: Joe User <user\@example.com>
Packit 709fb3
    List the specified name and email address on a second
Packit 709fb3
    ChangeLog header, denoting a co-author.
Packit 709fb3
  Signed-off-by: Joe User <user\@example.com>
Packit 709fb3
    These lines are simply elided.
Packit 709fb3
Packit 709fb3
In a FILE specified via --amend, comment lines (starting with "#") are ignored.
Packit 709fb3
FILE must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1 (alone on
Packit 709fb3
a line) referring to a commit in the current project, and CODE refers to one
Packit 709fb3
or more consecutive lines of Perl code.  Pairs must be separated by one or
Packit 709fb3
more blank line.
Packit 709fb3
Packit 709fb3
Here is sample input for use with --amend=FILE, from coreutils:
Packit 709fb3
Packit 709fb3
3a169f4c5d9159283548178668d2fae6fced3030
Packit 709fb3
# fix typo in title:
Packit 709fb3
s/all tile types/all file types/
Packit 709fb3
Packit 709fb3
1379ed974f1fa39b12e2ffab18b3f7a607082202
Packit 709fb3
# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself.
Packit 709fb3
# Change the author to be Paul.  Note the escaped "@":
Packit 709fb3
s,Jim .*>,Paul Eggert <eggert\\\@cs.ucla.edu>,
Packit 709fb3
Packit 709fb3
EOF
Packit 709fb3
    }
Packit 709fb3
  exit $exit_code;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
# If the string $S is a well-behaved file name, simply return it.
Packit 709fb3
# If it contains white space, quotes, etc., quote it, and return the new string.
Packit 709fb3
sub shell_quote($)
Packit 709fb3
{
Packit 709fb3
  my ($s) = @_;
Packit 709fb3
  if ($s =~ m![^\w+/.,-]!)
Packit 709fb3
    {
Packit 709fb3
      # Convert each single quote to '\''
Packit 709fb3
      $s =~ s/\'/\'\\\'\'/g;
Packit 709fb3
      # Then single quote the string.
Packit 709fb3
      $s = "'$s'";
Packit 709fb3
    }
Packit 709fb3
  return $s;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
sub quoted_cmd(@)
Packit 709fb3
{
Packit 709fb3
  return join (' ', map {shell_quote $_} @_);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
# Parse file F.
Packit 709fb3
# Comment lines (starting with "#") are ignored.
Packit 709fb3
# F must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1
Packit 709fb3
# (alone on a line) referring to a commit in the current project, and
Packit 709fb3
# CODE refers to one or more consecutive lines of Perl code.
Packit 709fb3
# Pairs must be separated by one or more blank line.
Packit 709fb3
sub parse_amend_file($)
Packit 709fb3
{
Packit 709fb3
  my ($f) = @_;
Packit 709fb3
Packit 709fb3
  open F, '<', $f
Packit 709fb3
    or die "$ME: $f: failed to open for reading: $!\n";
Packit 709fb3
Packit 709fb3
  my $fail;
Packit 709fb3
  my $h = {};
Packit 709fb3
  my $in_code = 0;
Packit 709fb3
  my $sha;
Packit 709fb3
  while (defined (my $line = <F>))
Packit 709fb3
    {
Packit 709fb3
      $line =~ /^\#/
Packit 709fb3
        and next;
Packit 709fb3
      chomp $line;
Packit 709fb3
      $line eq ''
Packit 709fb3
        and $in_code = 0, next;
Packit 709fb3
Packit 709fb3
      if (!$in_code)
Packit 709fb3
        {
Packit 709fb3
          $line =~ /^([0-9a-fA-F]{40})$/
Packit 709fb3
            or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"),
Packit 709fb3
              $fail = 1, next;
Packit 709fb3
          $sha = lc $1;
Packit 709fb3
          $in_code = 1;
Packit 709fb3
          exists $h->{$sha}
Packit 709fb3
            and (warn "$ME: $f:$.: duplicate SHA1\n"),
Packit 709fb3
              $fail = 1, next;
Packit 709fb3
        }
Packit 709fb3
      else
Packit 709fb3
        {
Packit 709fb3
          $h->{$sha} ||= '';
Packit 709fb3
          $h->{$sha} .= "$line\n";
Packit 709fb3
        }
Packit 709fb3
    }
Packit 709fb3
  close F;
Packit 709fb3
Packit 709fb3
  $fail
Packit 709fb3
    and exit 1;
Packit 709fb3
Packit 709fb3
  return $h;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
# git_dir_option $SRCDIR
Packit 709fb3
#
Packit 709fb3
# From $SRCDIR, the --git-dir option to pass to git (none if $SRCDIR
Packit 709fb3
# is undef).  Return as a list (0 or 1 element).
Packit 709fb3
sub git_dir_option($)
Packit 709fb3
{
Packit 709fb3
  my ($srcdir) = @_;
Packit 709fb3
  my @res = ();
Packit 709fb3
  if (defined $srcdir)
Packit 709fb3
    {
Packit 709fb3
      my $qdir = shell_quote $srcdir;
Packit 709fb3
      my $cmd = "cd $qdir && git rev-parse --show-toplevel";
Packit 709fb3
      my $qcmd = shell_quote $cmd;
Packit 709fb3
      my $git_dir = qx($cmd);
Packit 709fb3
      defined $git_dir
Packit 709fb3
        or die "$ME: cannot run $qcmd: $!\n";
Packit 709fb3
      $? == 0
Packit 709fb3
        or die "$ME: $qcmd had unexpected exit code or signal ($?)\n";
Packit 709fb3
      chomp $git_dir;
Packit 709fb3
      push @res, "--git-dir=$git_dir/.git";
Packit 709fb3
    }
Packit 709fb3
  @res;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
{
Packit 709fb3
  my $since_date;
Packit 709fb3
  my $until_date;
Packit 709fb3
  my $format_string = '%s%n%b%n';
Packit 709fb3
  my $amend_file;
Packit 709fb3
  my $append_dot = 0;
Packit 709fb3
  my $cluster = 1;
Packit 709fb3
  my $ignore_matching;
Packit 709fb3
  my $ignore_line;
Packit 709fb3
  my $strip_tab = 0;
Packit 709fb3
  my $strip_cherry_pick = 0;
Packit 709fb3
  my $srcdir;
Packit 709fb3
  GetOptions
Packit 709fb3
    (
Packit 709fb3
     help => sub { usage 0 },
Packit 709fb3
     version => sub { print "$ME version $VERSION\n"; exit },
Packit 709fb3
     'since=s' => \$since_date,
Packit 709fb3
     'until=s' => \$until_date,
Packit 709fb3
     'format=s' => \$format_string,
Packit 709fb3
     'amend=s' => \$amend_file,
Packit 709fb3
     'append-dot' => \$append_dot,
Packit 709fb3
     'cluster!' => \$cluster,
Packit 709fb3
     'ignore-matching=s' => \$ignore_matching,
Packit 709fb3
     'ignore-line=s' => \$ignore_line,
Packit 709fb3
     'strip-tab' => \$strip_tab,
Packit 709fb3
     'strip-cherry-pick' => \$strip_cherry_pick,
Packit 709fb3
     'srcdir=s' => \$srcdir,
Packit 709fb3
    ) or usage 1;
Packit 709fb3
Packit 709fb3
  defined $since_date
Packit 709fb3
    and unshift @ARGV, "--since=$since_date";
Packit 709fb3
  defined $until_date
Packit 709fb3
    and unshift @ARGV, "--until=$until_date";
Packit 709fb3
Packit 709fb3
  # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/)
Packit 709fb3
  # that makes a correction in the log or attribution of that commit.
Packit 709fb3
  my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {};
Packit 709fb3
Packit 709fb3
  my @cmd = ('git',
Packit 709fb3
             git_dir_option $srcdir,
Packit 709fb3
             qw(log --log-size),
Packit 709fb3
             '--pretty=format:%H:%ct  %an  <%ae>%n%n'.$format_string, @ARGV);
Packit 709fb3
  open PIPE, '-|', @cmd
Packit 709fb3
    or die ("$ME: failed to run '". quoted_cmd (@cmd) ."': $!\n"
Packit 709fb3
            . "(Is your Git too old?  Version 1.5.1 or later is required.)\n");
Packit 709fb3
Packit 709fb3
  my $prev_multi_paragraph;
Packit 709fb3
  my $prev_date_line = '';
Packit 709fb3
  my @prev_coauthors = ();
Packit 709fb3
  my @skipshas = ();
Packit 709fb3
  while (1)
Packit 709fb3
    {
Packit 709fb3
      defined (my $in = <PIPE>)
Packit 709fb3
        or last;
Packit 709fb3
      $in =~ /^log size (\d+)$/
Packit 709fb3
        or die "$ME:$.: Invalid line (expected log size):\n$in";
Packit 709fb3
      my $log_nbytes = $1;
Packit 709fb3
Packit 709fb3
      my $log;
Packit 709fb3
      my $n_read = read PIPE, $log, $log_nbytes;
Packit 709fb3
      $n_read == $log_nbytes
Packit 709fb3
        or die "$ME:$.: unexpected EOF\n";
Packit 709fb3
Packit 709fb3
      # Extract leading hash.
Packit 709fb3
      my ($sha, $rest) = split ':', $log, 2;
Packit 709fb3
      defined $sha
Packit 709fb3
        or die "$ME:$.: malformed log entry\n";
Packit 709fb3
      $sha =~ /^[0-9a-fA-F]{40}$/
Packit 709fb3
        or die "$ME:$.: invalid SHA1: $sha\n";
Packit 709fb3
Packit 709fb3
      my $skipflag = 0;
Packit 709fb3
      if (@skipshas)
Packit 709fb3
        {
Packit 709fb3
          foreach(@skipshas)
Packit 709fb3
            {
Packit 709fb3
              if ($sha =~ /^$_/)
Packit 709fb3
                {
Packit 709fb3
                  $skipflag = $_;
Packit 709fb3
                  last;
Packit 709fb3
                }
Packit 709fb3
            }
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      # If this commit's log requires any transformation, do it now.
Packit 709fb3
      my $code = $amend_code->{$sha};
Packit 709fb3
      if (defined $code)
Packit 709fb3
        {
Packit 709fb3
          eval 'use Safe';
Packit 709fb3
          my $s = new Safe;
Packit 709fb3
          # Put the unpreprocessed entry into "$_".
Packit 709fb3
          $_ = $rest;
Packit 709fb3
Packit 709fb3
          # Let $code operate on it, safely.
Packit 709fb3
          my $r = $s->reval("$code")
Packit 709fb3
            or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n";
Packit 709fb3
Packit 709fb3
          # Note that we've used this entry.
Packit 709fb3
          delete $amend_code->{$sha};
Packit 709fb3
Packit 709fb3
          # Update $rest upon success.
Packit 709fb3
          $rest = $_;
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      # Remove lines inserted by "git cherry-pick".
Packit 709fb3
      if ($strip_cherry_pick)
Packit 709fb3
        {
Packit 709fb3
          $rest =~ s/^\s*Conflicts:\n.*//sm;
Packit 709fb3
          $rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m;
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      my @line = split /[ \t]*\n/, $rest;
Packit 709fb3
      my $author_line = shift @line;
Packit 709fb3
      defined $author_line
Packit 709fb3
        or die "$ME:$.: unexpected EOF\n";
Packit 709fb3
      $author_line =~ /^(\d+)  (.*>)$/
Packit 709fb3
        or die "$ME:$.: Invalid line "
Packit 709fb3
          . "(expected date/author/email):\n$author_line\n";
Packit 709fb3
Packit 709fb3
      # Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog
Packit 709fb3
      # `(tiny change)' annotation.
Packit 709fb3
      my $tiny = (grep (/^(?:Copyright-paperwork-exempt|Tiny-change):\s+[Yy]es$/, @line)
Packit 709fb3
                  ? '  (tiny change)' : '');
Packit 709fb3
Packit 709fb3
      my $date_line = sprintf "%s  %s$tiny\n",
Packit 709fb3
        strftime ("%Y-%m-%d", localtime ($1)), $2;
Packit 709fb3
Packit 709fb3
      my @coauthors = grep /^Co-authored-by:.*$/, @line;
Packit 709fb3
      # Omit meta-data lines we've already interpreted.
Packit 709fb3
      @line = grep !/^(?:Signed-off-by:[ ].*>$
Packit 709fb3
                       |Co-authored-by:[ ]
Packit 709fb3
                       |Copyright-paperwork-exempt:[ ]
Packit 709fb3
                       |Tiny-change:[ ]
Packit 709fb3
                       )/x, @line;
Packit 709fb3
Packit 709fb3
      # Remove leading and trailing blank lines.
Packit 709fb3
      if (@line)
Packit 709fb3
        {
Packit 709fb3
          while ($line[0] =~ /^\s*$/) { shift @line; }
Packit 709fb3
          while ($line[$#line] =~ /^\s*$/) { pop @line; }
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      # Handle Emacs gitmerge.el "skipped" commits.
Packit 709fb3
      # Yes, this should be controlled by an option.  So sue me.
Packit 709fb3
      if ( grep /^(; )?Merge from /, @line )
Packit 709fb3
      {
Packit 709fb3
          my $found = 0;
Packit 709fb3
          foreach (@line)
Packit 709fb3
          {
Packit 709fb3
              if (grep /^The following commit.*skipped:$/, $_)
Packit 709fb3
              {
Packit 709fb3
                  $found = 1;
Packit 709fb3
                  ## Reset at each merge to reduce chance of false matches.
Packit 709fb3
                  @skipshas = ();
Packit 709fb3
                  next;
Packit 709fb3
              }
Packit 709fb3
              if ($found && $_ =~ /^([0-9a-fA-F]{7,}) [^ ]/)
Packit 709fb3
              {
Packit 709fb3
                  push ( @skipshas, $1 );
Packit 709fb3
              }
Packit 709fb3
          }
Packit 709fb3
      }
Packit 709fb3
Packit 709fb3
      # Ignore commits that match the --ignore-matching pattern, if specified.
Packit 709fb3
      if (defined $ignore_matching && @line && $line[0] =~ /$ignore_matching/)
Packit 709fb3
        {
Packit 709fb3
          $skipflag = 1;
Packit 709fb3
        }
Packit 709fb3
      elsif ($skipflag)
Packit 709fb3
        {
Packit 709fb3
          ## Perhaps only warn if a pattern matches more than once?
Packit 709fb3
          warn "$ME: warning: skipping $sha due to $skipflag\n";
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      if (! $skipflag)
Packit 709fb3
        {
Packit 709fb3
          if (defined $ignore_line && @line)
Packit 709fb3
            {
Packit 709fb3
              @line = grep ! /$ignore_line/, @line;
Packit 709fb3
              while ($line[$#line] =~ /^\s*$/) { pop @line; }
Packit 709fb3
            }
Packit 709fb3
Packit 709fb3
          # Record whether there are two or more paragraphs.
Packit 709fb3
          my $multi_paragraph = grep /^\s*$/, @line;
Packit 709fb3
Packit 709fb3
          # Format 'Co-authored-by: A U Thor <email@example.com>' lines in
Packit 709fb3
          # standard multi-author ChangeLog format.
Packit 709fb3
          for (@coauthors)
Packit 709fb3
            {
Packit 709fb3
              s/^Co-authored-by:\s*/\t    /;
Packit 709fb3
              s/\s*</  </;
Packit 709fb3
Packit 709fb3
              /<.*?@.*\..*>/
Packit 709fb3
                or warn "$ME: warning: missing email address for "
Packit 709fb3
                  . substr ($_, 5) . "\n";
Packit 709fb3
            }
Packit 709fb3
Packit 709fb3
          # If clustering of commit messages has been disabled, if this header
Packit 709fb3
          # would be different from the previous date/name/etc. header,
Packit 709fb3
          # or if this or the previous entry consists of two or more paragraphs,
Packit 709fb3
          # then print the header.
Packit 709fb3
          if ( ! $cluster
Packit 709fb3
              || $date_line ne $prev_date_line
Packit 709fb3
              || "@coauthors" ne "@prev_coauthors"
Packit 709fb3
              || $multi_paragraph
Packit 709fb3
              || $prev_multi_paragraph)
Packit 709fb3
            {
Packit 709fb3
              $prev_date_line eq ''
Packit 709fb3
                or print "\n";
Packit 709fb3
              print $date_line;
Packit 709fb3
              @coauthors
Packit 709fb3
                and print join ("\n", @coauthors), "\n";
Packit 709fb3
            }
Packit 709fb3
          $prev_date_line = $date_line;
Packit 709fb3
          @prev_coauthors = @coauthors;
Packit 709fb3
          $prev_multi_paragraph = $multi_paragraph;
Packit 709fb3
Packit 709fb3
          # If there were any lines
Packit 709fb3
          if (@line == 0)
Packit 709fb3
            {
Packit 709fb3
              warn "$ME: warning: empty commit message:\n  $date_line\n";
Packit 709fb3
            }
Packit 709fb3
          else
Packit 709fb3
            {
Packit 709fb3
              if ($append_dot)
Packit 709fb3
                {
Packit 709fb3
                  # If the first line of the message has enough room, then
Packit 709fb3
                  if (length $line[0] < 72)
Packit 709fb3
                    {
Packit 709fb3
                      # append a dot if there is no other punctuation or blank
Packit 709fb3
                      # at the end.
Packit 709fb3
                      $line[0] =~ /[[:punct:]\s]$/
Packit 709fb3
                        or $line[0] .= '.';
Packit 709fb3
                    }
Packit 709fb3
                }
Packit 709fb3
Packit 709fb3
              # Remove one additional leading TAB from each line.
Packit 709fb3
              $strip_tab
Packit 709fb3
                and map { s/^\t// } @line;
Packit 709fb3
Packit 709fb3
              # Prefix each non-empty line with a TAB.
Packit 709fb3
              @line = map { length $_ ? "\t$_" : '' } @line;
Packit 709fb3
Packit 709fb3
              print "\n", join ("\n", @line), "\n";
Packit 709fb3
            }
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      defined ($in = <PIPE>)
Packit 709fb3
        or last;
Packit 709fb3
      $in ne "\n"
Packit 709fb3
        and die "$ME:$.: unexpected line:\n$in";
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  close PIPE
Packit 709fb3
    or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n";
Packit 709fb3
  # FIXME-someday: include $PROCESS_STATUS in the diagnostic
Packit 709fb3
Packit 709fb3
  # Complain about any unused entry in the --amend=F specified file.
Packit 709fb3
  my $fail = 0;
Packit 709fb3
  foreach my $sha (keys %$amend_code)
Packit 709fb3
    {
Packit 709fb3
      warn "$ME:$amend_file: unused entry: $sha\n";
Packit 709fb3
      $fail = 1;
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  exit $fail;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
# Local Variables:
Packit 709fb3
# mode: perl
Packit 709fb3
# indent-tabs-mode: nil
Packit 709fb3
# eval: (add-hook 'write-file-hooks 'time-stamp)
Packit 709fb3
# time-stamp-start: "my $VERSION = '"
Packit 709fb3
# time-stamp-format: "%:y-%02m-%02d %02H:%02M"
Packit 709fb3
# time-stamp-time-zone: "UTC0"
Packit 709fb3
# time-stamp-end: "'; # UTC"
Packit 709fb3
# End: