Blame build-aux/gitlog-to-changelog

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