diff options
Diffstat (limited to 'build-aux/gitlog-to-changelog')
| -rwxr-xr-x | build-aux/gitlog-to-changelog | 194 | 
1 files changed, 194 insertions, 0 deletions
diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog new file mode 100755 index 0000000..b0db305 --- /dev/null +++ b/build-aux/gitlog-to-changelog @@ -0,0 +1,194 @@ +eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}' +  & eval 'exec perl -wS "$0" $argv:q' +    if 0; +# Convert git log output to ChangeLog format. + +my $VERSION = '2009-10-30 13:46'; # UTC +# The definition above must lie within the first 8 lines in order +# for the Emacs time-stamp write hook (at end) to update it. +# If you change this file with Emacs, please let the write hook +# do its job.  Otherwise, update this string manually. + +# Copyright (C) 2008-2011 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +# Written by Jim Meyering + +use strict; +use warnings; +use Getopt::Long; +use POSIX qw(strftime); + +(my $ME = $0) =~ s|.*/||; + +# use File::Coda; # http://meyering.net/code/Coda/ +END { +  defined fileno STDOUT or return; +  close STDOUT and return; +  warn "$ME: failed to close standard output: $!\n"; +  $? ||= 1; +} + +sub usage ($) +{ +  my ($exit_code) = @_; +  my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); +  if ($exit_code != 0) +    { +      print $STREAM "Try `$ME --help' for more information.\n"; +    } +  else +    { +      print $STREAM <<EOF; +Usage: $ME [OPTIONS] [ARGS] + +Convert git log output to ChangeLog format.  If present, any ARGS +are passed to "git log".  To avoid ARGS being parsed as options to +$ME, they may be preceded by '--'. + +OPTIONS: + +   --since=DATE convert only the logs since DATE; +                  the default is to convert all log entries. +   --format=FMT set format string for commit subject and body; +                  see 'man git-log' for the list of format metacharacters; +                  the default is '%s%n%b%n' + +   --help       display this help and exit +   --version    output version information and exit + +EXAMPLE: + +  $ME --since=2008-01-01 > ChangeLog +  $ME -- -n 5 foo > last-5-commits-to-branch-foo + +EOF +    } +  exit $exit_code; +} + +# If the string $S is a well-behaved file name, simply return it. +# If it contains white space, quotes, etc., quote it, and return the new string. +sub shell_quote($) +{ +  my ($s) = @_; +  if ($s =~ m![^\w+/.,-]!) +    { +      # Convert each single quote to '\'' +      $s =~ s/\'/\'\\\'\'/g; +      # Then single quote the string. +      $s = "'$s'"; +    } +  return $s; +} + +sub quoted_cmd(@) +{ +  return join (' ', map {shell_quote $_} @_); +} + +{ +  my $since_date = '1970-01-01 UTC'; +  my $format_string = '%s%n%b%n'; +  GetOptions +    ( +     help => sub { usage 0 }, +     version => sub { print "$ME version $VERSION\n"; exit }, +     'since=s' => \$since_date, +     'format=s' => \$format_string, +    ) or usage 1; + +  my @cmd = (qw (git log --log-size), "--since=$since_date", +             '--pretty=format:%ct  %an  <%ae>%n%n'.$format_string, @ARGV); +  open PIPE, '-|', @cmd +    or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n" +            . "(Is your Git too old?  Version 1.5.1 or later is required.)\n"); + +  my $prev_date_line = ''; +  while (1) +    { +      defined (my $in = <PIPE>) +        or last; +      $in =~ /^log size (\d+)$/ +        or die "$ME:$.: Invalid line (expected log size):\n$in"; +      my $log_nbytes = $1; + +      my $log; +      my $n_read = read PIPE, $log, $log_nbytes; +      $n_read == $log_nbytes +        or die "$ME:$.: unexpected EOF\n"; + +      my @line = split "\n", $log; +      my $author_line = shift @line; +      defined $author_line +        or die "$ME:$.: unexpected EOF\n"; +      $author_line =~ /^(\d+)  (.*>)$/ +        or die "$ME:$.: Invalid line " +          . "(expected date/author/email):\n$author_line\n"; + +      my $date_line = sprintf "%s  $2\n", strftime ("%F", localtime ($1)); +      # If this line would be the same as the previous date/name/email +      # line, then arrange not to print it. +      if ($date_line ne $prev_date_line) +        { +          $prev_date_line eq '' +            or print "\n"; +          print $date_line; +        } +      $prev_date_line = $date_line; + +      # Omit "Signed-off-by..." lines. +      @line = grep !/^Signed-off-by: .*>$/, @line; + +      # Omit gerrit lines. +      @line = grep !/^(Change-Id|Reviewed-(on|by)|Tested-by): .*$/, @line; + +      # If there were any lines +      if (@line == 0) +        { +          warn "$ME: warning: empty commit message:\n  $date_line\n"; +        } +      else +        { +          # Remove leading and trailing blank lines. +          while ($line[0] =~ /^\s*$/) { shift @line; } +          while ($line[$#line] =~ /^\s*$/) { pop @line; } + +          # Prefix each non-empty line with a TAB. +          @line = map { length $_ ? "\t$_" : '' } @line; + +          print "\n", join ("\n", @line), "\n"; +        } + +      defined ($in = <PIPE>) +        or last; +      $in ne "\n" +        and die "$ME:$.: unexpected line:\n$in"; +    } + +  close PIPE +    or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; +  # FIXME-someday: include $PROCESS_STATUS in the diagnostic +} + +# Local Variables: +# mode: perl +# indent-tabs-mode: nil +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "my $VERSION = '" +# time-stamp-format: "%:y-%02m-%02d %02H:%02M" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "'; # UTC" +# End:  | 
