From 81d4a01ac03bc2996eea1ca4cc3182e50d21e6ba Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 23 Apr 2009 11:47:06 +0100 Subject: [PATCH] Automatically generate ChangeLog file from the git log (thanks: Jim Meyering). --- .gitignore | 1 + Makefile.am | 9 ++- configure.ac | 2 +- gitlog-to-changelog | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libguestfs.spec.in | 2 +- 5 files changed, 186 insertions(+), 3 deletions(-) create mode 100755 gitlog-to-changelog diff --git a/.gitignore b/.gitignore index b680481..e44c516 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ *.so *.class *.jar +ChangeLog Makefile.in Makefile aclocal.m4 diff --git a/Makefile.am b/Makefile.am index a3992a6..1b5ea89 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,7 +43,8 @@ EXTRA_DIST = \ html/pod.css \ HACKING TODO \ tests.c \ - libguestfs.pc libguestfs.pc.in + libguestfs.pc libguestfs.pc.in \ + gitlog-to-changelog # Build the root filesystem. # Currently this is arch-dependent, so it seems like putting it in @@ -137,6 +138,12 @@ html/guestfish.1.html: guestfish.pod guestfish-actions.pod website: html/guestfs.3.html html/guestfish.1.html cp $^ html/pod.css $(HOME)/d/redhat/et-website/libguestfs/ +# Generate the ChangeLog automatically from the gitlog. + +dist-hook: + ./gitlog-to-changelog > ChangeLog + cp ChangeLog $(distdir)/ChangeLog + # Pkgconfig. pkgconfigdir = $(libdir)/pkgconfig diff --git a/configure.ac b/configure.ac index 1c0216a..46aac94 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -AC_INIT([libguestfs],[1.0.10]) +AC_INIT([libguestfs],[1.0.11]) AM_INIT_AUTOMAKE AC_CONFIG_MACRO_DIR([m4]) diff --git a/gitlog-to-changelog b/gitlog-to-changelog new file mode 100755 index 0000000..0a94b9e --- /dev/null +++ b/gitlog-to-changelog @@ -0,0 +1,175 @@ +#!/usr/bin/perl +# Convert git log output to ChangeLog format. + +my $VERSION = '2008-12-21 12:07'; # 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 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 . + +# 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 < 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'; + GetOptions + ( + help => sub { usage 0 }, + version => sub { print "$ME version $VERSION\n"; exit }, + 'since=s' => \$since_date, + ) or usage 1; + + my @cmd = (qw (git log --log-size), "--since=$since_date", + '--pretty=format:%ct %an <%ae>%n%n%s%n%b%n', @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 = ) + 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; + + # 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 = ) + 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: +# 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: diff --git a/libguestfs.spec.in b/libguestfs.spec.in index 9b83b48..5ba0b32 100644 --- a/libguestfs.spec.in +++ b/libguestfs.spec.in @@ -314,7 +314,7 @@ rm -rf $RPM_BUILD_ROOT %files devel %defattr(-,root,root,-) -%doc HACKING TODO README ex html/guestfs.3.html html/pod.css +%doc ChangeLog HACKING TODO README ex html/guestfs.3.html html/pod.css %doc src/generator.ml %{_libdir}/libguestfs.so %{_mandir}/man3/guestfs.3* -- 1.8.3.1